From ee26c9c9a1b9fc49194888df1182e9d93a4da5b2 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 18 Mar 2020 17:00:37 -0400 Subject: [PATCH] v4l2slh264dec: Improve end_picture() robustness Use a goto to ensure that for all cases we cleanup the current picture state. And move the src buffer allocation higher, so we don't queue a bitstream buffer if we don't have a picture buffer to decode into. --- sys/v4l2codecs/gstv4l2codech264dec.c | 48 ++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/sys/v4l2codecs/gstv4l2codech264dec.c b/sys/v4l2codecs/gstv4l2codech264dec.c index 135a755..37f7e78 100644 --- a/sys/v4l2codecs/gstv4l2codech264dec.c +++ b/sys/v4l2codecs/gstv4l2codech264dec.c @@ -608,6 +608,8 @@ gst_v4l2_codec_h264_dec_output_picture (GstH264Decoder * decoder, GstH264Picture *other_pic; GstV4l2Request *other_request; + GST_DEBUG_OBJECT (self, "Output picture %u", picture->system_frame_number); + if (gst_v4l2_request_is_done (request)) goto finish_frame; @@ -718,17 +720,33 @@ gst_v4l2_codec_h264_dec_end_picture (GstH264Decoder * decoder, if (!request) { GST_ELEMENT_ERROR (decoder, RESOURCE, NO_SPACE_LEFT, ("Failed to allocate a media request object."), (NULL)); - return FALSE; + goto fail; } gst_h264_picture_set_user_data (picture, request, (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) { + /* FIXME our pool does not wait */ + GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, + ("No more picture buffer available."), (NULL)); + goto fail; + } + + frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), + picture->system_frame_number); + g_return_val_if_fail (frame, FALSE); + g_warn_if_fail (frame->output_buffer == NULL); + frame->output_buffer = buffer; + gst_video_codec_frame_unref (frame); + if (!gst_v4l2_decoder_set_controls (self->decoder, request, control, G_N_ELEMENTS (control))) { GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, ("Driver did not accept the bitstream parameters."), (NULL)); - return FALSE; + goto fail; } bytesused = self->bitstream_map.size; @@ -739,41 +757,29 @@ gst_v4l2_codec_h264_dec_end_picture (GstH264Decoder * decoder, picture->system_frame_number, bytesused)) { GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, ("Driver did not accept the bitstream data."), (NULL)); - return FALSE; - } - - flow_ret = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (self->src_pool), - &buffer, NULL); - if (flow_ret != GST_FLOW_OK) { - /* FIXME our pool does not wait */ - GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, - ("No more picture buffer available."), (NULL)); - gst_v4l2_codec_h264_dec_reset_picture (self); - return FALSE; + goto fail; } - frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), - picture->system_frame_number); - g_return_val_if_fail (frame, FALSE); - g_warn_if_fail (frame->output_buffer == NULL); - frame->output_buffer = buffer; - gst_video_codec_frame_unref (frame); if (!gst_v4l2_decoder_queue_src_buffer (self->decoder, buffer, picture->system_frame_number)) { GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, ("Driver did not accept the picture buffer."), (NULL)); - return FALSE; + goto fail; } if (!gst_v4l2_request_queue (request)) { GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, ("Driver did not accept the decode request."), (NULL)); - return FALSE; + goto fail; } gst_v4l2_codec_h264_dec_reset_picture (self); return TRUE; + +fail: + gst_v4l2_codec_h264_dec_reset_picture (self); + return FALSE; } static gboolean -- 2.7.4