va: Add and use common decode negotiate vmethod.
authorVictor Manuel Jaquez Leal <vjaquez@igalia.com>
Sat, 26 Nov 2022 08:11:39 +0000 (09:11 +0100)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Thu, 1 Dec 2022 18:54:14 +0000 (18:54 +0000)
This vmethod can be used by decoders with the same VA decoder reopen logic:
same profile, chroma, width and height.

Also a new public method called gst_va_base_dec_set_output_state() with the
common GStreamer code for setting the output state, which is always called by
the negotiate vmethod.

In order to do this refactoring, new variables in vabasedec have to be populated
by the decoders:

* width and height define the resolution set in VA decoder. In the case of H264
  would be de coded_width and codec_height, or max_width and max_height in AV1.
* output_info is the downstream video info used for negotiation in
  gst_va_base_dec_set_output_state().
* input_state, from codec parent class shall be also held by vabasedec

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

subprojects/gst-plugins-bad/sys/va/gstvabasedec.c
subprojects/gst-plugins-bad/sys/va/gstvabasedec.h
subprojects/gst-plugins-bad/sys/va/gstvah264dec.c
subprojects/gst-plugins-bad/sys/va/gstvah265dec.c
subprojects/gst-plugins-bad/sys/va/gstvampeg2dec.c
subprojects/gst-plugins-bad/sys/va/gstvavp8dec.c

index 4510fc0..4b168bf 100644 (file)
@@ -101,9 +101,8 @@ gst_va_base_dec_stop (GstVideoDecoder * decoder)
   if (!gst_va_decoder_close (base->decoder))
     return FALSE;
 
-  if (base->output_state)
-    gst_video_codec_state_unref (base->output_state);
-  base->output_state = NULL;
+  g_clear_pointer (&base->output_state, gst_video_codec_state_unref);
+  g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
 
   if (base->other_pool)
     gst_buffer_pool_set_active (base->other_pool, FALSE);
@@ -662,10 +661,41 @@ gst_va_base_dec_set_context (GstElement * element, GstContext * context)
       (element))->set_context (element, context);
 }
 
+static gboolean
+gst_va_base_dec_negotiate (GstVideoDecoder * decoder)
+{
+  GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
+
+  /* Ignore downstream renegotiation request. */
+  if (!base->need_negotiation)
+    return TRUE;
+
+  base->need_negotiation = FALSE;
+
+  if (!gst_va_decoder_config_is_equal (base->decoder, base->profile,
+          base->rt_format, base->width, base->height)) {
+    if (gst_va_decoder_is_open (base->decoder) &&
+        !gst_va_decoder_close (base->decoder))
+      return FALSE;
+    if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
+      return FALSE;
+    if (!gst_va_decoder_set_frame_size (base->decoder, base->width,
+            base->height))
+      return FALSE;
+  }
+
+  if (!gst_va_base_dec_set_output_state (base))
+    return FALSE;
+
+  return GST_VIDEO_DECODER_CLASS (GST_VA_BASE_DEC_GET_PARENT_CLASS (decoder))
+      ->negotiate (decoder);
+}
+
 void
 gst_va_base_dec_init (GstVaBaseDec * base, GstDebugCategory * cat)
 {
   base->debug_category = cat;
+  gst_video_info_init (&base->output_info);
 }
 
 void
