Add gst_vaapi_decoder_ffmpeg_new_from_caps() helper.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 3 May 2010 15:11:32 +0000 (15:11 +0000)
committerGwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Mon, 20 Sep 2010 10:55:42 +0000 (12:55 +0200)
gst-libs/gst/vaapi/gstvaapidecoder.c
gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h
gst-libs/gst/vaapi/gstvaapidecoder_priv.h
gst/vaapidecode/gstvaapidecode.c
gst/vaapidecode/gstvaapidecode.h

index 326cbf8..9f44130 100644 (file)
@@ -50,7 +50,9 @@ enum {
 
     PROP_DISPLAY,
     PROP_CODEC,
-    PROP_CODEC_DATA
+    PROP_CODEC_DATA,
+    PROP_WIDTH,
+    PROP_HEIGHT,
 };
 
 static inline void
@@ -285,6 +287,12 @@ gst_vaapi_decoder_set_property(
     case PROP_CODEC_DATA:
         set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value));
         break;
+    case PROP_WIDTH:
+        priv->width = g_value_get_uint(value);
+        break;
+    case PROP_HEIGHT:
+        priv->height = g_value_get_uint(value);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -311,6 +319,12 @@ gst_vaapi_decoder_get_property(
     case PROP_CODEC_DATA:
         gst_value_set_buffer(value, priv->codec_data);
         break;
+    case PROP_WIDTH:
+        g_value_set_uint(value, priv->width);
+        break;
+    case PROP_HEIGHT:
+        g_value_set_uint(value, priv->height);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -359,6 +373,24 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
                                     "Extra codec data",
                                     GST_TYPE_BUFFER,
                                     G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_WIDTH,
+         g_param_spec_uint("width",
+                           "Width",
+                           "The coded width of the picture",
+                           0, G_MAXINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_HEIGHT,
+         g_param_spec_uint("height",
+                           "Height",
+                           "The coded height of the picture",
+                           0, G_MAXINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -370,6 +402,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder)
     priv->context               = NULL;
     priv->codec                 = 0;
     priv->codec_data            = NULL;
+    priv->width                 = 0;
+    priv->height                = 0;
     priv->fps_n                 = 1000;
     priv->fps_d                 = 30;
     priv->buffers               = g_queue_new();
index 03b5533..44e99da 100644 (file)
@@ -608,3 +608,59 @@ gst_vaapi_decoder_ffmpeg_new(
                         "codec-data", codec_data,
                         NULL);
 }
+
+/**
+ * st_vaapi_decoder_ffmpeg_new_from_caps:
+ * @display: a #GstVaapiDisplay
+ * @caps: a #GstCaps holding codec information
+ *
+ * Creates a new #GstVaapiDecoder whose codec is determined from
+ * @caps. The @caps can hold extra information like codec-data and
+ * size.
+ *
+ * Return value: the newly allocated #GstVaapiDecoder object
+ */
+GstVaapiDecoder *
+gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps)
+{
+    GstStructure *structure;
+    GstVaapiProfile profile;
+    GstVaapiCodec codec;
+    const GValue *v_codec_data;
+    GstBuffer *codec_data;
+    gint width, height;
+
+    g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
+    g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
+
+    structure = gst_caps_get_structure(caps, 0);
+    if (!structure)
+        return NULL;
+
+    profile = gst_vaapi_profile_from_caps(caps);
+    if (!profile)
+        return NULL;
+
+    codec = gst_vaapi_profile_get_codec(profile);
+    if (!codec)
+        return NULL;
+
+    if (!gst_structure_get_int(structure, "width", &width))
+        width = 0;
+    if (!gst_structure_get_int(structure, "height", &height))
+        height = 0;
+
+    v_codec_data = gst_structure_get_value(structure, "codec_data");
+    if (v_codec_data)
+        codec_data = gst_value_get_buffer(v_codec_data);
+    else
+        codec_data = NULL;
+
+    return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG,
+                        "display",    display,
+                        "codec",      codec,
+                        "codec-data", codec_data,
+                        "width",      width,
+                        "height",     height,
+                        NULL);
+}
index 015ba2f..acf5bf3 100644 (file)
@@ -86,6 +86,9 @@ gst_vaapi_decoder_ffmpeg_new(
     GstBuffer       *codec_data
 );
 
