vaapidecode: improve "no free surface" conditions.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Tue, 11 Sep 2012 13:54:20 +0000 (15:54 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Tue, 11 Sep 2012 15:08:47 +0000 (17:08 +0200)
Previously, vaapidecode would wait up to one second until a free surface
is available, or it aborts decoding. Now, vaapidecode waits until the
last decoded surface was to be presented, plus one second. Besides, end
times are now expressed relative to the monotonic clock.

gst/vaapi/gstvaapidecode.c
gst/vaapi/gstvaapidecode.h

index 0b9643fa3508e4715facb53f09a2923776801314..4a4f4e74e32fa3cd81b1cd4b17f1c2c461ff8e4a 100644 (file)
@@ -189,28 +189,30 @@ gst_vaapidecode_step(GstVaapiDecode *decode)
     GstVaapiDecoderStatus status;
     GstBuffer *buffer;
     GstFlowReturn ret;
-    guint tries;
+    GstClockTime timestamp;
+    gint64 end_time;
 
     for (;;) {
-        tries = 0;
-    again:
+        end_time = decode->render_time_base;
+        if (!end_time)
+            end_time = g_get_monotonic_time();
+        end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time);
+        end_time += G_TIME_SPAN_SECOND;
+
         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 */
-                if (++tries > 100)
-                    goto error_decode_timeout;
-                GTimeVal timeout;
-                g_get_current_time(&timeout);
-                g_time_val_add(&timeout, 10000); /* 10 ms each step */
+                gboolean was_signalled;
                 g_mutex_lock(decode->decoder_mutex);
-                g_cond_timed_wait(
+                was_signalled = g_cond_wait_until(
                     decode->decoder_ready,
                     decode->decoder_mutex,
-                    &timeout
+                    end_time
                 );
                 g_mutex_unlock(decode->decoder_mutex);
-                goto again;
+                if (was_signalled)
+                    continue;
+                goto error_decode_timeout;
             }
             if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)
                 goto error_decode;
@@ -228,7 +230,12 @@ gst_vaapidecode_step(GstVaapiDecode *decode)
         if (!buffer)
             goto error_create_buffer;
 
-        GST_BUFFER_TIMESTAMP(buffer) = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy);
+        timestamp = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy);
+        if (!decode->render_time_base)
+            decode->render_time_base = g_get_monotonic_time();
+        decode->last_buffer_time = timestamp;
+
+        GST_BUFFER_TIMESTAMP(buffer) = timestamp;
         GST_BUFFER_DURATION(buffer) = GST_VAAPI_SURFACE_PROXY_DURATION(proxy);
         gst_buffer_set_caps(buffer, GST_PAD_CAPS(decode->srcpad));
 
@@ -710,6 +717,8 @@ gst_vaapidecode_init(GstVaapiDecode *decode)
     decode->decoder_caps        = NULL;
     decode->allowed_caps        = NULL;
     decode->delayed_new_seg     = NULL;
+    decode->render_time_base    = 0;
+    decode->last_buffer_time    = 0;
     decode->is_ready            = FALSE;
 
     /* Pad through which data comes in to the element */
index 408ee08c1a7eb40f0c7366336e44af709166b29f..68799df52eb1b8e2ce23a9129555b7b19b886377 100644 (file)
@@ -72,6 +72,8 @@ struct _GstVaapiDecode {
     GstCaps            *decoder_caps;
     GstCaps            *allowed_caps;
     GstEvent           *delayed_new_seg;
+    gint64              render_time_base;
+    GstClockTime        last_buffer_time;
     unsigned int        is_ready        : 1;
 };