@@ -713,6 +743,7 @@ gst_va_base_dec_class_init (GstVaBaseDecClass * klass, GstVaCodecs codec,
   decoder_class->sink_query = GST_DEBUG_FUNCPTR (gst_va_base_dec_sink_query);
   decoder_class->decide_allocation =
       GST_DEBUG_FUNCPTR (gst_va_base_dec_decide_allocation);
+  decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_base_dec_negotiate);
 
   g_object_class_install_property (object_class, GST_VA_DEC_PROP_DEVICE_PATH,
       g_param_spec_string ("device-path", "Device Path",
@@ -978,7 +1009,7 @@ gst_va_base_dec_copy_output_buffer (GstVaBaseDec * base,
 
   src_vinfo = &base->output_state->info;
   gst_video_info_set_format (&dest_vinfo, GST_VIDEO_INFO_FORMAT (src_vinfo),
-      base->width, base->height);
+      GST_VIDEO_INFO_WIDTH (src_vinfo), GST_VIDEO_INFO_HEIGHT (src_vinfo));
 
   ret = gst_buffer_pool_acquire_buffer (base->other_pool, &buffer, NULL);
   if (ret != GST_FLOW_OK)
@@ -1003,8 +1034,8 @@ gst_va_base_dec_copy_output_buffer (GstVaBaseDec * base,
   } else {
     /* gst_video_frame_copy can crop this, but does not know, so let
      * make it think it's all right */
-    GST_VIDEO_INFO_WIDTH (&src_frame.info) = base->width;
-    GST_VIDEO_INFO_HEIGHT (&src_frame.info) = base->height;
+    GST_VIDEO_INFO_WIDTH (&src_frame.info) = GST_VIDEO_INFO_WIDTH (src_vinfo);
+    GST_VIDEO_INFO_HEIGHT (&src_frame.info) = GST_VIDEO_INFO_HEIGHT (src_vinfo);
 
     if (!gst_video_frame_copy (&dest_frame, &src_frame)) {
       gst_video_frame_unmap (&src_frame);
@@ -1070,3 +1101,35 @@ gst_va_base_dec_prepare_output_frame (GstVaBaseDec * base,
     return gst_video_decoder_allocate_output_frame (vdec, frame);
   return GST_FLOW_OK;
 }
+
+gboolean
+gst_va_base_dec_set_output_state (GstVaBaseDec * base)
+{
+  GstVideoDecoder *decoder = GST_VIDEO_DECODER (base);
+  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
+  GstCapsFeatures *capsfeatures = NULL;
+  GstVideoInfo *info = &base->output_info;
+
+  if (base->output_state)
+    gst_video_codec_state_unref (base->output_state);
+
+  gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
+      &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
+
+  base->output_state =
+      gst_video_decoder_set_interlaced_output_state (decoder, format,
+      GST_VIDEO_INFO_INTERLACE_MODE (info), GST_VIDEO_INFO_WIDTH (info),
+      GST_VIDEO_INFO_HEIGHT (info), base->input_state);
+
+  /* set caps feature */
+  base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
+  if (capsfeatures)
+    gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
+
+  GST_INFO_OBJECT (base, "Negotiated caps %" GST_PTR_FORMAT,
+      base->output_state->caps);
+
+  return TRUE;
+}
index bc16e77..62b1ae8 100644 (file)
@@ -68,12 +68,15 @@ struct _GstVaBaseDec
 
   VAProfile profile;
   guint rt_format;
+  /* coded or max resolution */
   gint width;
   gint height;
 
   guint min_buffers;
 
+  GstVideoInfo output_info;
   GstVideoCodecState *output_state;
+  GstVideoCodecState *input_state;
   GstBufferPool *other_pool;
 
   gboolean need_valign;
@@ -137,5 +140,6 @@ gboolean              gst_va_base_dec_process_output      (GstVaBaseDec * base,
                                                            GstVideoBufferFlags buffer_flags);
 GstFlowReturn         gst_va_base_dec_prepare_output_frame (GstVaBaseDec * base,
                                                             GstVideoCodecFrame * frame);
+gboolean              gst_va_base_dec_set_output_state    (GstVaBaseDec * base);
 
 G_END_DECLS
index f8b452d..53f616f 100644 (file)
@@ -75,8 +75,6 @@ struct _GstVaH264Dec
 {
   GstVaBaseDec parent;
 
-  gint coded_width;
-  gint coded_height;
   gint dpb_size;
 
   /* Used to fill VAPictureParameterBufferH264.ReferenceFrames */
@@ -643,6 +641,7 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
+  GstVideoInfo *info = &base->output_info;
   VAProfile profile;
   gint display_width;
   gint display_height;
@@ -680,34 +679,35 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
           rt_format, sps->width, sps->height)) {
     base->profile = profile;
     base->rt_format = rt_format;
-    self->coded_width = sps->width;
-    self->coded_height = sps->height;
+    base->width = sps->width;
+    base->height = sps->height;
 
     negotiation_needed = TRUE;
     GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
-        gst_va_profile_name (profile), rt_format, self->coded_width,
-        self->coded_height);
+        gst_va_profile_name (profile), rt_format, base->width, base->height);
   }
 
-  if (base->width != display_width || base->height != display_height) {
-    base->width = display_width;
-    base->height = display_height;
+  if (GST_VIDEO_INFO_WIDTH (info) != display_width ||
+      GST_VIDEO_INFO_HEIGHT (info) != display_height) {
+    GST_VIDEO_INFO_WIDTH (info) = display_width;
+    GST_VIDEO_INFO_HEIGHT (info) = display_height;
 
     negotiation_needed = TRUE;
-    GST_INFO_OBJECT (self, "Resolution changed to %dx%d", base->width,
-        base->height);
+    GST_INFO_OBJECT (self, "Resolution changed to %dx%d",
+        GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
   }
 
   interlaced = !sps->frame_mbs_only_flag;
   if (self->interlaced != interlaced) {
     self->interlaced = interlaced;
-
+    GST_VIDEO_INFO_INTERLACE_MODE (info) = interlaced ?
+        GST_VIDEO_INTERLACE_MODE_MIXED : GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
     negotiation_needed = TRUE;
     GST_INFO_OBJECT (self, "Interlaced mode changed to %d", interlaced);
   }
 
-  base->need_valign = base->width < self->coded_width
-      || base->height < self->coded_height;
+  base->need_valign = GST_VIDEO_INFO_WIDTH (info) < base->width ||
+      GST_VIDEO_INFO_HEIGHT (info) < base->height;
   if (base->need_valign) {
     /* *INDENT-OFF* */
     if (base->valign.padding_left != padding_left ||
@@ -728,8 +728,9 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
   }
 
   base->min_buffers = self->dpb_size + 4;       /* dpb size + scratch surfaces */
-
   base->need_negotiation = negotiation_needed;
+  g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
+  base->input_state = gst_video_codec_state_ref (decoder->input_state);
 
   return GST_FLOW_OK;
 }
@@ -823,56 +824,6 @@ gst_va_h264_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
   return caps;
 }
 
-static gboolean
-gst_va_h264_dec_negotiate (GstVideoDecoder * decoder)
-{
-  GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
-  GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
-  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
-  GstCapsFeatures *capsfeatures = NULL;
-  GstH264Decoder *h264dec = GST_H264_DECODER (decoder);
-
-  /* Ignore downstream renegotiation request. */
-  if (!base->need_negotiation)
-    return TRUE;
-
-  base->need_negotiation = FALSE;
-
-  if (gst_va_decoder_is_open (base->decoder)
-      && !gst_va_decoder_close (base->decoder))
-    return FALSE;
-
-  if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
-    return FALSE;
-
-  if (!gst_va_decoder_set_frame_size (base->decoder, self->coded_width,
-          self->coded_height))
-    return FALSE;
-
-  if (base->output_state)
-    gst_video_codec_state_unref (base->output_state);
-
-  gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
-      &capsfeatures);
-  if (format == GST_VIDEO_FORMAT_UNKNOWN)
-    return FALSE;
-
-  base->output_state =
-      gst_video_decoder_set_output_state (decoder, format,
-      base->width, base->height, h264dec->input_state);
-  if (self->interlaced)
-    base->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
-
-  base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
-  if (capsfeatures)
-    gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
-
-  GST_INFO_OBJECT (self, "Negotiated caps %" GST_PTR_FORMAT,
-      base->output_state->caps);
-
-  return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
-}
-
 static void
 gst_va_h264_dec_dispose (GObject * object)
 {
@@ -926,7 +877,6 @@ gst_va_h264_dec_class_init (gpointer g_class, gpointer class_data)
   gobject_class->dispose = gst_va_h264_dec_dispose;
 
   decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h264_dec_getcaps);
-  decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_h264_dec_negotiate);
 
   h264decoder_class->new_sequence =
       GST_DEBUG_FUNCPTR (gst_va_h264_dec_new_sequence);
