v4l2videoenc: unconditionally activate the OUTPUT pool

If the v4l2videoenc receives an QUERY_ALLOCATION, it must not propose a
currently used pool, because it cannot be sure that the allocation query came
from exactly the same upstream element. The QUERY_ALLOCATION will not contain
the internal OUTPUT pool.

The upstream element (the basesrc) detects that the newly proposed pool differs
from the old pool. It deactivates the old pool and switches to the new pool.

If there was a format change, a new OUTPUT buffer pool will be allocated in
gst_v4l2_object_set_format_full() and the CAPTURE task will be stopped to switch
the format. If there hasn't been a format change,
gst_v4l2_object_set_format_full() will not be called. The old pool will be kept
and reused.

Without a format change, the processing task continues running.

This leads to the situation that the processing task is running, but the OUTPUT
buffer pool (the old pool) is deactivated. Therefore, the encoder is not able to
get buffers from the OUTPUT pool and encoding cannot continue.

This situation can be triggered by sending a RECONFIGURE event without a format
change.

Resolve this situation by ensuring that the OUTPUT buffer pool is always
activated when frames arrive at the encoder.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4235>
This commit is contained in:
Michael Tretter 2023-09-05 17:56:49 +02:00 committed by GStreamer Marge Bot
parent 41ce99ebab
commit 0563a25494

View file

@ -780,7 +780,9 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder,
ret = self->output_flow; ret = self->output_flow;
goto drop; goto drop;
} }
}
{
/* Ensure input internal output pool is active */ /* Ensure input internal output pool is active */
GstBufferPool *opool = gst_v4l2_object_get_buffer_pool (self->v4l2output); GstBufferPool *opool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
if (!gst_buffer_pool_is_active (opool)) { if (!gst_buffer_pool_is_active (opool)) {
@ -819,7 +821,9 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder,
if (opool) if (opool)
gst_object_unref (opool); gst_object_unref (opool);
} }
}
if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED) {
{ {
GstBufferPool *cpool = GstBufferPool *cpool =
gst_v4l2_object_get_buffer_pool (self->v4l2capture); gst_v4l2_object_get_buffer_pool (self->v4l2capture);