From 32258512246cd240eb9aea227114e51e32cc1829 Mon Sep 17 00:00:00 2001 From: Isaac Isaac Date: Tue, 23 Feb 2021 13:11:34 -0500 Subject: [PATCH] Move call to Initialise into Constructor making sure that it only gets called once. Move channel switching out of PostCapture into just after capturing image in order to free up more time for image to stabilise while we do other things like timestamping etc which happen in Capture. --- src/zm_local_camera.cpp | 167 +++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 81 deletions(-) diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 67b3a8ac6..f5c884532 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -340,7 +340,7 @@ LocalCamera::LocalCamera( Debug(2, "V4L support enabled, using V4L%d api", v4l_version); } - if ( !last_camera || channel != last_camera->channel ) { + if ( (!last_camera) || (channel != last_camera->channel) ) { // We are the first, or only, input that uses this channel channel_prime = true; channel_index = channel_count++; @@ -382,19 +382,19 @@ LocalCamera::LocalCamera( } #endif - if ( capture ) { - if ( last_camera ) { - if ( (p_method == "v4l2" && v4l_version != 2) || (p_method == "v4l1" && v4l_version != 1) ) - Fatal( "Different Video For Linux version used for monitors sharing same device" ); + if (capture) { + if (last_camera) { + if ((p_method == "v4l2" && v4l_version != 2) || (p_method == "v4l1" && v4l_version != 1)) + Fatal("Different Video For Linux version used for monitors sharing same device"); - if ( standard != last_camera->standard ) - Warning( "Different video standards defined for monitors sharing same device, results may be unpredictable or completely wrong" ); + if (standard != last_camera->standard) + Warning("Different video standards defined for monitors sharing same device, results may be unpredictable or completely wrong"); - if ( palette != last_camera->palette ) - Warning( "Different video palettes defined for monitors sharing same device, results may be unpredictable or completely wrong" ); + if (palette != last_camera->palette) + Warning("Different video palettes defined for monitors sharing same device, results may be unpredictable or completely wrong"); - if ( width != last_camera->width || height != last_camera->height ) - Warning( "Different capture sizes defined for monitors sharing same device, results may be unpredictable or completely wrong" ); + if (width != last_camera->width or height != last_camera->height) + Warning("Different capture sizes defined for monitors sharing same device, results may be unpredictable or completely wrong"); } #if HAVE_LIBSWSCALE @@ -676,6 +676,8 @@ LocalCamera::LocalCamera( imgConversionContext = nullptr; } // end if capture and conversion_tye == swscale #endif + if ( device_prime ) + Initialise(); } // end LocalCamera::LocalCamera LocalCamera::~LocalCamera() { @@ -1971,7 +1973,10 @@ int LocalCamera::Contrast( int p_contrast ) { } int LocalCamera::PrimeCapture() { - Initialise(); + + get_VideoStream(); + if ( !device_prime ) + return 1; Debug(2, "Priming capture"); #if ZM_HAS_V4L2 @@ -1989,8 +1994,10 @@ int LocalCamera::PrimeCapture() { vid_buf.memory = v4l2_data.reqbufs.memory; vid_buf.index = frame; - if ( vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0 ) - Fatal("Failed to queue buffer %d: %s", frame, strerror(errno)); + if (vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0) { + Error("Failed to queue buffer %d: %s", frame, strerror(errno)); + return 0; + } } v4l2_data.bufptr = nullptr; @@ -1998,9 +2005,11 @@ int LocalCamera::PrimeCapture() { //enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //enum v4l2_buf_type type = v4l2_data.fmt.type; enum v4l2_buf_type type = (v4l2_buf_type)v4l2_data.fmt.type; - if ( vidioctl(vid_fd, VIDIOC_STREAMON, &type) < 0 ) - Fatal("Failed to start capture stream: %s", strerror(errno)); - } + if (vidioctl(vid_fd, VIDIOC_STREAMON, &type) < 0) { + Error("Failed to start capture stream: %s", strerror(errno)); + return -1; + } + } // end if v4l_version == 2 #endif // ZM_HAS_V4L2 #if ZM_HAS_V4L1 if ( v4l_version == 1 ) { @@ -2013,7 +2022,6 @@ int LocalCamera::PrimeCapture() { } } #endif // ZM_HAS_V4L1 - mVideoStreamId = 0; return 1; } // end LocalCamera::PrimeCapture @@ -2046,7 +2054,6 @@ int LocalCamera::Capture(ZMPacket &zm_packet) { memset(&vid_buf, 0, sizeof(vid_buf)); vid_buf.type = v4l2_data.fmt.type; - //vid_buf.memory = V4L2_MEMORY_MMAP; vid_buf.memory = v4l2_data.reqbufs.memory; Debug(3, "Capturing %d frames", captures_per_frame); @@ -2114,6 +2121,65 @@ int LocalCamera::Capture(ZMPacket &zm_packet) { buffer = v4l1_data.bufptr+v4l1_data.frames.offsets[capture_frame]; } #endif // ZM_HAS_V4L1 +#if ZM_HAS_V4L2 + if ( v4l_version == 2 ) { + if ( channel_count > 1 ) { + int next_channel = (channel_index+1)%channel_count; + Debug(3, "Switching video source to %d", channels[next_channel]); + if ( vidioctl(vid_fd, VIDIOC_S_INPUT, &channels[next_channel]) < 0 ) { + Error("Failed to set camera source %d: %s", channels[next_channel], strerror(errno)); + return -1; + } + + v4l2_std_id stdId = standards[next_channel]; + if ( vidioctl(vid_fd, VIDIOC_S_STD, &stdId) < 0 ) { + Error("Failed to set video format %d: %s", standards[next_channel], strerror(errno)); + } + } + if ( v4l2_data.bufptr ) { + Debug(3, "Requeueing buffer %d", v4l2_data.bufptr->index); + if ( vidioctl(vid_fd, VIDIOC_QBUF, v4l2_data.bufptr) < 0 ) { + Error("Unable to requeue buffer %d: %s", v4l2_data.bufptr->index, strerror(errno)); + return -1; + } + } else { + Error("Unable to requeue buffer due to not v4l2_data") + } + } +#if ZM_HAS_V4L1 + else +#endif // ZM_HAS_V4L1 +#endif // ZM_HAS_V4L2 +#if ZM_HAS_V4L1 + if ( v4l_version == 1 ) { + if ( channel_count > 1 ) { + Debug(3, "Switching video source"); + int next_channel = (channel_index+1)%channel_count; + struct video_channel vid_src; + memset(&vid_src, 0, sizeof(vid_src)); + vid_src.channel = channel; + if ( ioctl(vid_fd, VIDIOCGCHAN, &vid_src) < 0 ) { + Error("Failed to get camera source %d: %s", channel, strerror(errno)); + return -1; + } + + vid_src.channel = channels[next_channel]; + vid_src.norm = standards[next_channel]; + vid_src.flags = 0; + vid_src.type = VIDEO_TYPE_CAMERA; + if ( ioctl(vid_fd, VIDIOCSCHAN, &vid_src) < 0 ) { + Error("Failed to set camera source %d: %s", channel, strerror(errno)); + return -1; + } + } + Debug(3, "Requeueing frame %d", v4l1_data.active_frame); + if ( ioctl(vid_fd, VIDIOCMCAPTURE, &v4l1_data.buffers[v4l1_data.active_frame]) < 0 ) { + Error("Capture failure for frame %d: %s", v4l1_data.active_frame, strerror(errno)); + return -1; + } + v4l1_data.active_frame = (v4l1_data.active_frame+1)%v4l1_data.frames.frames; + } +#endif // ZM_HAS_V4L1 } /* prime capture */ @@ -2179,69 +2245,8 @@ int LocalCamera::Capture(ZMPacket &zm_packet) { } // end int LocalCamera::Capture() int LocalCamera::PostCapture() { + return 1; Debug(4, "Post-capturing"); - // Requeue the buffer unless we need to switch or are a duplicate camera on a channel - if ( channel_count > 1 || channel_prime ) { -#if ZM_HAS_V4L2 - if ( v4l_version == 2 ) { - if ( channel_count > 1 ) { - int next_channel = (channel_index+1)%channel_count; - Debug(3, "Switching video source to %d", channels[next_channel]); - if ( vidioctl(vid_fd, VIDIOC_S_INPUT, &channels[next_channel]) < 0 ) { - Error("Failed to set camera source %d: %s", channels[next_channel], strerror(errno)); - return -1; - } - - v4l2_std_id stdId = standards[next_channel]; - if ( vidioctl(vid_fd, VIDIOC_S_STD, &stdId) < 0 ) { - Error("Failed to set video format %d: %s", standards[next_channel], strerror(errno)); - } - } - if ( v4l2_data.bufptr ) { - Debug(3, "Requeueing buffer %d", v4l2_data.bufptr->index); - if ( vidioctl(vid_fd, VIDIOC_QBUF, v4l2_data.bufptr) < 0 ) { - Error("Unable to requeue buffer %d: %s", v4l2_data.bufptr->index, strerror(errno)); - return -1; - } - } else { - Error("Unable to requeue buffer due to not v4l2_data") - } - } -#if ZM_HAS_V4L1 - else -#endif // ZM_HAS_V4L1 -#endif // ZM_HAS_V4L2 -#if ZM_HAS_V4L1 - if ( v4l_version == 1 ) { - if ( channel_count > 1 ) { - Debug(3, "Switching video source"); - int next_channel = (channel_index+1)%channel_count; - struct video_channel vid_src; - memset(&vid_src, 0, sizeof(vid_src)); - vid_src.channel = channel; - if ( ioctl(vid_fd, VIDIOCGCHAN, &vid_src) < 0 ) { - Error("Failed to get camera source %d: %s", channel, strerror(errno)); - return -1; - } - - vid_src.channel = channels[next_channel]; - vid_src.norm = standards[next_channel]; - vid_src.flags = 0; - vid_src.type = VIDEO_TYPE_CAMERA; - if ( ioctl(vid_fd, VIDIOCSCHAN, &vid_src) < 0 ) { - Error("Failed to set camera source %d: %s", channel, strerror(errno)); - return -1; - } - } - Debug(3, "Requeueing frame %d", v4l1_data.active_frame); - if ( ioctl(vid_fd, VIDIOCMCAPTURE, &v4l1_data.buffers[v4l1_data.active_frame]) < 0 ) { - Error("Capture failure for frame %d: %s", v4l1_data.active_frame, strerror(errno)); - return -1; - } - v4l1_data.active_frame = (v4l1_data.active_frame+1)%v4l1_data.frames.frames; - } -#endif // ZM_HAS_V4L1 - } return 0; }