index 0273c12..53be567 100644 (file)
@@ -88,8 +88,6 @@ struct _GstVaH265Dec
 {
   GstVaBaseDec parent;
 
-  gint coded_width;
-  gint coded_height;
   gint dpb_size;
 
   VAPictureParameterBufferHEVCExtension pic_param;
@@ -1047,6 +1045,7 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
+  GstVideoInfo *info = &base->output_info;
   VAProfile profile;
   gint display_width;
   gint display_height;
@@ -1083,26 +1082,26 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
           rt_format, sps->width, sps->height)) {
     base->profile = profile;
     base->rt_format = rt_format;
-    self->coded_width = sps->width;
-    self->coded_height = sps->height;
+    base->width = sps->width;
+    base->height = sps->height;
 
     negotiation_needed = TRUE;
     GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
-        gst_va_profile_name (profile), rt_format, self->coded_width,
-        self->coded_height);
+        gst_va_profile_name (profile), rt_format, base->width, base->height);
   }
 
-  if (base->width != display_width || base->height != display_height) {
-    base->width = display_width;
-    base->height = display_height;
+  if (GST_VIDEO_INFO_WIDTH (info) != display_width ||
+      GST_VIDEO_INFO_HEIGHT (info) != display_height) {
+    GST_VIDEO_INFO_WIDTH (info) = display_width;
+    GST_VIDEO_INFO_HEIGHT (info) = display_height;
 
     negotiation_needed = TRUE;
-    GST_INFO_OBJECT (self, "Resolution changed to %dx%d", base->width,
-        base->height);
+    GST_INFO_OBJECT (self, "Resolution changed to %dx%d",
+        GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
   }
 
-  base->need_valign = base->width < self->coded_width
-      || base->height < self->coded_height;
+  base->need_valign = GST_VIDEO_INFO_WIDTH (info) < base->width ||
+      GST_VIDEO_INFO_HEIGHT (info) < base->height;
   if (base->need_valign) {
     /* *INDENT-OFF* */
     if (base->valign.padding_left != padding_left ||
@@ -1123,8 +1122,9 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
   }
 
   base->min_buffers = self->dpb_size + 4;       /* dpb size + scratch surfaces */
-
   base->need_negotiation = negotiation_needed;
+  g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
+  base->input_state = gst_video_codec_state_ref (decoder->input_state);
 
   {
     /* FIXME: We don't have parser API for sps_range_extension, so
@@ -1196,54 +1196,6 @@ gst_va_h265_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
   return caps;
 }
 
-static gboolean
-gst_va_h265_dec_negotiate (GstVideoDecoder * decoder)
-{
-  GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
-  GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
-  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
-  GstCapsFeatures *capsfeatures = NULL;
-  GstH265Decoder *h265dec = GST_H265_DECODER (decoder);
-
-  /* Ignore downstream renegotiation request. */
-  if (!base->need_negotiation)
-    return TRUE;
-
-  base->need_negotiation = FALSE;
-
-  if (gst_va_decoder_is_open (base->decoder)
-      && !gst_va_decoder_close (base->decoder))
-    return FALSE;
-
-  if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
-    return FALSE;
-
-  if (!gst_va_decoder_set_frame_size (base->decoder, self->coded_width,
-          self->coded_height))
-    return FALSE;
-
-  if (base->output_state)
-    gst_video_codec_state_unref (base->output_state);
-
-  gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
-      &capsfeatures);
-  if (format == GST_VIDEO_FORMAT_UNKNOWN)
-    return FALSE;
-
-  base->output_state =
-      gst_video_decoder_set_output_state (decoder, format,
-      base->width, base->height, h265dec->input_state);
-
-  base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
-  if (capsfeatures)
-    gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
-
-  GST_INFO_OBJECT (self, "Negotiated caps %" GST_PTR_FORMAT,
-      base->output_state->caps);
-
-  return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
-}
-
 static void
 gst_va_h265_dec_dispose (GObject * object)
 {
@@ -1296,7 +1248,6 @@ gst_va_h265_dec_class_init (gpointer g_class, gpointer class_data)
   gobject_class->dispose = gst_va_h265_dec_dispose;
 
   decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h265_dec_getcaps);
-  decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_h265_dec_negotiate);
 
   h265decoder_class->new_sequence =
       GST_DEBUG_FUNCPTR (gst_va_h265_dec_new_sequence);
index f087d41..49f337a 100644 (file)
@@ -85,56 +85,6 @@ static const gchar *src_caps_str =
 
 static const gchar *sink_caps_str = "video/x-mpeg2";
 
-static gboolean
-gst_va_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
-{
-  GstCapsFeatures *capsfeatures = NULL;
-  GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
-  GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);
-  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
-  GstMpeg2Decoder *mpeg2dec = GST_MPEG2_DECODER (decoder);
-
-  /* Ignore downstream renegotiation request. */
-  if (!base->need_negotiation)
-    return TRUE;
-
-  base->need_negotiation = FALSE;
-
-  if (gst_va_decoder_is_open (base->decoder)
-      && !gst_va_decoder_close (base->decoder))
-    return FALSE;
-
-  if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
-    return FALSE;
-
-  if (!gst_va_decoder_set_frame_size (base->decoder, base->width, base->height))
-    return FALSE;
-
-  if (base->output_state)
-    gst_video_codec_state_unref (base->output_state);
-
-  gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
-      &capsfeatures);
-  if (format == GST_VIDEO_FORMAT_UNKNOWN)
-    return FALSE;
-
-  base->output_state =
-      gst_video_decoder_set_output_state (decoder, format,
-      base->width, base->height, mpeg2dec->input_state);
-
-  if (!self->progressive)
-    base->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
-
-  base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
-  if (capsfeatures)
-    gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
-
-  GST_INFO_OBJECT (self, "Negotiated caps %" GST_PTR_FORMAT,
-      base->output_state->caps);
-
-  return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
-}
-
 static VAProfile
 _map_profile (GstMpegVideoProfile profile)
 {
@@ -226,6 +176,7 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);
+  GstVideoInfo *info = &base->output_info;
   VAProfile profile;
   GstMpegVideoProfile mpeg_profile;
   gboolean negotiation_needed = FALSE;
