vaapipostproc: reset deinterlacer state when there is a discontinuity.
authorZhao, Halley <halley.zhao@intel.com>
Thu, 12 Dec 2013 02:01:13 +0000 (10:01 +0800)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 18 Jun 2014 15:24:48 +0000 (17:24 +0200)
Reset deinterlacer state, i.e. past reference frames used for advanced
deinterlacing, when there is some discontinuity detected in the course
of processing source buffers.

This fixes support for advanced deinterlacing when a seek occurred.

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

[fixed type of pts_diff variable, fetch previous buffer PTS from the
 history buffer, reduce heuristic for detecting discontinuity]
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
gst/vaapi/gstvaapipostproc.c

index f670c55..428cba4 100644 (file)
@@ -513,6 +513,20 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
     deint_changed = deint != ds->deint;
     if (deint_changed || (ds->num_surfaces > 0 && tff != ds->tff))
         ds_reset(ds);
+
+    deint_method = postproc->deinterlace_method;
+    deint_refs = deint_method_is_advanced(deint_method);
+    if (deint_refs) {
+        GstBuffer * const prev_buf = ds_get_buffer(ds, 0);
+        GstClockTime prev_pts, pts = GST_BUFFER_TIMESTAMP(inbuf);
+        /* Reset deinterlacing state when there is a discontinuity */
+        if (prev_buf && (prev_pts = GST_BUFFER_TIMESTAMP(prev_buf)) != pts) {
+            const GstClockTimeDiff pts_diff = GST_CLOCK_DIFF(prev_pts, pts);
+            if (pts_diff < 0 || pts_diff > postproc->field_duration * 2)
+                ds_reset(ds);
+        }
+    }
+
     ds->deint = deint;
     ds->tff = tff;
 
@@ -520,8 +534,6 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
         ~GST_VAAPI_PICTURE_STRUCTURE_MASK;
 
     /* First field */
-    deint_method = postproc->deinterlace_method;
-    deint_refs = deint_method_is_advanced(deint_method);
     if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) {
         fieldbuf = create_output_buffer(postproc);
         if (!fieldbuf)