v4l2: videodec: Move the capture setup into the processing loop

In previous implementation that job was split between handle_frame and
the processing loop and it wasn't clear if this mechanism was race
free. The capture setup would also be tried for every buffer, which was
not necessary.

This also simplify the handling of SRC_CH event, dropping the unneeded
atomic boolean.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4525>
This commit is contained in:
Nicolas Dufresne 2023-04-14 09:53:15 -04:00 committed by GStreamer Marge Bot
parent 20ddda2538
commit f01e71d4ad
2 changed files with 20 additions and 32 deletions

View file

@ -185,7 +185,6 @@ gst_v4l2_video_dec_start (GstVideoDecoder * decoder)
gst_v4l2_object_unlock (self->v4l2output); gst_v4l2_object_unlock (self->v4l2output);
g_atomic_int_set (&self->active, TRUE); g_atomic_int_set (&self->active, TRUE);
g_atomic_int_set (&self->capture_configuration_change, FALSE);
self->output_flow = GST_FLOW_OK; self->output_flow = GST_FLOW_OK;
return TRUE; return TRUE;
@ -708,28 +707,22 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
GstFlowReturn ret; GstFlowReturn ret;
GST_VIDEO_DECODER_STREAM_LOCK (decoder); GST_VIDEO_DECODER_STREAM_LOCK (decoder);
if (g_atomic_int_get (&self->capture_configuration_change)) { /* FIXME at the moment we need a capture pool to poll for SRC_CH, they may
gst_v4l2_object_stop (self->v4l2capture); * cause suprious reallocation. */
if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2capture))) {
ret = gst_v4l2_video_dec_setup_capture (decoder); ret = gst_v4l2_video_dec_setup_capture (decoder);
if (ret != GST_FLOW_OK) { if (ret != GST_FLOW_OK) {
GST_ERROR_OBJECT (decoder, "Failed setup capture queue.\n");
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
goto beach;
/* if caps negotiation failed, avoid trying it repeatly */
if (ret == GST_FLOW_NOT_NEGOTIATED) {
GST_ERROR_OBJECT (decoder,
"capture configuration change fail, return negotiation fail");
goto beach;
} else {
return;
}
} }
g_atomic_int_set (&self->capture_configuration_change, FALSE);
/* just a safety, as introducing mistakes in setup_capture seems rather
* easy.*/
g_return_if_fail (GST_V4L2_IS_ACTIVE (self->v4l2capture));
} }
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder); GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2capture)))
return;
GST_LOG_OBJECT (decoder, "Allocate output buffer"); GST_LOG_OBJECT (decoder, "Allocate output buffer");
self->output_flow = GST_FLOW_OK; self->output_flow = GST_FLOW_OK;
@ -752,8 +745,7 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) { if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) {
GST_INFO_OBJECT (decoder, "Received resolution change"); GST_INFO_OBJECT (decoder, "Received resolution change");
g_atomic_int_set (&self->capture_configuration_change, TRUE); goto resolution_changed;
return;
} }
if (ret != GST_FLOW_OK) if (ret != GST_FLOW_OK)
@ -771,8 +763,7 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) { if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) {
GST_INFO_OBJECT (decoder, "Received resolution change"); GST_INFO_OBJECT (decoder, "Received resolution change");
g_atomic_int_set (&self->capture_configuration_change, TRUE); goto resolution_changed;
return;
} }
} while (ret == GST_V4L2_FLOW_CORRUPTED_BUFFER); } while (ret == GST_V4L2_FLOW_CORRUPTED_BUFFER);
@ -846,6 +837,13 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
return; return;
resolution_changed:
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
/* FIXME, should be draining here */
gst_v4l2_object_stop (self->v4l2capture);
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
return;
beach: beach:
GST_DEBUG_OBJECT (decoder, "Leaving output thread: %s", GST_DEBUG_OBJECT (decoder, "Leaving output thread: %s",
gst_flow_get_name (ret)); gst_flow_get_name (ret));
@ -862,7 +860,7 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
{ {
GstV4l2Error error = GST_V4L2_ERROR_INIT; GstV4l2Error error = GST_V4L2_ERROR_INIT;
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (self->v4l2output); GstBufferPool *pool = NULL;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gboolean processed = FALSE; gboolean processed = FALSE;
GstBuffer *tmp; GstBuffer *tmp;
@ -881,14 +879,7 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
goto not_negotiated; goto not_negotiated;
} }
if (!g_atomic_int_get (&self->capture_configuration_change)) { pool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
ret = gst_v4l2_video_dec_setup_capture (decoder);
if (ret != GST_FLOW_OK) {
GST_ERROR_OBJECT (decoder, "setup capture fail\n");
goto not_negotiated;
}
}
if (G_UNLIKELY (!gst_buffer_pool_is_active (pool))) { if (G_UNLIKELY (!gst_buffer_pool_is_active (pool))) {
GstBuffer *codec_data; GstBuffer *codec_data;
GstStructure *config = gst_buffer_pool_get_config (pool); GstStructure *config = gst_buffer_pool_get_config (pool);

View file

@ -62,9 +62,6 @@ struct _GstV4l2VideoDec
GstVideoCodecState *input_state; GstVideoCodecState *input_state;
gboolean active; gboolean active;
GstFlowReturn output_flow; GstFlowReturn output_flow;
/* dynamic resolution change flag */
gboolean capture_configuration_change;
}; };
struct _GstV4l2VideoDecClass struct _GstV4l2VideoDecClass