@@ -259,8 +210,8 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
           rt_format, width, height)) {
     base->profile = profile;
     base->rt_format = rt_format;
-    base->width = width;
-    base->height = height;
+    GST_VIDEO_INFO_WIDTH (info) = base->width = width;
+    GST_VIDEO_INFO_HEIGHT (info) = base->height = height;
 
     negotiation_needed = TRUE;
 
@@ -271,16 +222,17 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
   progressive = seq_ext ? seq_ext->progressive : 1;
   if (self->progressive != progressive) {
     self->progressive = progressive;
-
+    GST_VIDEO_INFO_INTERLACE_MODE (info) = progressive ?
+        GST_VIDEO_INTERLACE_MODE_PROGRESSIVE : GST_VIDEO_INTERLACE_MODE_MIXED;
     negotiation_needed = TRUE;
     GST_INFO_OBJECT (self, "Interlaced mode changed to %d", !progressive);
   }
 
   base->need_valign = FALSE;
-
   base->min_buffers = 2 + 4;    /* max num pic references + scratch surfaces */
-
   base->need_negotiation = negotiation_needed;
+  g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
+  base->input_state = gst_video_codec_state_ref (decoder->input_state);
 
   return GST_FLOW_OK;
 }
@@ -594,7 +546,6 @@ gst_va_mpeg2_dec_class_init (gpointer g_class, gpointer class_data)
   GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
   GstMpeg2DecoderClass *mpeg2decoder_class = GST_MPEG2_DECODER_CLASS (g_class);
