Fix VC-1 decoding through the playbin2 pipeline.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Sun, 16 May 2010 21:04:32 +0000 (21:04 +0000)
committerGwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Mon, 20 Sep 2010 10:55:46 +0000 (12:55 +0200)
NEWS
gst/vaapidecode/gstvaapidecode.c
gst/vaapidecode/gstvaapidecode.h

diff --git a/NEWS b/NEWS
index 52d49e8..43e6745 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Copyright (C) 2010 Splitted-Desktop Systems
 
 Version 0.2.3 - DD.May.2010
 * Fix memory leak of encoded buffers
+* Fix VC-1 decoding through the playbin2 pipeline
 
 Version 0.2.2 - 14.May.2010
 * Fix packaging dependencies
index d20d8b5..992178d 100644 (file)
@@ -93,6 +93,14 @@ enum {
     PROP_USE_FFMPEG,
 };
 
+static void
+gst_vaapidecode_release(GstVaapiDecode *decode, GObject *dead_object)
+{
+    g_mutex_lock(decode->decoder_mutex);
+    g_cond_signal(decode->decoder_ready);
+    g_mutex_unlock(decode->decoder_mutex);
+}
+
 static GstFlowReturn
 gst_vaapidecode_step(GstVaapiDecode *decode)
 {
@@ -104,12 +112,32 @@ gst_vaapidecode_step(GstVaapiDecode *decode)
     for (;;) {
         proxy = gst_vaapi_decoder_get_surface(decode->decoder, &status);
         if (!proxy) {
+            if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) {
+                /* Wait for a VA surface to be displayed and free'd */
+                GTimeVal timeout;
+                g_get_current_time(&timeout);
+                g_time_val_add(&timeout, 100);
+                g_mutex_lock(decode->decoder_mutex);
+                g_cond_timed_wait(
+                    decode->decoder_ready,
+                    decode->decoder_mutex,
+                    &timeout
+                );
+                g_mutex_unlock(decode->decoder_mutex);
+                continue;
+            }
             if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)
                 goto error_decode;
             /* More data is needed */
             break;
         }
 
+        g_object_weak_ref(
+            G_OBJECT(proxy),
+            (GWeakNotify)gst_vaapidecode_release,
+            decode
+        );
+
         buffer = NULL;
         ret = gst_pad_alloc_buffer(
             decode->srcpad,
@@ -179,6 +207,14 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
     if (!gst_vaapidecode_ensure_display(decode))
         return FALSE;
 
+    decode->decoder_mutex = g_mutex_new();
+    if (!decode->decoder_mutex)
+        return FALSE;
+
+    decode->decoder_ready = g_cond_new();
+    if (!decode->decoder_ready)
+        return FALSE;
+
     if (decode->use_ffmpeg)
         decode->decoder = gst_vaapi_decoder_ffmpeg_new(decode->display, caps);
     if (!decode->decoder)
@@ -191,6 +227,17 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
 static void
 gst_vaapidecode_destroy(GstVaapiDecode *decode)
 {
+    if (decode->decoder_ready) {
+        gst_vaapidecode_release(decode, NULL);
+        g_cond_free(decode->decoder_ready);
+        decode->decoder_ready = NULL;
+    }
+
+    if (decode->decoder_mutex) {
+        g_mutex_free(decode->decoder_mutex);
+        decode->decoder_mutex = NULL;
+    }
+
     if (decode->decoder) {
         gst_vaapi_decoder_put_buffer(decode->decoder, NULL);
         g_object_unref(decode->decoder);
@@ -513,11 +560,13 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
 {
     GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
 
-    decode->display      = NULL;
-    decode->decoder      = NULL;
-    decode->decoder_caps = NULL;
-    decode->allowed_caps = NULL;
-    decode->use_ffmpeg   = TRUE;
+    decode->display             = NULL;
+    decode->decoder             = NULL;
+    decode->decoder_mutex       = NULL;
+    decode->decoder_ready       = NULL;
+    decode->decoder_caps        = NULL;
+    decode->allowed_caps        = NULL;
+    decode->use_ffmpeg          = TRUE;
 
     /* Pad through which data comes in to the element */
     decode->sinkpad = gst_pad_new_from_template(
index 8791bd9..6d07bc5 100644 (file)
@@ -63,6 +63,8 @@ struct _GstVaapiDecode {
     GstPad             *srcpad;
     GstVaapiDisplay    *display;
     GstVaapiDecoder    *decoder;
+    GMutex             *decoder_mutex;
+    GCond              *decoder_ready;
     GstCaps            *decoder_caps;
     GstCaps            *allowed_caps;
     unsigned int        use_ffmpeg      : 1;