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.
This commit is contained in:
parent
0ac3e6fd5b
commit
3225851224
|
@ -340,7 +340,7 @@ LocalCamera::LocalCamera(
|
||||||
Debug(2, "V4L support enabled, using V4L%d api", v4l_version);
|
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
|
// We are the first, or only, input that uses this channel
|
||||||
channel_prime = true;
|
channel_prime = true;
|
||||||
channel_index = channel_count++;
|
channel_index = channel_count++;
|
||||||
|
@ -382,19 +382,19 @@ LocalCamera::LocalCamera(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( capture ) {
|
if (capture) {
|
||||||
if ( last_camera ) {
|
if (last_camera) {
|
||||||
if ( (p_method == "v4l2" && v4l_version != 2) || (p_method == "v4l1" && v4l_version != 1) )
|
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" );
|
Fatal("Different Video For Linux version used for monitors sharing same device");
|
||||||
|
|
||||||
if ( standard != last_camera->standard )
|
if (standard != last_camera->standard)
|
||||||
Warning( "Different video standards defined for monitors sharing same device, results may be unpredictable or completely wrong" );
|
Warning("Different video standards defined for monitors sharing same device, results may be unpredictable or completely wrong");
|
||||||
|
|
||||||
if ( palette != last_camera->palette )
|
if (palette != last_camera->palette)
|
||||||
Warning( "Different video palettes defined for monitors sharing same device, results may be unpredictable or completely wrong" );
|
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 )
|
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" );
|
Warning("Different capture sizes defined for monitors sharing same device, results may be unpredictable or completely wrong");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE
|
#if HAVE_LIBSWSCALE
|
||||||
|
@ -676,6 +676,8 @@ LocalCamera::LocalCamera(
|
||||||
imgConversionContext = nullptr;
|
imgConversionContext = nullptr;
|
||||||
} // end if capture and conversion_tye == swscale
|
} // end if capture and conversion_tye == swscale
|
||||||
#endif
|
#endif
|
||||||
|
if ( device_prime )
|
||||||
|
Initialise();
|
||||||
} // end LocalCamera::LocalCamera
|
} // end LocalCamera::LocalCamera
|
||||||
|
|
||||||
LocalCamera::~LocalCamera() {
|
LocalCamera::~LocalCamera() {
|
||||||
|
@ -1971,7 +1973,10 @@ int LocalCamera::Contrast( int p_contrast ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int LocalCamera::PrimeCapture() {
|
int LocalCamera::PrimeCapture() {
|
||||||
Initialise();
|
|
||||||
|
get_VideoStream();
|
||||||
|
if ( !device_prime )
|
||||||
|
return 1;
|
||||||
|
|
||||||
Debug(2, "Priming capture");
|
Debug(2, "Priming capture");
|
||||||
#if ZM_HAS_V4L2
|
#if ZM_HAS_V4L2
|
||||||
|
@ -1989,8 +1994,10 @@ int LocalCamera::PrimeCapture() {
|
||||||
vid_buf.memory = v4l2_data.reqbufs.memory;
|
vid_buf.memory = v4l2_data.reqbufs.memory;
|
||||||
vid_buf.index = frame;
|
vid_buf.index = frame;
|
||||||
|
|
||||||
if ( vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0 )
|
if (vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0) {
|
||||||
Fatal("Failed to queue buffer %d: %s", frame, strerror(errno));
|
Error("Failed to queue buffer %d: %s", frame, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v4l2_data.bufptr = nullptr;
|
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_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
//enum v4l2_buf_type type = v4l2_data.fmt.type;
|
//enum v4l2_buf_type type = v4l2_data.fmt.type;
|
||||||
enum v4l2_buf_type type = (v4l2_buf_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 )
|
if (vidioctl(vid_fd, VIDIOC_STREAMON, &type) < 0) {
|
||||||
Fatal("Failed to start capture stream: %s", strerror(errno));
|
Error("Failed to start capture stream: %s", strerror(errno));
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
} // end if v4l_version == 2
|
||||||
#endif // ZM_HAS_V4L2
|
#endif // ZM_HAS_V4L2
|
||||||
#if ZM_HAS_V4L1
|
#if ZM_HAS_V4L1
|
||||||
if ( v4l_version == 1 ) {
|
if ( v4l_version == 1 ) {
|
||||||
|
@ -2013,7 +2022,6 @@ int LocalCamera::PrimeCapture() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ZM_HAS_V4L1
|
#endif // ZM_HAS_V4L1
|
||||||
mVideoStreamId = 0;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} // end LocalCamera::PrimeCapture
|
} // end LocalCamera::PrimeCapture
|
||||||
|
@ -2046,7 +2054,6 @@ int LocalCamera::Capture(ZMPacket &zm_packet) {
|
||||||
memset(&vid_buf, 0, sizeof(vid_buf));
|
memset(&vid_buf, 0, sizeof(vid_buf));
|
||||||
|
|
||||||
vid_buf.type = v4l2_data.fmt.type;
|
vid_buf.type = v4l2_data.fmt.type;
|
||||||
//vid_buf.memory = V4L2_MEMORY_MMAP;
|
|
||||||
vid_buf.memory = v4l2_data.reqbufs.memory;
|
vid_buf.memory = v4l2_data.reqbufs.memory;
|
||||||
|
|
||||||
Debug(3, "Capturing %d frames", captures_per_frame);
|
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];
|
buffer = v4l1_data.bufptr+v4l1_data.frames.offsets[capture_frame];
|
||||||
}
|
}
|
||||||
#endif // ZM_HAS_V4L1
|
#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 */
|
} /* prime capture */
|
||||||
|
|
||||||
|
@ -2179,69 +2245,8 @@ int LocalCamera::Capture(ZMPacket &zm_packet) {
|
||||||
} // end int LocalCamera::Capture()
|
} // end int LocalCamera::Capture()
|
||||||
|
|
||||||
int LocalCamera::PostCapture() {
|
int LocalCamera::PostCapture() {
|
||||||
|
return 1;
|
||||||
Debug(4, "Post-capturing");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue