codecs: Signal required DPB size for AV1,MPEG2,VP8, and VP9 via new_sequence()
authorSeungha Yang <seungha@centricular.com>
Wed, 27 Apr 2022 19:25:05 +0000 (04:25 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 3 May 2022 14:17:49 +0000 (14:17 +0000)
Make all codecs consistent so that subclass can know additional DPB
size requirement depending on render-delay configuration regardless
of codec. Note that render-delay feature is not implemented for AV1
yet but it's planned.

Also, consider new_sequence() is mandatory requirement, not optional

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2343>

21 files changed:
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstav1decoder.c
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstav1decoder.h
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstmpeg2decoder.c
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstmpeg2decoder.h
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstvp8decoder.c
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstvp8decoder.h
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstvp9decoder.c
subprojects/gst-plugins-bad/gst-libs/gst/codecs/gstvp9decoder.h
subprojects/gst-plugins-bad/sys/d3d11/gstd3d11av1dec.cpp
subprojects/gst-plugins-bad/sys/d3d11/gstd3d11mpeg2dec.cpp
subprojects/gst-plugins-bad/sys/d3d11/gstd3d11vp8dec.cpp
subprojects/gst-plugins-bad/sys/d3d11/gstd3d11vp9dec.cpp
subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.c
subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.c
subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c
subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp8dec.c
subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c
subprojects/gst-plugins-bad/sys/va/gstvaav1dec.c
subprojects/gst-plugins-bad/sys/va/gstvampeg2dec.c
subprojects/gst-plugins-bad/sys/va/gstvavp8dec.c
subprojects/gst-plugins-bad/sys/va/gstvavp9dec.c

index 6b1ef63..e3acbac 100644 (file)
@@ -273,7 +273,8 @@ gst_av1_decoder_process_sequence (GstAV1Decoder * self, GstAV1OBU * obu)
       priv->max_width, priv->max_height, seq_header.max_frame_width_minus_1 + 1,
       seq_header.max_frame_height_minus_1 + 1);
 
-  ret = klass->new_sequence (self, &seq_header);
+  /* TODO: Implement render delay */
+  ret = klass->new_sequence (self, &seq_header, GST_AV1_TOTAL_REFS_PER_FRAME);
   if (ret != GST_FLOW_OK) {
     GST_ERROR_OBJECT (self, "subclass does not want accept new sequence");
     return ret;
index dc0e953..cc0191f 100644 (file)
@@ -70,13 +70,16 @@ struct _GstAV1DecoderClass
    * GstAV1DecoderClass::new_sequence:
    * @decoder: a #GstAV1Decoder
    * @seq_hdr: a #GstAV1SequenceHeaderOBU
+   * @max_dpb_size: the size of dpb including preferred output delay
+   *   by subclass reported via get_preferred_output_delay method.
    *
    * Notifies subclass of SPS update
    *
    * Since: 1.20
    */
   GstFlowReturn   (*new_sequence)      (GstAV1Decoder * decoder,
-                                        const GstAV1SequenceHeaderOBU * seq_hdr);
+                                        const GstAV1SequenceHeaderOBU * seq_hdr,
+                                        gint max_dpb_size);
   /**
    * GstAV1DecoderClass::new_picture:
    * @decoder: a #GstAV1Decoder
index d6571fa..988eb7c 100644 (file)
@@ -741,6 +741,8 @@ gst_mpeg2_decoder_handle_picture (GstMpeg2Decoder * decoder,
   GstMpegVideoPictureHdr pic_hdr = { 0, };
   GstMpeg2DecoderClass *klass = GST_MPEG2_DECODER_GET_CLASS (decoder);
 
+  g_assert (klass->new_sequence);
+
   if (!_is_valid_state (decoder, GST_MPEG2_DECODER_STATE_VALID_SEQ_HEADERS)) {
     GST_ERROR_OBJECT (decoder, "no sequence before parsing picture header");
     return GST_FLOW_ERROR;
@@ -767,24 +769,27 @@ gst_mpeg2_decoder_handle_picture (GstMpeg2Decoder * decoder,
       priv->need_to_drain = FALSE;
     }
 
-    if (klass->get_preferred_output_delay)
+    if (klass->get_preferred_output_delay) {
       priv->preferred_output_delay =
           klass->get_preferred_output_delay (decoder, priv->is_live);
+    } else {
+      priv->preferred_output_delay = 0;
+    }
 
     priv->seq_changed = FALSE;
 
-    if (klass->new_sequence) {
-      ret = klass->new_sequence (decoder, &priv->seq_hdr,
-          _seq_ext_is_valid (&priv->seq_ext) ? &priv->seq_ext : NULL,
-          _seq_display_ext_is_valid (&priv->seq_display_ext) ?
-          &priv->seq_display_ext : NULL,
-          _seq_scalable_ext_is_valid (&priv->seq_scalable_ext) ?
-          &priv->seq_scalable_ext : NULL);
+    ret = klass->new_sequence (decoder, &priv->seq_hdr,
+        _seq_ext_is_valid (&priv->seq_ext) ? &priv->seq_ext : NULL,
+        _seq_display_ext_is_valid (&priv->seq_display_ext) ?
+        &priv->seq_display_ext : NULL,
+        _seq_scalable_ext_is_valid (&priv->seq_scalable_ext) ?
+        &priv->seq_scalable_ext : NULL,
+        /* previous/next 2 pictures */
+        2 + priv->preferred_output_delay);
 
-      if (ret != GST_FLOW_OK) {
-        GST_WARNING_OBJECT (decoder, "new sequence error");
-        return ret;
-      }
+    if (ret != GST_FLOW_OK) {
+      GST_WARNING_OBJECT (decoder, "new sequence error");
+      return ret;
     }
   }
 
index 0e36084..2fa4fc3 100644 (file)
@@ -73,6 +73,8 @@ struct _GstMpeg2DecoderClass
    * @decoder: a #GstMpeg2Decoder
    * @seq: a #GstMpegVideoSequenceHdr
    * @seq_ext: a #GstMpegVideoSequenceExt
+   * @max_dpb_size: the size of dpb including preferred output delay
+   *   by subclass reported via get_preferred_output_delay method.
    *
    * Notifies subclass of SPS update
    *
@@ -82,7 +84,8 @@ struct _GstMpeg2DecoderClass
                                      const GstMpegVideoSequenceHdr * seq,
                                      const GstMpegVideoSequenceExt * seq_ext,
                                      const GstMpegVideoSequenceDisplayExt * seq_display_ext,
-                                     const GstMpegVideoSequenceScalableExt * seq_scalable_ext);
+                                     const GstMpegVideoSequenceScalableExt * seq_scalable_ext,
+                                     gint max_dpb_size);
 
   /**
    * GstMpeg2DecoderClass::new_picture:
index 379e8d7..9afb8d8 100644 (file)
@@ -178,14 +178,18 @@ gst_vp8_decoder_check_codec_change (GstVp8Decoder * self,
 
     priv->had_sequence = TRUE;
 
-    if (klass->get_preferred_output_delay)
+    if (klass->get_preferred_output_delay) {
       priv->preferred_output_delay =
           klass->get_preferred_output_delay (self, priv->is_live);
-    else
+    } else {
       priv->preferred_output_delay = 0;
+    }
+
+    g_assert (klass->new_sequence);
 
-    if (klass->new_sequence)
-      ret = klass->new_sequence (self, frame_hdr);
+    ret = klass->new_sequence (self, frame_hdr,
+        /* last/golden/alt 3 pictures */
+        3 + priv->preferred_output_delay);
   }
 
   return ret;
index e147afb..7cc32b3 100644 (file)
@@ -89,7 +89,8 @@ struct _GstVp8DecoderClass
   GstVideoDecoderClass parent_class;
 
   GstFlowReturn   (*new_sequence)      (GstVp8Decoder * decoder,
-                                        const GstVp8FrameHdr * frame_hdr);
+                                        const GstVp8FrameHdr * frame_hdr,
+                                        gint max_dpb_size);
 
   /**
    * GstVp8DecoderClass:new_picture:
index 6d7eb53..f5ad4d2 100644 (file)
@@ -216,6 +216,8 @@ gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
   GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
   GstFlowReturn ret = GST_FLOW_OK;
 
+  g_assert (klass->new_sequence);
+
   if (priv->had_sequence && !gst_vp9_decoder_is_format_change (self, frame_hdr)) {
     return GST_FLOW_OK;
   }
@@ -243,8 +245,8 @@ gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
     priv->preferred_output_delay = 0;
   }
 
-  if (klass->new_sequence)
-    ret = klass->new_sequence (self, frame_hdr);
+  ret = klass->new_sequence (self, frame_hdr,
+      GST_VP9_REF_FRAMES + priv->preferred_output_delay);
 
   if (ret != GST_FLOW_OK)
     priv->had_sequence = FALSE;
index 7f68898..d68cb4a 100644 (file)
@@ -67,6 +67,10 @@ struct _GstVp9DecoderClass
 
   /**
    * GstVp9DecoderClass::new_sequence:
+   * @decoder: a #GstVp9Decoder
+   * @frame_hdr: a #GstVp9FrameHeader
+   * @max_dpb_size: the size of dpb including preferred output delay
+   *   by subclass reported via get_preferred_output_delay method.
    *
    * Notifies subclass of video sequence update such as resolution, bitdepth,
    * profile.
@@ -74,7 +78,8 @@ struct _GstVp9DecoderClass
    * Since: 1.18
    */
   GstFlowReturn   (*new_sequence)      (GstVp9Decoder * decoder,
-                                        const GstVp9FrameHeader *frame_hdr);
+                                        const GstVp9FrameHeader *frame_hdr,
+                                        gint max_dpb_size);
 
   /**
    * GstVp9DecoderClass::new_picture:
index b339a37..6d19cd6 100644 (file)
@@ -423,7 +423,7 @@ static gboolean gst_d3d11_av1_dec_sink_event (GstVideoDecoder * decoder,
 
 /* GstAV1Decoder */
 static GstFlowReturn gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
-    const GstAV1SequenceHeaderOBU * seq_hdr);
+    const GstAV1SequenceHeaderOBU * seq_hdr, gint max_dpb_size);
 static GstFlowReturn gst_d3d11_av1_dec_new_picture (GstAV1Decoder * decoder,
     GstVideoCodecFrame * frame, GstAV1Picture * picture);
 static GstAV1Picture *gst_d3d11_av1_dec_duplicate_picture (GstAV1Decoder *
@@ -630,7 +630,7 @@ gst_d3d11_av1_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
 
 static GstFlowReturn
 gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
-    const GstAV1SequenceHeaderOBU * seq_hdr)
+    const GstAV1SequenceHeaderOBU * seq_hdr, gint max_dpb_size)
 {
   GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
   GstD3D11AV1DecInner *inner = self->inner;
index 5d9e457..21f1e8f 100644 (file)
@@ -120,7 +120,8 @@ static GstFlowReturn gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder *
     decoder, const GstMpegVideoSequenceHdr * seq,
     const GstMpegVideoSequenceExt * seq_ext,
     const GstMpegVideoSequenceDisplayExt * seq_display_ext,
-    const GstMpegVideoSequenceScalableExt * seq_scalable_ext);
+    const GstMpegVideoSequenceScalableExt * seq_scalable_ext,
+    gint max_dpb_size);
 static GstFlowReturn gst_d3d11_mpeg2_dec_new_picture (GstMpeg2Decoder * decoder,
     GstVideoCodecFrame * frame, GstMpeg2Picture * picture);
 static GstFlowReturn
@@ -332,7 +333,7 @@ gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
     const GstMpegVideoSequenceHdr * seq,
     const GstMpegVideoSequenceExt * seq_ext,
     const GstMpegVideoSequenceDisplayExt * seq_display_ext,
-    const GstMpegVideoSequenceScalableExt * seq_scalable_ext)
+    const GstMpegVideoSequenceScalableExt * seq_scalable_ext, gint max_dpb_size)
 {
   GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
   GstD3D11Mpeg2DecInner *inner = self->inner;
index 92f3d89..93bcf77 100644 (file)
@@ -111,7 +111,7 @@ static gboolean gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder,
 
 /* GstVp8Decoder */
 static GstFlowReturn gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
-    const GstVp8FrameHdr * frame_hdr);
+    const GstVp8FrameHdr * frame_hdr, gint max_dpb_size);
 static GstFlowReturn gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture);
 static GstFlowReturn gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
@@ -313,7 +313,7 @@ gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder, GstEvent * event)
 
 static GstFlowReturn
 gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
-    const GstVp8FrameHdr * frame_hdr)
+    const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
 {
   GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
   GstD3D11Vp8DecInner *inner = self->inner;
index 47444b4..ab66a4e 100644 (file)
@@ -143,7 +143,7 @@ static gboolean gst_d3d11_vp9_dec_sink_event (GstVideoDecoder * decoder,
 
 /* GstVp9Decoder */
 static GstFlowReturn gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9FrameHeader * frame_hdr);
+    const GstVp9FrameHeader * frame_hdr, gint max_dpb_size);
 static GstFlowReturn gst_d3d11_vp9_dec_new_picture (GstVp9Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp9Picture * picture);
 static GstVp9Picture *gst_d3d11_vp9_dec_duplicate_picture (GstVp9Decoder *
@@ -361,7 +361,7 @@ gst_d3d11_vp9_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
 
 static GstFlowReturn
 gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9FrameHeader * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
 {
   GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
   GstD3D11Vp9DecInner *inner = self->inner;
index 2fb5443..d11fc8d 100644 (file)
@@ -74,7 +74,7 @@ static gboolean gst_nv_vp8_dec_src_query (GstVideoDecoder * decoder,
 
 /* GstVp8Decoder */
 static GstFlowReturn gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
-    const GstVp8FrameHdr * frame_hdr);
+    const GstVp8FrameHdr * frame_hdr, gint max_dpb_size);
 static GstFlowReturn gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture);
 static GstFlowReturn gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
@@ -232,7 +232,7 @@ gst_nv_vp8_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
 
 static GstFlowReturn
 gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
-    const GstVp8FrameHdr * frame_hdr)
+    const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
 {
   GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
   gboolean modified = FALSE;
index b77e0cc..6967859 100644 (file)
@@ -75,7 +75,7 @@ static gboolean gst_nv_vp9_dec_src_query (GstVideoDecoder * decoder,
 
 /* GstVp9Decoder */
 static GstFlowReturn gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9FrameHeader * frame_hdr);
+    const GstVp9FrameHeader * frame_hdr, gint max_dpb_size);
 static GstFlowReturn gst_nv_vp9_dec_new_picture (GstVp9Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp9Picture * picture);
 static GstVp9Picture *gst_nv_vp9_dec_duplicate_picture (GstVp9Decoder *
@@ -242,7 +242,7 @@ gst_nv_vp9_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
 
 static GstFlowReturn
 gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9FrameHeader * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
 {
   GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
   GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
index e3a31da..d7982c8 100644 (file)
@@ -360,7 +360,7 @@ gst_v4l2_codec_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
     const GstMpegVideoSequenceHdr * seq,
     const GstMpegVideoSequenceExt * seq_ext,
     const GstMpegVideoSequenceDisplayExt * seq_display_ext,
-    const GstMpegVideoSequenceScalableExt * seq_scalable_ext)
+    const GstMpegVideoSequenceScalableExt * seq_scalable_ext, gint max_dpb_size)
 {
   GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder);
   gboolean negotiation_needed = FALSE;
index 6d547c5..95a6df1 100644 (file)
@@ -450,7 +450,7 @@ gst_v4l2_codec_vp8_dec_fill_references (GstV4l2CodecVp8Dec * self)
 
 static GstFlowReturn
 gst_v4l2_codec_vp8_dec_new_sequence (GstVp8Decoder * decoder,
-    const GstVp8FrameHdr * frame_hdr)
+    const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
 {
   GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
   gboolean negotiation_needed = FALSE;
index 924d27b..5902c1b 100644 (file)
@@ -580,7 +580,7 @@ gst_v4l2_codec_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
 
 static GstFlowReturn
 gst_v4l2_codec_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9FrameHeader * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
 {
   GstV4l2CodecVp9Dec *self = GST_V4L2_CODEC_VP9_DEC (decoder);
   gboolean negotiation_needed = FALSE;
index 539251a..266e6c4 100644 (file)
@@ -247,7 +247,7 @@ gst_va_av1_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
 
 static GstFlowReturn
 gst_va_av1_dec_new_sequence (GstAV1Decoder * decoder,
-    const GstAV1SequenceHeaderOBU * seq_hdr)
+    const GstAV1SequenceHeaderOBU * seq_hdr, gint max_dpb_size)
 {
   GstVaAV1Dec *self = GST_VA_AV1_DEC (decoder);
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
index 2a8de73..641eba8 100644 (file)
@@ -220,7 +220,7 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
     const GstMpegVideoSequenceHdr * seq,
     const GstMpegVideoSequenceExt * seq_ext,
     const GstMpegVideoSequenceDisplayExt * seq_display_ext,
-    const GstMpegVideoSequenceScalableExt * seq_scalable_ext)
+    const GstMpegVideoSequenceScalableExt * seq_scalable_ext, gint max_dpb_size)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);
index bd88ba8..8863426 100644 (file)
@@ -143,7 +143,7 @@ _get_profile (GstVaVp8Dec * self, const GstVp8FrameHdr * frame_hdr)
 
 static GstFlowReturn
 gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
-    const GstVp8FrameHdr * frame_hdr)
+    const GstVp8FrameHdr * frame_hdr, gint max_dpb_size)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);
index 042f79a..ae9e47b 100644 (file)
@@ -145,7 +145,7 @@ _get_profile (GstVaVp9Dec * self, GstVP9Profile profile)
 
 static GstFlowReturn
 gst_va_vp9_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9FrameHeader * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr, gint max_dpb_size)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaVp9Dec *self = GST_VA_VP9_DEC (decoder);