vaapidecode: Always keep a copy of input codec state
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>
Fri, 28 Aug 2015 20:43:47 +0000 (23:43 +0300)
committerSreerenj Balachandran <sreerenj.balachandran@intel.com>
Fri, 28 Aug 2015 20:43:47 +0000 (23:43 +0300)
Currently we are sharing the input GstVideoCodecState with
GstVaapiDecoder(gst-libs/gst/vaapi) by just doing ref and unref for
each caps change. This is troublesome in many cases, for eg: if
resoultion changes with in a singe stream. Because, when ever there
is a resolution change, GstVideoDecoder will first change the Codec_state->caps
fields with new resolution, but since we are using the same codecstate (ref)
in gstvaapidecode.c, the caps check for input caps change will always fail.

https://bugzilla.gnome.org/show_bug.cgi?id=753914

gst/vaapi/gstvaapidecode.c

index cf4b67a..e40ee94 100644 (file)
@@ -138,6 +138,37 @@ gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder,
     return;
 }
 
+static GstVideoCodecState *
+copy_video_codec_state (const GstVideoCodecState * in_state)
+{
+  GstVideoCodecState *state;
+  GstStructure *structure;
+  const GValue *codec_data;
+
+  g_return_val_if_fail (in_state != NULL, NULL);
+
+  state = g_slice_new0 (GstVideoCodecState);
+  state->ref_count = 1;
+  gst_video_info_init (&state->info);
+  if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, in_state->caps)))
+    goto fail;
+  state->caps = gst_caps_copy (in_state->caps);
+
+  structure = gst_caps_get_structure (state->caps, 0);
+
+  codec_data = gst_structure_get_value (structure, "codec_data");
+  if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER)
+    state->codec_data = GST_BUFFER (g_value_dup_boxed (codec_data));
+
+  return state;
+
+fail:
+  {
+    g_slice_free (GstVideoCodecState, state);
+    return NULL;
+  }
+}
+
 static gboolean
 gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode,
     const GstVideoCodecState * new_state)
@@ -152,8 +183,7 @@ gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode,
   }
 
   if (new_state)
-    decode->input_state = gst_video_codec_state_ref
-        ((GstVideoCodecState *) new_state);
+    decode->input_state = copy_video_codec_state (new_state);
   else
     decode->input_state = NULL;