-  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (g_class);
   struct CData *cdata = class_data;
   gchar *long_name;
 
@@ -627,8 +578,6 @@ gst_va_mpeg2_dec_class_init (gpointer g_class, gpointer class_data)
 
   gobject_class->dispose = gst_va_mpeg2_dec_dispose;
 
-  decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_mpeg2_dec_negotiate);
-
   mpeg2decoder_class->new_sequence =
       GST_DEBUG_FUNCPTR (gst_va_mpeg2_dec_new_sequence);
   mpeg2decoder_class->new_picture =
index 46c9c6c..fe80575 100644 (file)
@@ -82,53 +82,6 @@ static const gchar *src_caps_str =
 
 static const gchar *sink_caps_str = "video/x-vp8";
 
-static gboolean
-gst_va_vp8_dec_negotiate (GstVideoDecoder * decoder)
-{
-  GstCapsFeatures *capsfeatures = NULL;
-  GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
-  GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);
-  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
-  GstVp8Decoder *vp8dec = GST_VP8_DECODER (decoder);
-
-  /* Ignore downstream renegotiation request. */
-  if (!base->need_negotiation)
-    return TRUE;
-
-  base->need_negotiation = FALSE;
-
-  if (gst_va_decoder_is_open (base->decoder)
-      && !gst_va_decoder_close (base->decoder))
-    return FALSE;
-
-  if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
-    return FALSE;
-
-  if (!gst_va_decoder_set_frame_size (base->decoder, base->width, base->height))
-    return FALSE;
-
-  if (base->output_state)
-    gst_video_codec_state_unref (base->output_state);
-
-  gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
-      &capsfeatures);
-  if (format == GST_VIDEO_FORMAT_UNKNOWN)
-    return FALSE;
-
-  base->output_state =
-      gst_video_decoder_set_output_state (decoder, format,
-      base->width, base->height, vp8dec->input_state);
-
-  base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
-  if (capsfeatures)
-    gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
-
-  GST_INFO_OBJECT (self, "Negotiated caps %" GST_PTR_FORMAT,
-      base->output_state->caps);
-
-  return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
-}
-
 static VAProfile
 _get_profile (GstVaVp8Dec * self, const GstVp8FrameHdr * frame_hdr)
 {
@@ -147,6 +100,7 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);
+  GstVideoInfo *info = &base->output_info;
   VAProfile profile;
   guint rt_format;
   gboolean negotiation_needed = FALSE;