+GstVaapiDecoder *
+gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps);
+
 G_END_DECLS
 
 #endif /* GST_VAAPI_DECODER_FFMPEG_H */
index 1b4a616..183c499 100644 (file)
@@ -92,6 +92,8 @@ struct _GstVaapiDecoderPrivate {
     GstVaapiContext    *context;
     GstVaapiCodec       codec;
     GstBuffer          *codec_data;
+    guint               width;
+    guint               height;
     guint               fps_n;
     guint               fps_d;
     GQueue             *buffers;
index 4449b34..ab29f42 100644 (file)
@@ -162,7 +162,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode)
 {
     GstVaapiVideoSink *sink;
     GstVaapiDisplay *display;
-    GstVaapiCodec codec;
 
     /* Look for a downstream vaapisink */
     sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode));
@@ -175,30 +174,26 @@ gst_vaapidecode_create(GstVaapiDecode *decode)
 
     decode->display = g_object_ref(display);
 
-    codec = gst_vaapi_profile_get_codec(decode->profile);
-    if (!codec)
-        return FALSE;
-
     if (decode->use_ffmpeg)
         decode->decoder =
-            gst_vaapi_decoder_ffmpeg_new(display, codec, decode->codec_data);
+            gst_vaapi_decoder_ffmpeg_new_from_caps(display, decode->decoder_caps);
     return decode->decoder != NULL;
 }
 
 static void
 gst_vaapidecode_destroy(GstVaapiDecode *decode)
 {
+    if (decode->decoder_caps) {
+        gst_caps_unref(decode->decoder_caps);
+        decode->decoder_caps = NULL;
+    }
+
     if (decode->decoder) {
         gst_vaapi_decoder_put_buffer(decode->decoder, NULL);
         g_object_unref(decode->decoder);
         decode->decoder = NULL;
     }
 
-    if (decode->codec_data) {
-        gst_buffer_unref(decode->codec_data);
-        decode->codec_data = NULL;
-    }
-
     if (decode->display) {
         g_object_unref(decode->display);
         decode->display = NULL;
@@ -331,7 +326,7 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps)
     GstPad *other_pad;
     GstCaps *other_caps = NULL;
     GstStructure *structure;
-    const GValue *v_width, *v_height, *v_framerate, *v_par, *v_codec_data;
+    const GValue *v_width, *v_height, *v_framerate, *v_par;
 
     if (pad == decode->sinkpad) {
         other_pad  = decode->srcpad;
@@ -348,14 +343,9 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps)
     v_height     = gst_structure_get_value(structure, "height");
     v_framerate  = gst_structure_get_value(structure, "framerate");
     v_par        = gst_structure_get_value(structure, "pixel-aspect-ratio");
-    v_codec_data = gst_structure_get_value(structure, "codec_data");
 
-    if (pad == decode->sinkpad) {
-        decode->profile = gst_vaapi_profile_from_caps(caps);
-        if (v_codec_data)
-            decode->codec_data =
-                gst_buffer_ref(gst_value_get_buffer(v_codec_data));
-    }
+    if (pad == decode->sinkpad)
+        decode->decoder_caps = gst_caps_ref(caps);
 
     structure = gst_caps_get_structure(other_caps, 0);
     gst_structure_set_value(structure, "width", v_width);
@@ -426,11 +416,10 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
 {
     GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
 
-    decode->display     = NULL;
-    decode->profile     = 0;
-    decode->codec_data  = NULL;
-    decode->decoder     = NULL;
-    decode->use_ffmpeg  = TRUE;
+    decode->display      = NULL;
+    decode->decoder      = NULL;
+    decode->decoder_caps = NULL;
+    decode->use_ffmpeg   = TRUE;
 
     /* Pad through which data comes in to the element */
     decode->sinkpad = gst_pad_new_from_template(
index b2b6915..068f198 100644 (file)
@@ -62,9 +62,8 @@ struct _GstVaapiDecode {
     GstPad             *sinkpad;
     GstPad             *srcpad;
     GstVaapiDisplay    *display;
-    GstVaapiProfile     profile;
-    GstBuffer          *codec_data;
     GstVaapiDecoder    *decoder;
+    GstCaps            *decoder_caps;
     unsigned int        use_ffmpeg      : 1;
 };