deinterlace: Better alternate support
authorVivia Nikolaidou <vivia@ahiru.eu>
Sat, 30 Jan 2021 13:49:23 +0000 (15:49 +0200)
committerVivia Nikolaidou <vivia@ahiru.eu>
Wed, 3 Feb 2021 14:30:15 +0000 (16:30 +0200)
Improve line offset halving based on whether this field is top or
bottom.

Also handle the buffer state the same as mixed.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/866>

gst/deinterlace/gstdeinterlace.c
gst/deinterlace/gstdeinterlacemethod.c

index 1045d9a..5b21e48 100644 (file)
@@ -1029,7 +1029,8 @@ gst_deinterlace_get_buffer_state (GstDeinterlace * self, GstVideoFrame * frame,
     interlacing_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
 
   if (state) {
-    if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED) {
+    if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED ||
+        interlacing_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
       if (GST_VIDEO_FRAME_IS_RFF (frame)) {
         *state = GST_DEINTERLACE_BUFFER_STATE_RFF;
       } else if (GST_VIDEO_FRAME_IS_ONEFIELD (frame)) {
index ab57323..105a73f 100644 (file)
@@ -333,12 +333,35 @@ get_line (LinesGetter * lg, gint field_offset, guint plane, gint line,
   frame = lg->history[idx].frame;
   g_assert (frame);
 
+  /* Now frame already refers to the field we want, the correct one is taken
+   * from the history */
   if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_TOP_FIELD) ||
       GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_BOTTOM_FIELD)) {
     /* Alternate frame containing a single field, adjust the line index */
     line /= 2;
-    if (line_offset != 1)
-      line_offset /= 2;
+    switch (line_offset) {
+      case -2:
+      case 2:
+        line_offset /= 2;
+        break;
+      case 1:
+        /* the "next" line of a top field line is the same line of a bottom
+         * field */
+        if (!GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_TFF))
+          line_offset = 0;
+        break;
+      case -1:
+        /* the "previous" line of a bottom field line is the same line of a
+         * top field */
+        if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_TFF))
+          line_offset = 0;
+        break;
+      case 0:
+        break;
+      default:
+        g_assert_not_reached ();
+        break;
+    }
   }
 
   frame_height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, plane);