From ad5dcfb0912a17d4f8a77c59750bcdfee399b175 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 19 Aug 2021 11:40:22 -0400 Subject: [PATCH] v4l2codec: h264: Implement support for split fields When a frame is composed of two fields, the base class now split the picture in two. In order to support this, we need to ensure that picture buffer is held in VB2 queue so that the second field get decoded into it. This also implements the new_field_picture() virtual and sets the previous request on the new picture. Part-of: --- sys/v4l2codecs/gstv4l2codech264dec.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/sys/v4l2codecs/gstv4l2codech264dec.c b/sys/v4l2codecs/gstv4l2codech264dec.c index 5c912ed..bd482b5 100644 --- a/sys/v4l2codecs/gstv4l2codech264dec.c +++ b/sys/v4l2codecs/gstv4l2codech264dec.c @@ -1216,7 +1216,37 @@ gst_v4l2_codec_h264_dec_end_picture (GstH264Decoder * decoder, GstH264Picture * picture) { GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder); - return gst_v4l2_codec_h264_dec_submit_bitstream (self, picture, 0); + guint flags = 0; + + /* Hold on the output frame if this is first field of a pair */ + if (picture->field != GST_H264_PICTURE_FIELD_FRAME && !picture->second_field) + flags = V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; + + return gst_v4l2_codec_h264_dec_submit_bitstream (self, picture, flags); +} + +static gboolean +gst_v4l2_codec_h264_dec_new_field_picture (GstH264Decoder * decoder, + const GstH264Picture * first_field, GstH264Picture * second_field) +{ + GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder); + GstV4l2Request *request = + gst_h264_picture_get_user_data ((GstH264Picture *) first_field); + + if (!request) { + GST_WARNING_OBJECT (self, + "First picture does not have an associated request"); + return TRUE; + } + + GST_DEBUG_OBJECT (self, "Assigned request %p to second field.", request); + + /* Associate the previous request with the new picture so that + * submit_bitstream can create sub-request */ + gst_h264_picture_set_user_data (second_field, gst_v4l2_request_ref (request), + (GDestroyNotify) gst_v4l2_request_unref); + + return TRUE; } static guint @@ -1393,6 +1423,8 @@ gst_v4l2_codec_h264_dec_subclass_init (GstV4l2CodecH264DecClass * klass, GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_decode_slice); h264decoder_class->end_picture = GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_end_picture); + h264decoder_class->new_field_picture = + GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_new_field_picture); h264decoder_class->get_preferred_output_delay = GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_get_preferred_output_delay); -- 2.7.4