@@ -169,15 +123,16 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
   if (!gst_va_decoder_config_is_equal (base->decoder, profile,
           rt_format, frame_hdr->width, frame_hdr->height)) {
     base->profile = profile;
-    base->width = frame_hdr->width;
-    base->height = frame_hdr->height;
+    GST_VIDEO_INFO_WIDTH (info) = base->width = frame_hdr->width;
+    GST_VIDEO_INFO_HEIGHT (info) = base->height = frame_hdr->height;
     base->rt_format = rt_format;
     negotiation_needed = TRUE;
   }
 
   base->min_buffers = 3 + 4;    /* max num pic references + scratch surfaces */
-
   base->need_negotiation = negotiation_needed;
+  g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
+  base->input_state = gst_video_codec_state_ref (decoder->input_state);
 
   return GST_FLOW_OK;
 }
@@ -471,7 +426,6 @@ gst_va_vp8_dec_class_init (gpointer g_class, gpointer class_data)
   GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
   GstVp8DecoderClass *vp8decoder_class = GST_VP8_DECODER_CLASS (g_class);
-  GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (g_class);
   struct CData *cdata = class_data;
   gchar *long_name;
 
@@ -504,8 +458,6 @@ gst_va_vp8_dec_class_init (gpointer g_class, gpointer class_data)
 
   gobject_class->dispose = gst_va_vp8_dec_dispose;
 
-  decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_vp8_dec_negotiate);
-
   vp8decoder_class->new_sequence =
       GST_DEBUG_FUNCPTR (gst_va_vp8_dec_new_sequence);
   vp8decoder_class->new_picture =