以下是icvRetrieveFrameCAM_V4L(CvCaptureCAM_V4L* capture,int)的源码,在Opencv3.1.0源码中cap_v4l.cpp中第1438行,被cap_v4l.cpp中第1794行retrieveFrame(int)调用,retrieveFrame(int)被cap.cpp第100行cvRetrieveFrame( CvCapture* capture, int idx )调用,cvRetrieveFrame( CvCapture* capture, int idx )被cap.cpp中第620行bool VideoCapture::retrieve(OutputArray image, int channel)调用,而bool VideoCapture::retrieve(OutputArray image, int channel)即为bool VideoCapture::read(OutputArray image)中调用的读取图像的函数。
static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) {
/* Now get what has already been captured as a IplImage return */
// we need memory iff convert_rgb is true
bool recreate_frame = capture->frame_allocated != capture->convert_rgb;
if (!capture->convert_rgb) {
// for mjpeg streams the size might change in between, so we have to change the header
recreate_frame += capture->frame.imageSize != (int)capture->buffers[capture->bufferIndex].length;
}
if(recreate_frame) {
// printf("realloc %d %zu\n", capture->frame.imageSize, capture->buffers[capture->bufferIndex].length);
if(capture->frame_allocated)
cvFree(&capture->frame.imageData);
v4l2_create_frame(capture);
}
if(!capture->convert_rgb) {
capture->frame.imageData = (char*)capture->buffers[capture->bufferIndex].start;
return &capture->frame;
}
switch (capture->palette)
{
case V4L2_PIX_FMT_BGR24:
memcpy((char *)capture->frame.imageData,
(char *)capture->buffers[capture->bufferIndex].start,
capture->frame.imageSize);
break;
case V4L2_PIX_FMT_YVU420:
yuv420p_to_rgb24(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)(capture->buffers[capture->bufferIndex].start),
(unsigned char*)capture->frame.imageData);
break;
case V4L2_PIX_FMT_YUV411P:
yuv411p_to_rgb24(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)(capture->buffers[capture->bufferIndex].start),
(unsigned char*)capture->frame.imageData);
break;
#ifdef HAVE_JPEG
case V4L2_PIX_FMT_MJPEG:
case V4L2_PIX_FMT_JPEG:
if (!mjpeg_to_rgb24(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)(capture->buffers[capture->bufferIndex]
.start),
capture->buffers[capture->bufferIndex].length,
&capture->frame))
return 0;
break;
#endif
case V4L2_PIX_FMT_YUYV:
yuyv_to_rgb24(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)(capture->buffers[capture->bufferIndex].start),
(unsigned char*)capture->frame.imageData);
break;
case V4L2_PIX_FMT_UYVY:
uyvy_to_rgb24(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)(capture->buffers[capture->bufferIndex].start),
(unsigned char*)capture->frame.imageData);
break;
case V4L2_PIX_FMT_SBGGR8:
bayer2rgb24(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)capture->buffers[capture->bufferIndex].start,
(unsigned char*)capture->frame.imageData);
break;
case V4L2_PIX_FMT_SN9C10X:
sonix_decompress_init();
sonix_decompress(capture->form.fmt.pix.width,
capture->form.fmt.pix.height,
(unsigned char*)capture->buffers[capture->bufferIndex].start,
(u