41#include "adv_trigger.h"
47#define __STDC_CONSTANT_MACROS
49#define CLEAR(x) memset(&(x), 0, sizeof(x))
63 frame_drop_interval_(0.0) {}
72 config_ = cameraconfig;
74 if (config_->pixel_format() ==
"yuyv") {
75 pixel_format_ = V4L2_PIX_FMT_YUYV;
76 }
else if (config_->pixel_format() ==
"uyvy") {
77 pixel_format_ = V4L2_PIX_FMT_UYVY;
78 }
else if (config_->pixel_format() ==
"mjpeg") {
79 pixel_format_ = V4L2_PIX_FMT_MJPEG;
80 }
else if (config_->pixel_format() ==
"yuvmono10") {
81 pixel_format_ = V4L2_PIX_FMT_YUYV;
82 config_->set_monochrome(
true);
83 }
else if (config_->pixel_format() ==
"rgb24") {
84 pixel_format_ = V4L2_PIX_FMT_RGB24;
86 pixel_format_ = V4L2_PIX_FMT_YUYV;
87 AERROR <<
"Wrong pixel fromat:" << config_->pixel_format()
88 <<
",must be yuyv | uyvy | mjpeg | yuvmono10 | rgb24";
91 if (pixel_format_ == V4L2_PIX_FMT_MJPEG) {
92 init_mjpeg_decoder(config_->width(), config_->height());
96 frame_warning_interval_ =
static_cast<float>(1.5 / config_->frame_rate());
98 frame_drop_interval_ =
static_cast<float>(0.9 / config_->frame_rate());
104int UsbCam::init_mjpeg_decoder(
int image_width,
int image_height) {
105 avcodec_register_all();
109 AERROR <<
"Could not find MJPEG decoder";
113 avcodec_context_ = avcodec_alloc_context3(avcodec_);
115#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
116 avframe_camera_ = av_frame_alloc();
117 avframe_rgb_ = av_frame_alloc();
119 avpicture_alloc(
reinterpret_cast<AVPicture*
>(avframe_rgb_), AV_PIX_FMT_RGB24,
120 image_width, image_height);
122 avframe_camera_ = avcodec_alloc_frame();
123 avframe_rgb_ = avcodec_alloc_frame();
125 avpicture_alloc(
reinterpret_cast<AVPicture*
>(avframe_rgb_), PIX_FMT_RGB24,
126 image_width, image_height);
130 avcodec_context_->width = image_width;
131 avcodec_context_->height = image_height;
133#if LIBAVCODEC_VERSION_MAJOR > 52
134#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
135 avcodec_context_->pix_fmt = AV_PIX_FMT_YUV422P;
137 avcodec_context_->pix_fmt = PIX_FMT_YUV422P;
139 avcodec_context_->codec_type = AVMEDIA_TYPE_VIDEO;
142#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
143 avframe_camera_size_ =
144 avpicture_get_size(AV_PIX_FMT_YUV422P, image_width, image_height);
146 avpicture_get_size(AV_PIX_FMT_RGB24, image_width, image_height);
148 avframe_camera_size_ =
149 avpicture_get_size(PIX_FMT_YUV422P, image_width, image_height);
151 avpicture_get_size(PIX_FMT_RGB24, image_width, image_height);
155 if (avcodec_open2(avcodec_context_, avcodec_, &avoptions_) < 0) {
156 AERROR <<
"Could not open MJPEG Decoder";
162void UsbCam::mjpeg2rgb(
char* mjpeg_buffer,
int len,
char* rgb_buffer,
167 memset(rgb_buffer, 0, avframe_rgb_size_);
169#if LIBAVCODEC_VERSION_MAJOR > 52
172 av_init_packet(&avpkt);
175 avpkt.data = (
unsigned char*)mjpeg_buffer;
176 decoded_len = avcodec_decode_video2(avcodec_context_, avframe_camera_,
177 &got_picture, &avpkt);
179 if (decoded_len < 0) {
180 AERROR <<
"Error while decoding frame.";
184 avcodec_decode_video(avcodec_context_, avframe_camera_, &got_picture,
185 reinterpret_cast<uint8_t*
>(mjpeg_buffer), len);
189 AERROR <<
"Camera: expected picture but didn't get it...";
193 int xsize = avcodec_context_->width;
194 int ysize = avcodec_context_->height;
195 int pic_size = avpicture_get_size(avcodec_context_->pix_fmt, xsize, ysize);
196 if (pic_size != avframe_camera_size_) {
197 AERROR <<
"outbuf size mismatch. pic_size:" << pic_size
198 <<
",buffer_size:" << avframe_camera_size_;
202#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
204 sws_getContext(xsize, ysize, avcodec_context_->pix_fmt, xsize, ysize,
205 AV_PIX_FMT_RGB24, SWS_BILINEAR,
nullptr,
nullptr,
nullptr);
208 sws_getContext(xsize, ysize, avcodec_context_->pix_fmt, xsize, ysize,
209 PIX_FMT_RGB24, SWS_BILINEAR,
nullptr,
nullptr,
nullptr);
212 sws_scale(video_sws_, avframe_camera_->data, avframe_camera_->linesize, 0,
213 ysize, avframe_rgb_->data, avframe_rgb_->linesize);
214 sws_freeContext(video_sws_);
216#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
217 int size = avpicture_layout(
218 reinterpret_cast<AVPicture*
>(avframe_rgb_), AV_PIX_FMT_RGB24, xsize,
219 ysize,
reinterpret_cast<uint8_t*
>(rgb_buffer), avframe_rgb_size_);
221 int size = avpicture_layout(
222 reinterpret_cast<AVPicture*
>(avframe_rgb_), PIX_FMT_RGB24, xsize, ysize,
223 reinterpret_cast<uint8_t*
>(rgb_buffer), avframe_rgb_size_);
225 if (size != avframe_rgb_size_) {
226 AERROR <<
"webcam: avpicture_layout error: " << size;
233 raw_image->is_new = 0;
235 memset(raw_image->image, 0, raw_image->image_size *
sizeof(
char));
248 r = select(fd_ + 1, &fds,
nullptr,
nullptr, &tv);
251 if (EINTR == errno) {
260 AERROR <<
"select timeout";
264 int get_new_image = read_frame(raw_image, sensor_raw_image);
266 if (!get_new_image) {
270 raw_image->is_new = 1;
274bool UsbCam::open_device(
void) {
277 if (-1 == stat(config_->camera_dev().c_str(), &st)) {
278 AERROR <<
"Cannot identify '" << config_->camera_dev() <<
"': " << errno
279 <<
", " << strerror(errno);
283 if (!S_ISCHR(st.st_mode)) {
284 AERROR << config_->camera_dev() <<
" is no device";
288 fd_ = open(config_->camera_dev().c_str(), O_RDWR | O_NONBLOCK,
292 AERROR <<
"Cannot open '" << config_->camera_dev() <<
"': " << errno <<
", "
300bool UsbCam::init_device(
void) {
301 struct v4l2_capability cap;
302 struct v4l2_cropcap cropcap;
303 struct v4l2_crop crop;
304 struct v4l2_format fmt;
305 unsigned int min = 0;
307 if (-1 == xioctl(fd_, VIDIOC_QUERYCAP, &cap)) {
308 if (EINVAL == errno) {
309 AERROR << config_->camera_dev() <<
" is no V4L2 device";
312 AERROR <<
"VIDIOC_QUERYCAP";
316 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
317 AERROR << config_->camera_dev() <<
" is no video capture device";
321 switch (config_->io_method()) {
323 if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
324 AERROR << config_->camera_dev() <<
" does not support read i/o";
332 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
333 AERROR << config_->camera_dev() <<
" does not support streaming i/o";
339 AERROR << config_->camera_dev() <<
" does not support unknown i/o";
347 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
349 if (0 == xioctl(fd_, VIDIOC_CROPCAP, &cropcap)) {
350 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
351 crop.c = cropcap.defrect;
353 if (-1 == xioctl(fd_, VIDIOC_S_CROP, &crop)) {
364 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
365 fmt.fmt.pix.width = config_->width();
366 fmt.fmt.pix.height = config_->height();
367 fmt.fmt.pix.pixelformat = pixel_format_;
368 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
370 if (-1 == xioctl(fd_, VIDIOC_S_FMT, &fmt)) {
378 min = fmt.fmt.pix.width * 2;
380 if (fmt.fmt.pix.bytesperline < min) {
381 fmt.fmt.pix.bytesperline = min;
384 min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
386 if (fmt.fmt.pix.sizeimage < min) {
387 fmt.fmt.pix.sizeimage = min;
390 config_->set_width(fmt.fmt.pix.width);
391 config_->set_height(fmt.fmt.pix.height);
393 struct v4l2_streamparm stream_params;
394 memset(&stream_params, 0,
sizeof(stream_params));
395 stream_params.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
404 AINFO <<
"Capability flag: 0x" << stream_params.parm.capture.capability;
406 stream_params.parm.capture.timeperframe.numerator = 1;
407 stream_params.parm.capture.timeperframe.denominator = config_->frame_rate();
409 if (xioctl(fd_, VIDIOC_S_PARM, &stream_params) < 0) {
410 AINFO <<
"Couldn't set camera framerate";
412 AINFO <<
"Set framerate to be " << config_->frame_rate();
415 switch (config_->io_method()) {
417 init_read(fmt.fmt.pix.sizeimage);
425 init_userp(fmt.fmt.pix.sizeimage);
429 AERROR <<
" does not support unknown i/o";
437bool UsbCam::set_adv_trigger() {
438 AINFO <<
"Trigger enable, dev:" << config_->camera_dev()
439 <<
", fps:" << config_->trigger_fps()
440 <<
", internal:" << config_->trigger_internal();
441 int ret = adv_trigger_enable(
442 config_->camera_dev().c_str(),
443 static_cast<unsigned char>(config_->trigger_fps()),
444 static_cast<unsigned char>(config_->trigger_internal()));
446 AERROR <<
"trigger failed:" << ret;
453int UsbCam::xioctl(
int fd,
int request,
void* arg) {
456 r = ioctl(fd, request, arg);
457 }
while (-1 == r && EINTR == errno);
462bool UsbCam::init_read(
unsigned int buffer_size) {
463 buffers_ =
reinterpret_cast<buffer*
>(calloc(1,
sizeof(*buffers_)));
466 AERROR <<
"Out of memory";
472 buffers_[0].
length = buffer_size;
473 buffers_[0].
start = malloc(buffer_size);
475 if (!buffers_[0].start) {
476 AERROR <<
"Out of memory";
483bool UsbCam::init_mmap(
void) {
484 struct v4l2_requestbuffers req;
488 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
489 req.memory = V4L2_MEMORY_MMAP;
491 if (-1 == xioctl(fd_, VIDIOC_REQBUFS, &req)) {
492 if (EINVAL == errno) {
493 AERROR << config_->camera_dev() <<
" does not support memory mapping";
499 buffers_ =
reinterpret_cast<buffer*
>(calloc(req.count,
sizeof(*buffers_)));
502 AERROR <<
"Out of memory";
506 for (n_buffers_ = 0; n_buffers_ < req.count; ++n_buffers_) {
507 struct v4l2_buffer buf;
510 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
511 buf.memory = V4L2_MEMORY_MMAP;
512 buf.index = n_buffers_;
514 if (-1 == xioctl(fd_, VIDIOC_QUERYBUF, &buf)) {
515 AERROR <<
"VIDIOC_QUERYBUF";
519 buffers_[n_buffers_].
length = buf.length;
520 buffers_[n_buffers_].
start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
521 MAP_SHARED, fd_, buf.m.offset);
523 if (MAP_FAILED == buffers_[n_buffers_].start) {
532bool UsbCam::init_userp(
unsigned int buffer_size) {
533 struct v4l2_requestbuffers req;
534 unsigned int page_size = 0;
536 page_size = getpagesize();
537 buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
542 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
543 req.memory = V4L2_MEMORY_USERPTR;
545 if (-1 == xioctl(fd_, VIDIOC_REQBUFS, &req)) {
546 if (EINVAL == errno) {
547 AERROR << config_->camera_dev()
548 <<
" does not support "
552 AERROR <<
"VIDIOC_REQBUFS";
556 buffers_ =
reinterpret_cast<buffer*
>(calloc(4,
sizeof(*buffers_)));
559 AERROR <<
"Out of memory";
563 for (n_buffers_ = 0; n_buffers_ < 4; ++n_buffers_) {
564 buffers_[n_buffers_].
length = buffer_size;
565 buffers_[n_buffers_].
start =
566 memalign( page_size, buffer_size);
568 if (!buffers_[n_buffers_].start) {
569 AERROR <<
"Out of memory";
577bool UsbCam::start_capturing(
void) {
583 enum v4l2_buf_type type;
585 switch (config_->io_method()) {
591 for (i = 0; i < n_buffers_; ++i) {
592 struct v4l2_buffer buf;
595 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
596 buf.memory = V4L2_MEMORY_MMAP;
598 if (-1 == xioctl(fd_, VIDIOC_QBUF, &buf)) {
604 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
606 if (-1 == xioctl(fd_, VIDIOC_STREAMON, &type)) {
607 AERROR <<
"VIDIOC_STREAMON";
614 for (i = 0; i < n_buffers_; ++i) {
615 struct v4l2_buffer buf;
619 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
620 buf.memory = V4L2_MEMORY_USERPTR;
622 buf.m.userptr =
reinterpret_cast<uint64_t
>(buffers_[i].
start);
623 buf.length =
static_cast<unsigned int>(buffers_[i].
length);
625 if (-1 == xioctl(fd_, VIDIOC_QBUF, &buf)) {
631 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
633 if (-1 == xioctl(fd_, VIDIOC_STREAMON, &type)) {
634 AERROR <<
"VIDIOC_STREAMON";
646 is_capturing_ =
true;
650void UsbCam::set_device_config() {
651 if (config_->brightness() >= 0) {
652 set_v4l_parameter(
"brightness", config_->brightness());
655 if (config_->contrast() >= 0) {
656 set_v4l_parameter(
"contrast", config_->contrast());
659 if (config_->saturation() >= 0) {
660 set_v4l_parameter(
"saturation", config_->saturation());
663 if (config_->sharpness() >= 0) {
664 set_v4l_parameter(
"sharpness", config_->sharpness());
667 if (config_->gain() >= 0) {
668 set_v4l_parameter(
"gain", config_->gain());
672 if (config_->auto_white_balance()) {
673 set_v4l_parameter(
"white_balance_temperature_auto", 1);
675 set_v4l_parameter(
"white_balance_temperature_auto", 0);
676 set_v4l_parameter(
"white_balance_temperature", config_->white_balance());
680 if (!config_->auto_exposure()) {
682 set_v4l_parameter(
"auto_exposure", 1);
684 set_v4l_parameter(
"exposure_absolute", config_->exposure());
688 if (config_->auto_focus()) {
690 set_v4l_parameter(
"focus_auto", 1);
692 set_v4l_parameter(
"focus_auto", 0);
693 if (config_->focus() >= 0) {
694 set_v4l_parameter(
"focus_absolute", config_->focus());
699bool UsbCam::uninit_device(
void) {
702 switch (config_->io_method()) {
704 free(buffers_[0].start);
708 for (i = 0; i < n_buffers_; ++i) {
709 if (-1 == munmap(buffers_[i].start, buffers_[i].length)) {
718 for (i = 0; i < n_buffers_; ++i) {
719 free(buffers_[i].start);
732bool UsbCam::close_device(
void) {
733 if (-1 == close(fd_)) {
742bool UsbCam::stop_capturing(
void) {
743 if (!is_capturing_) {
747 is_capturing_ =
false;
748 enum v4l2_buf_type type;
750 switch (config_->io_method()) {
757 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
759 if (-1 == xioctl(fd_, VIDIOC_STREAMOFF, &type)) {
760 AERROR <<
"VIDIOC_STREAMOFF";
776 struct v4l2_buffer buf;
780 timeval sample_ts_monotonic;
781 timespec current_ts_monotonic;
782 uint64_t sample_ts_monotonic_ns, current_ts_monotonic_ns, diff_ns, sample_in_systme_time_ns;
784 switch (config_->io_method()) {
786 len =
static_cast<int>(read(fd_, buffers_[0].start, buffers_[0].length));
806 process_image(buffers_[0].start, len, raw_image);
807 if(sensor_raw_image->image !=
nullptr) {
808 memcpy(sensor_raw_image->image, buffers_[0].start, len);
815 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
816 buf.memory = V4L2_MEMORY_MMAP;
818 if (-1 == xioctl(fd_, VIDIOC_DQBUF, &buf)) {
835 assert(buf.index < n_buffers_);
837 if(!config_->hardware_trigger()){
838 sample_ts_monotonic.tv_sec =
static_cast<int>(buf.timestamp.tv_sec);
839 sample_ts_monotonic.tv_usec =
static_cast<int>(buf.timestamp.tv_usec);
840 clock_gettime(CLOCK_MONOTONIC,¤t_ts_monotonic);
841 sample_ts_monotonic_ns =
static_cast<uint64_t
>(sample_ts_monotonic.tv_sec*(1000000000)) +
static_cast<uint64_t
>(sample_ts_monotonic.tv_usec*(1000));
842 current_ts_monotonic_ns =
static_cast<uint64_t
>(current_ts_monotonic.tv_sec*(1000000000)) +
static_cast<uint64_t
>(current_ts_monotonic.tv_nsec);
843 diff_ns =
static_cast<uint64_t
>(current_ts_monotonic_ns - sample_ts_monotonic_ns);
845 raw_image->tv_sec =
static_cast<int>((sample_in_systme_time_ns)/1000000000);
846 raw_image->tv_usec =
static_cast<int>(((sample_in_systme_time_ns)%1000000000)/1000);
849 raw_image->tv_sec =
static_cast<int>(buf.timestamp.tv_sec);
850 raw_image->tv_usec =
static_cast<int>(buf.timestamp.tv_usec);
853 cyber::Time image_time(raw_image->tv_sec, 1000 * raw_image->tv_usec);
854 uint64_t camera_timestamp = image_time.ToNanosecond();
855 if (last_nsec_ == 0) {
856 last_nsec_ = camera_timestamp;
859 static_cast<double>(camera_timestamp - last_nsec_) / 1e9;
861 if (diff < frame_drop_interval_) {
862 AINFO <<
"drop image:" << camera_timestamp;
863 if (-1 == xioctl(fd_, VIDIOC_QBUF, &buf)) {
864 AERROR <<
"VIDIOC_QBUF ERROR";
868 if (frame_warning_interval_ < diff) {
869 AWARN <<
"stamp jump.last stamp:" << last_nsec_
870 <<
" current stamp:" << camera_timestamp;
872 last_nsec_ = camera_timestamp;
876 double image_s =
static_cast<double>(camera_timestamp) / 1e9;
877 double diff = now_s - image_s;
878 if (diff > 0.5 || diff < 0) {
879 std::stringstream warning_stream;
880 std::string warning_str;
881 warning_stream <<
"camera time diff exception,diff:" << diff
882 <<
";dev:" << config_->camera_dev();
883 warning_stream >> warning_str;
884 AWARN << warning_str;
887 if (len < raw_image->width * raw_image->height) {
888 AERROR <<
"Wrong Buffer Len: " << len
889 <<
", dev: " << config_->camera_dev();
891 process_image(buffers_[buf.index].start, len, raw_image);
892 if(sensor_raw_image->image !=
nullptr) {
893 memcpy(sensor_raw_image->image, buffers_[buf.index].start, len);
897 if (-1 == xioctl(fd_, VIDIOC_QBUF, &buf)) {
907 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
908 buf.memory = V4L2_MEMORY_USERPTR;
910 if (-1 == xioctl(fd_, VIDIOC_DQBUF, &buf)) {
927 for (i = 0; i < n_buffers_; ++i) {
928 if (buf.m.userptr ==
reinterpret_cast<uint64_t
>(buffers_[i].start) &&
929 buf.length == buffers_[i].length) {
934 assert(i < n_buffers_);
936 process_image(
reinterpret_cast<void*
>(buf.m.userptr), len, raw_image);
937 if(sensor_raw_image->image !=
nullptr) {
938 memcpy(sensor_raw_image->image,
reinterpret_cast<void*
>(buf.m.userptr), len);
941 if (-1 == xioctl(fd_, VIDIOC_QBUF, &buf)) {
957bool UsbCam::process_image(
void* src,
int len,
CameraImagePtr dest) {
958 if (src ==
nullptr || dest ==
nullptr) {
959 AERROR <<
"process image error. src or dest is null";
962 if (pixel_format_ == V4L2_PIX_FMT_YUYV ||
963 pixel_format_ == V4L2_PIX_FMT_UYVY) {
964 if (pixel_format_ == V4L2_PIX_FMT_UYVY) {
965 unsigned char yuyvbuf[len];
966 unsigned char uyvybuf[len];
967 memcpy(yuyvbuf, src, len);
968 for (
int index = 0; index < len; index = index + 2) {
969 uyvybuf[index] = yuyvbuf[index + 1];
970 uyvybuf[index + 1] = yuyvbuf[index];
972 memcpy(src, uyvybuf, len);
974 if (config_->output_type() == YUYV) {
975 memcpy(dest->image, src, dest->width * dest->height * 2);
976 }
else if (config_->output_type() == RGB) {
978 yuyv2rgb_avx((
unsigned char*)src, (
unsigned char*)dest->image,
979 dest->width * dest->height);
981 convert_yuv_to_rgb_buffer((
unsigned char*)src,
982 (
unsigned char*)dest->image, dest->width,
986 AERROR <<
"unsupported output format:" << config_->output_type();
990 AERROR <<
"unsupported pixel format:" << pixel_format_;
999void UsbCam::set_auto_focus(
int value) {
1000 struct v4l2_queryctrl queryctrl;
1001 struct v4l2_ext_control control;
1003 memset(&queryctrl, 0,
sizeof(queryctrl));
1004 queryctrl.id = V4L2_CID_FOCUS_AUTO;
1006 if (-1 == xioctl(fd_, VIDIOC_QUERYCTRL, &queryctrl)) {
1007 if (errno != EINVAL) {
1008 perror(
"VIDIOC_QUERYCTRL");
1011 AINFO <<
"V4L2_CID_FOCUS_AUTO is not supported";
1014 }
else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
1015 AINFO <<
"V4L2_CID_FOCUS_AUTO is not supported";
1018 memset(&control, 0,
sizeof(control));
1019 control.id = V4L2_CID_FOCUS_AUTO;
1020 control.value = value;
1022 if (-1 == xioctl(fd_, VIDIOC_S_CTRL, &control)) {
1023 perror(
"VIDIOC_S_CTRL");
1035void UsbCam::set_v4l_parameter(
const std::string& param,
int value) {
1036 set_v4l_parameter(param, std::to_string(value));
1044void UsbCam::set_v4l_parameter(
const std::string& param,
1045 const std::string& value) {
1047 std::stringstream ss;
1048 ss <<
"v4l2-ctl --device=" << config_->camera_dev() <<
" -c " << param <<
"="
1049 << value <<
" 2>&1";
1050 std::string cmd = ss.str();
1055 FILE* stream = popen(cmd.c_str(),
"r");
1057 while (!feof(stream)) {
1058 if (fgets(buffer, 256, stream) !=
nullptr) {
1059 output.append(buffer);
1065 if (output.length() > 0) {
1066 AERROR << output.c_str();
1069 AERROR <<
"usb_cam_node could not run " << cmd.c_str();
1074 if (is_capturing_) {
1075 ADEBUG <<
"is capturing";
1078 if (!open_device()) {
1081 if (!init_device()) {
1085 if (!start_capturing()) {
1098int UsbCam::convert_yuv_to_rgb_pixel(
int y,
int u,
int v) {
1099 unsigned int pixel32 = 0;
1100 unsigned char* pixel = (
unsigned char*)&pixel32;
1102 r = (int)((
double)y + (1.370705 * ((double)v - 128.0)));
1103 g = (int)((
double)y - (0.698001 * ((double)v - 128.0)) -
1104 (0.337633 * ((
double)u - 128.0)));
1105 b = (int)((
double)y + (1.732446 * ((double)u - 128.0)));
1106 if (r > 255) r = 255;
1107 if (g > 255) g = 255;
1108 if (b > 255) b = 255;
1112 pixel[0] = (
unsigned char)r;
1113 pixel[1] = (
unsigned char)g;
1114 pixel[2] = (
unsigned char)b;
1118int UsbCam::convert_yuv_to_rgb_buffer(
unsigned char* yuv,
unsigned char* rgb,
1119 unsigned int width,
unsigned int height) {
1120 unsigned int in, out = 0;
1121 unsigned int pixel_16;
1122 unsigned char pixel_24[3];
1123 unsigned int pixel32;
1126 for (in = 0; in < width * height * 2; in += 4) {
1128 yuv[in + 3] << 24 | yuv[in + 2] << 16 | yuv[in + 1] << 8 | yuv[in + 0];
1129 y0 = (pixel_16 & 0x000000ff);
1130 u = (pixel_16 & 0x0000ff00) >> 8;
1131 y1 = (pixel_16 & 0x00ff0000) >> 16;
1132 v = (pixel_16 & 0xff000000) >> 24;
1133 pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
1134 pixel_24[0] = (
unsigned char)(pixel32 & 0x000000ff);
1135 pixel_24[1] = (
unsigned char)((pixel32 & 0x0000ff00) >> 8);
1136 pixel_24[2] = (
unsigned char)((pixel32 & 0x00ff0000) >> 16);
1137 rgb[out++] = pixel_24[0];
1138 rgb[out++] = pixel_24[1];
1139 rgb[out++] = pixel_24[2];
1140 pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
1141 pixel_24[0] = (
unsigned char)(pixel32 & 0x000000ff);
1142 pixel_24[1] = (
unsigned char)((pixel32 & 0x0000ff00) >> 8);
1143 pixel_24[2] = (
unsigned char)((pixel32 & 0x00ff0000) >> 16);
1144 rgb[out++] = pixel_24[0];
1145 rgb[out++] = pixel_24[1];
1146 rgb[out++] = pixel_24[2];
1152void UsbCam::reconnect() {
uint64_t ToNanosecond() const
convert time to nanosecond.
static Time Now()
get the current time.
double ToSecond() const
convert time to second.
virtual bool init(const std::shared_ptr< Config > &camera_config)
bool wait_for_device(void)
virtual bool poll(const CameraImagePtr &raw_image, const CameraImagePtr &sensor_raw_image)
std::shared_ptr< CameraImage > CameraImagePtr
void yuyv2rgb_avx(unsigned char *YUV, unsigned char *RGB, int NumPixels)
#define AV_CODEC_ID_MJPEG