v4l2slh264dec: Add a helper to ensure output buffer

In preparation of multi-slice decoding, we will decode multiple
slices into the same buffer. This will ensure we have a buffer to
decode to, queued into the driver.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1395>
This commit is contained in:
Nicolas Dufresne 2020-06-29 13:04:56 -04:00
parent d65f7de650
commit 779f331bd4

View file

@ -900,14 +900,45 @@ gst_v4l2_codec_h264_dec_reset_picture (GstV4l2CodecH264Dec * self)
self->decode_params.num_slices = 0; self->decode_params.num_slices = 0;
} }
static gboolean
gst_v4l2_codec_h264_dec_ensure_output_buffer (GstV4l2CodecH264Dec * self,
GstVideoCodecFrame * frame)
{
GstBuffer *buffer;
GstFlowReturn flow_ret;
if (frame->output_buffer)
return TRUE;
flow_ret = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (self->src_pool),
&buffer, NULL);
if (flow_ret != GST_FLOW_OK) {
if (flow_ret == GST_FLOW_FLUSHING)
GST_DEBUG_OBJECT (self, "Frame decoding aborted, we are flushing.");
else
GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
("No more picture buffer available."), (NULL));
return FALSE;
}
if (!gst_v4l2_decoder_queue_src_buffer (self->decoder, buffer,
frame->system_frame_number)) {
GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
("Driver did not accept the picture buffer."), (NULL));
gst_buffer_unref (buffer);
return FALSE;
}
frame->output_buffer = buffer;
return TRUE;
}
static gboolean static gboolean
gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self, gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self,
GstH264Picture * picture, guint flags) GstH264Picture * picture, guint flags)
{ {
GstVideoCodecFrame *frame; GstVideoCodecFrame *frame;
GstV4l2Request *request; GstV4l2Request *request;
GstBuffer *buffer;
GstFlowReturn flow_ret;
gsize bytesused; gsize bytesused;
gboolean ret = FALSE; gboolean ret = FALSE;
@ -952,22 +983,13 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self,
gst_h264_picture_set_user_data (picture, request, gst_h264_picture_set_user_data (picture, request,
(GDestroyNotify) gst_v4l2_request_free); (GDestroyNotify) gst_v4l2_request_free);
flow_ret = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (self->src_pool),
&buffer, NULL);
if (flow_ret != GST_FLOW_OK) {
if (flow_ret == GST_FLOW_FLUSHING)
GST_DEBUG_OBJECT (self, "Frame decoding aborted, we are flushing.");
else
GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
("No more picture buffer available."), (NULL));
goto done;
}
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
picture->system_frame_number); picture->system_frame_number);
g_return_val_if_fail (frame, FALSE); g_return_val_if_fail (frame, FALSE);
g_warn_if_fail (frame->output_buffer == NULL);
frame->output_buffer = buffer; if (!gst_v4l2_codec_h264_dec_ensure_output_buffer (self, frame))
goto done;
gst_video_codec_frame_unref (frame); gst_video_codec_frame_unref (frame);
if (!gst_v4l2_decoder_set_controls (self->decoder, request, control, if (!gst_v4l2_decoder_set_controls (self->decoder, request, control,
@ -988,13 +1010,6 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self,
goto done; goto done;
} }
if (!gst_v4l2_decoder_queue_src_buffer (self->decoder, buffer,
picture->system_frame_number)) {
GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
("Driver did not accept the picture buffer."), (NULL));
goto done;
}
if (!gst_v4l2_request_queue (request)) { if (!gst_v4l2_request_queue (request)) {
GST_ELEMENT_ERROR (self, RESOURCE, WRITE, GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
("Driver did not accept the decode request."), (NULL)); ("Driver did not accept the decode request."), (NULL));