36 #define __STDC_CONSTANT_MACROS 46 #include <sys/types.h> 49 #include <sys/ioctl.h> 52 #include <boost/lexical_cast.hpp> 57 #define CLEAR(x) memset (&(x), 0, sizeof (x)) 63 ROS_ERROR(
"%s error %d, %s", s, errno, strerror(errno));
67 static int xioctl(
int fd,
int request,
void * arg)
72 r = ioctl(fd, request, arg);
73 while (-1 == r && EINTR == errno);
207 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
208 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
209 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
210 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
211 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
212 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
213 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
214 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
215 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
216 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
217 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
218 255, 255, 255, 255, 255, 255, 255, 255,
219 255, 255, 255, 255, 255, 255, 255, 255,
220 255, 255, 255, 255, 255, 255, 255, 255,
221 255, 255, 255, 255, 255, 255, 255, 255,
222 255, 255, 255, 255, 255, 255, 255, 255,
223 255, 255, 255, 255, 255, 255, 255, 255,
224 255, 255, 255, 255, 255, 255, 255, 255,
225 255, 255, 255, 255, 255, 255, 255, 255,
226 255, 255, 255, 255, 255, 255, 255, 255,
227 255, 255, 255, 255, 255, 255, 255, 255,
228 255, 255, 255, 255, 255, 255, 255, 255,
229 255, 255, 255, 255, 255, 255, 255, 255,
230 255, 255, 255, 255, 255, 255, 255, 255,
231 255, 255, 255, 255, 255, 255, 255, 255,
232 255, 255, 255, 255, 255, 255, 255, 255,
270 static void YUV2RGB(
const unsigned char y,
const unsigned char u,
const unsigned char v,
unsigned char* r,
271 unsigned char* g,
unsigned char* b)
273 const int y2 = (int)y;
274 const int u2 = (int)u - 128;
275 const int v2 = (int)v - 128;
284 int r2 = y2 + ((v2 * 37221) >> 15);
285 int g2 = y2 - (((u2 * 12975) + (v2 * 18949)) >> 15);
286 int b2 = y2 + ((u2 * 66883) >> 15);
298 unsigned char y0, y1, u, v;
299 unsigned char r, g, b;
300 for (i = 0, j = 0; i < (NumPixels << 1); i += 4, j += 6)
302 u = (
unsigned char)YUV[i + 0];
303 y0 = (
unsigned char)YUV[i + 1];
304 v = (
unsigned char)YUV[i + 2];
305 y1 = (
unsigned char)YUV[i + 3];
320 for (i = 0, j = 0; i < (NumPixels << 1); i += 2, j += 1)
323 MONO[j] = (
unsigned char)(((RAW[i + 0] >> 2) & 0x3F) | ((RAW[i + 1] << 6) & 0xC0));
327 static void yuyv2rgb(
char *YUV,
char *RGB,
int NumPixels)
330 unsigned char y0, y1, u, v;
331 unsigned char r, g, b;
333 for (i = 0, j = 0; i < (NumPixels << 1); i += 4, j += 6)
335 y0 = (
unsigned char)YUV[i + 0];
336 u = (
unsigned char)YUV[i + 1];
337 y1 = (
unsigned char)YUV[i + 2];
338 v = (
unsigned char)YUV[i + 3];
352 memcpy(RGB, YUV, NumPixels * 3);
357 : io_(IO_METHOD_MMAP), fd_(-1), buffers_(NULL), n_buffers_(0), avframe_camera_(NULL),
358 avframe_rgb_(NULL), avcodec_(NULL), avoptions_(NULL), avcodec_context_(NULL),
359 avframe_camera_size_(0), avframe_rgb_size_(0), video_sws_(NULL), image_(NULL), is_capturing_(false) {
368 avcodec_register_all();
373 ROS_ERROR(
"Could not find MJPEG decoder");
378 #if LIBAVCODEC_VERSION_MAJOR < 55 386 avpicture_alloc((AVPicture *)
avframe_rgb_, AV_PIX_FMT_RGB24, image_width, image_height);
392 #if LIBAVCODEC_VERSION_MAJOR > 52 398 avframe_rgb_size_ = avpicture_get_size(AV_PIX_FMT_RGB24, image_width, image_height);
403 ROS_ERROR(
"Could not open MJPEG Decoder");
415 #if LIBAVCODEC_VERSION_MAJOR > 52 418 av_init_packet(&avpkt);
421 avpkt.data = (
unsigned char*)MJPEG;
426 ROS_ERROR(
"Error while decoding frame.");
435 ROS_ERROR(
"Webcam: expected picture but didn't get it...");
457 ROS_ERROR(
"webcam: avpicture_layout error: %d", size);
487 struct v4l2_buffer buf;
519 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
520 buf.memory = V4L2_MEMORY_MMAP;
522 if (-1 ==
xioctl(
fd_, VIDIOC_DQBUF, &buf))
543 if (-1 ==
xioctl(
fd_, VIDIOC_QBUF, &buf))
551 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
552 buf.memory = V4L2_MEMORY_USERPTR;
554 if (-1 ==
xioctl(
fd_, VIDIOC_DQBUF, &buf))
575 assert(i < n_buffers_);
579 if (-1 ==
xioctl(
fd_, VIDIOC_QBUF, &buf))
597 enum v4l2_buf_type type;
607 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
609 if (-1 ==
xioctl(
fd_, VIDIOC_STREAMOFF, &type))
622 enum v4l2_buf_type type;
633 struct v4l2_buffer buf;
637 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
638 buf.memory = V4L2_MEMORY_MMAP;
641 if (-1 ==
xioctl(
fd_, VIDIOC_QBUF, &buf))
645 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
647 if (-1 ==
xioctl(
fd_, VIDIOC_STREAMON, &type))
655 struct v4l2_buffer buf;
659 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
660 buf.memory = V4L2_MEMORY_USERPTR;
665 if (-1 ==
xioctl(
fd_, VIDIOC_QBUF, &buf))
669 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
671 if (-1 ==
xioctl(
fd_, VIDIOC_STREAMON, &type))
726 struct v4l2_requestbuffers req;
731 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
732 req.memory = V4L2_MEMORY_MMAP;
734 if (-1 ==
xioctl(
fd_, VIDIOC_REQBUFS, &req))
763 struct v4l2_buffer buf;
767 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
768 buf.memory = V4L2_MEMORY_MMAP;
771 if (-1 ==
xioctl(
fd_, VIDIOC_QUERYBUF, &buf))
786 struct v4l2_requestbuffers req;
787 unsigned int page_size;
789 page_size = getpagesize();
790 buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
795 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
796 req.memory = V4L2_MEMORY_USERPTR;
798 if (-1 ==
xioctl(
fd_, VIDIOC_REQBUFS, &req))
835 struct v4l2_capability cap;
836 struct v4l2_cropcap cropcap;
837 struct v4l2_crop crop;
838 struct v4l2_format fmt;
841 if (-1 ==
xioctl(
fd_, VIDIOC_QUERYCAP, &cap))
854 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
863 if (!(cap.capabilities & V4L2_CAP_READWRITE))
873 if (!(cap.capabilities & V4L2_CAP_STREAMING))
886 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
888 if (0 ==
xioctl(
fd_, VIDIOC_CROPCAP, &cropcap))
890 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
891 crop.c = cropcap.defrect;
893 if (-1 ==
xioctl(
fd_, VIDIOC_S_CROP, &crop))
919 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
920 fmt.fmt.pix.width = image_width;
921 fmt.fmt.pix.height = image_height;
923 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
925 if (-1 ==
xioctl(
fd_, VIDIOC_S_FMT, &fmt))
931 min = fmt.fmt.pix.width * 2;
932 if (fmt.fmt.pix.bytesperline < min)
933 fmt.fmt.pix.bytesperline = min;
934 min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
935 if (fmt.fmt.pix.sizeimage < min)
936 fmt.fmt.pix.sizeimage = min;
938 image_width = fmt.fmt.pix.width;
939 image_height = fmt.fmt.pix.height;
941 struct v4l2_streamparm stream_params;
942 memset(&stream_params, 0,
sizeof(stream_params));
943 stream_params.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
944 if (
xioctl(
fd_, VIDIOC_G_PARM, &stream_params) < 0)
947 ROS_DEBUG(
"Capability flag: 0x%x", stream_params.parm.capture.capability);
949 stream_params.parm.capture.timeperframe.numerator = 1;
950 stream_params.parm.capture.timeperframe.denominator = framerate;
951 if (
xioctl(
fd_, VIDIOC_S_PARM, &stream_params) < 0)
952 ROS_WARN(
"Couldn't set camera framerate");
954 ROS_DEBUG(
"Set framerate to be %i", framerate);
974 if (-1 == close(
fd_))
990 if (!S_ISCHR(st.st_mode))
1044 init_device(image_width, image_height, framerate);
1114 r = select(
fd_ + 1, &fds, NULL, NULL, &tv);
1137 struct v4l2_queryctrl queryctrl;
1138 struct v4l2_ext_control control;
1140 memset(&queryctrl, 0,
sizeof(queryctrl));
1141 queryctrl.id = V4L2_CID_FOCUS_AUTO;
1143 if (-1 ==
xioctl(
fd_, VIDIOC_QUERYCTRL, &queryctrl))
1145 if (errno != EINVAL)
1147 perror(
"VIDIOC_QUERYCTRL");
1152 ROS_INFO(
"V4L2_CID_FOCUS_AUTO is not supported");
1156 else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
1158 ROS_INFO(
"V4L2_CID_FOCUS_AUTO is not supported");
1163 memset(&control, 0,
sizeof(control));
1164 control.id = V4L2_CID_FOCUS_AUTO;
1165 control.value = value;
1167 if (-1 ==
xioctl(
fd_, VIDIOC_S_CTRL, &control))
1169 perror(
"VIDIOC_S_CTRL");
1194 std::stringstream ss;
1195 ss <<
"v4l2-ctl --device=" <<
camera_dev_ <<
" -c " << param <<
"=" << value <<
" 2>&1";
1196 std::string
cmd = ss.str();
1200 int buffer_size = 256;
1201 char buffer[buffer_size];
1202 FILE *stream = popen(cmd.c_str(),
"r");
1205 while (!feof(stream))
1206 if (fgets(buffer, buffer_size, stream) != NULL)
1207 output.append(buffer);
1210 if (output.length() > 0)
1214 ROS_WARN(
"usb_cam_node could not run '%s'", cmd.c_str());
1221 else if (str ==
"read")
1223 else if (str ==
"userptr")
1233 else if (str ==
"uyvy")
1235 else if (str ==
"mjpeg")
1237 else if (str ==
"yuvmono10")
1239 else if (str ==
"rgb24")
1241 else if (str ==
"grey")
static void mono102mono8(char *RAW, char *MONO, int NumPixels)
int init_mjpeg_decoder(int image_width, int image_height)
void start_capturing(void)
void rgb242rgb(char *YUV, char *RGB, int NumPixels)
static int xioctl(int fd, int request, void *arg)
AVFrame * avframe_camera_
void set_auto_focus(int value)
void uyvy2rgb(char *YUV, char *RGB, int NumPixels)
struct SwsContext * video_sws_
void stop_capturing(void)
void process_image(const void *src, int len, camera_image_t *dest)
const int clipping_table_offset
static pixel_format pixel_format_from_string(const std::string &str)
void mjpeg2rgb(char *MJPEG, int len, char *RGB, int NumPixels)
unsigned int pixelformat_
void set_v4l_parameter(const std::string ¶m, int value)
static io_method io_method_from_string(const std::string &str)
void init_userp(unsigned int buffer_size)
AVDictionary * avoptions_
void init_device(int image_width, int image_height, int framerate)
static void YUV2RGB(const unsigned char y, const unsigned char u, const unsigned char v, unsigned char *r, unsigned char *g, unsigned char *b)
AVCodecContext * avcodec_context_
#define AV_CODEC_ID_MJPEG
const unsigned char uchar_clipping_table[]
void init_read(unsigned int buffer_size)
#define ROS_ERROR_STREAM(args)
static void errno_exit(const char *s)
void start(const std::string &dev, io_method io, pixel_format pf, int image_width, int image_height, int framerate)
static unsigned char CLIPVALUE(int val)
static void yuyv2rgb(char *YUV, char *RGB, int NumPixels)