deinterlace: Fix telecine
authorRobert Swain <robert.swain@collabora.co.uk>
Tue, 25 Sep 2012 08:41:44 +0000 (10:41 +0200)
committerRobert Swain <robert.swain@collabora.co.uk>
Tue, 25 Sep 2012 15:04:54 +0000 (17:04 +0200)
This only affects behaviour in telecine cases with pattern locking
enabled. The default case should be untouched.

This works with the output from fieldanalysis at least, but the field
order looks swapped for telecine mixed buffers with the
David_slides_Schleef clip.

gst/deinterlace/gstdeinterlace.c

index ed9d96e..ea05823 100644 (file)
@@ -1710,7 +1710,8 @@ restart:
   if ((self->field_history[self->cur_field_idx].flags == PICTURE_INTERLACED_TOP
           && (self->fields == GST_DEINTERLACE_TF
               || IS_TELECINE (interlacing_mode)))
-      || self->fields == GST_DEINTERLACE_ALL) {
+      || (self->fields == GST_DEINTERLACE_ALL
+          && !IS_TELECINE (interlacing_mode))) {
     GST_DEBUG_OBJECT (self, "deinterlacing top field");
 
     /* create new buffer */
@@ -1740,8 +1741,10 @@ restart:
           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
               GST_BUFFER_DURATION (outbuf)));
     } else {
-      GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-      GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+      GST_BUFFER_TIMESTAMP (outbuf) =
+          GST_BUFFER_TIMESTAMP (field1->frame->buffer);
+      GST_BUFFER_DURATION (outbuf) =
+          GST_BUFFER_DURATION (field1->frame->buffer);
     }
 
     /* Check if we need to drop the frame because of QoS */
@@ -1779,9 +1782,12 @@ restart:
       gst_video_frame_unmap_and_free (outframe);
 
       self->cur_field_idx--;
-      if (self->cur_field_idx + 1 +
-          gst_deinterlace_method_get_latency (self->method)
-          < self->history_count || flushing) {
+      /* need to remove the field in the telecine weaving case */
+      if ((IS_TELECINE (interlacing_mode)
+              && self->method_id == GST_DEINTERLACE_WEAVE)
+          || self->cur_field_idx + 1 +
+          gst_deinterlace_method_get_latency (self->method) <
+          self->history_count || flushing) {
         gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
       }
 
@@ -1801,7 +1807,7 @@ restart:
       outbuf = NULL;
       if (ret != GST_FLOW_OK)
         return ret;
-      if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED
+      if (IS_TELECINE (interlacing_mode)
           && self->method_id == GST_DEINTERLACE_WEAVE) {
         /* pop off the second field */
         GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",
@@ -1842,7 +1848,8 @@ restart:
   if ((self->field_history[self->cur_field_idx].flags ==
           PICTURE_INTERLACED_BOTTOM && (self->fields == GST_DEINTERLACE_BF
               || IS_TELECINE (interlacing_mode)))
-      || self->fields == GST_DEINTERLACE_ALL) {
+      || (self->fields == GST_DEINTERLACE_ALL
+          && !IS_TELECINE (interlacing_mode))) {
     GST_DEBUG_OBJECT (self, "deinterlacing bottom field");
 
     /* create new buffer */
@@ -1873,8 +1880,10 @@ restart:
           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
               GST_BUFFER_DURATION (outbuf)));
     } else {
-      GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-      GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+      GST_BUFFER_TIMESTAMP (outbuf) =
+          GST_BUFFER_TIMESTAMP (field1->frame->buffer);
+      GST_BUFFER_DURATION (outbuf) =
+          GST_BUFFER_DURATION (field1->frame->buffer);
     }
 
     /* Check if we need to drop the frame because of QoS */
@@ -1898,9 +1907,12 @@ restart:
       gst_video_frame_unmap_and_free (outframe);
 
       self->cur_field_idx--;
-      if (self->cur_field_idx + 1 +
-          gst_deinterlace_method_get_latency (self->method)
-          < self->history_count) {
+      /* need to remove the field in the telecine weaving case */
+      if ((IS_TELECINE (interlacing_mode)
+              && self->method_id == GST_DEINTERLACE_WEAVE)
+          || self->cur_field_idx + 1 +
+          gst_deinterlace_method_get_latency (self->method) <
+          self->history_count) {
         gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
       }
 
@@ -1920,7 +1932,7 @@ restart:
       outbuf = NULL;
       if (ret != GST_FLOW_OK)
         return ret;
-      if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED
+      if (IS_TELECINE (interlacing_mode)
           && self->method_id == GST_DEINTERLACE_WEAVE) {
         /* pop off the second field */
         GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",