deinterlace: Add planar YUV support to all other simple methods
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Sat, 24 Apr 2010 14:28:12 +0000 (16:28 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 29 Apr 2010 17:28:24 +0000 (19:28 +0200)
gst/deinterlace/tvtime/linear.c
gst/deinterlace/tvtime/linearblend.c
gst/deinterlace/tvtime/scalerbob.c
gst/deinterlace/tvtime/weave.c
gst/deinterlace/tvtime/weavebff.c
gst/deinterlace/tvtime/weavetff.c

index e17e29e..1a18850 100644 (file)
@@ -61,6 +61,30 @@ deinterlace_scanline_linear_packed_c (GstDeinterlaceSimpleMethod * self,
       self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_planar_y_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_c (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_planar_u_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_c (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_planar_v_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_c (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[2]);
+}
+
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static void
@@ -140,6 +164,30 @@ deinterlace_scanline_linear_packed_mmx (GstDeinterlaceSimpleMethod * self,
       self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_planar_y_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmx (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_planar_u_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmx (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_planar_v_mmx (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmx (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[2]);
+}
+
 #include "sse.h"
 static void
 deinterlace_scanline_linear_mmxext (GstDeinterlaceSimpleMethod * self,
@@ -197,6 +245,30 @@ deinterlace_scanline_linear_packed_mmxext (GstDeinterlaceSimpleMethod * self,
       self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_planar_y_mmxext (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmxext (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_planar_u_mmxext (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmxext (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_planar_v_mmxext (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_mmxext (self, out, scanlines->t0, scanlines->b0,
+      self->parent.row_stride[2]);
+}
+
 #endif
 
 G_DEFINE_TYPE (GstDeinterlaceMethodLinear, gst_deinterlace_method_linear,
@@ -220,6 +292,12 @@ gst_deinterlace_method_linear_class_init (GstDeinterlaceMethodLinearClass *
 
   dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_linear_packed_c;
   dism_class->interpolate_scanline_yvyu = deinterlace_scanline_linear_packed_c;
+  dism_class->interpolate_scanline_planar_y =
+      deinterlace_scanline_linear_planar_y_c;
+  dism_class->interpolate_scanline_planar_u =
+      deinterlace_scanline_linear_planar_u_c;
+  dism_class->interpolate_scanline_planar_v =
+      deinterlace_scanline_linear_planar_v_c;
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {
@@ -227,11 +305,23 @@ gst_deinterlace_method_linear_class_init (GstDeinterlaceMethodLinearClass *
         deinterlace_scanline_linear_packed_mmxext;
     dism_class->interpolate_scanline_yvyu =
         deinterlace_scanline_linear_packed_mmxext;
+    dism_class->interpolate_scanline_planar_y =
+        deinterlace_scanline_linear_planar_y_mmxext;
+    dism_class->interpolate_scanline_planar_u =
+        deinterlace_scanline_linear_planar_u_mmxext;
+    dism_class->interpolate_scanline_planar_v =
+        deinterlace_scanline_linear_planar_v_mmxext;
   } else if (cpu_flags & OIL_IMPL_FLAG_MMX) {
     dism_class->interpolate_scanline_yuy2 =
         deinterlace_scanline_linear_packed_mmx;
     dism_class->interpolate_scanline_yvyu =
         deinterlace_scanline_linear_packed_mmx;
+    dism_class->interpolate_scanline_planar_y =
+        deinterlace_scanline_linear_planar_y_mmx;
+    dism_class->interpolate_scanline_planar_u =
+        deinterlace_scanline_linear_planar_u_mmx;
+    dism_class->interpolate_scanline_planar_v =
+        deinterlace_scanline_linear_planar_v_mmx;
   }
 #endif
 }
index 8e2a763..8c9b10e 100644 (file)
@@ -65,6 +65,30 @@ deinterlace_scanline_linear_blend_packed_c (GstDeinterlaceSimpleMethod * self,
       scanlines->m1, self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_blend_planar_y_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
+      scanlines->m1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_blend_planar_u_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
+      scanlines->m1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_blend_planar_v_c (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_c (self, out, scanlines->t0, scanlines->b0,
+      scanlines->m1, self->parent.row_stride[2]);
+}
+
 static inline void
 deinterlace_scanline_linear_blend2_c (GstDeinterlaceSimpleMethod * self,
     guint8 * out, const guint8 * m0, const guint8 * t1, const guint8 * b1,
@@ -83,6 +107,30 @@ deinterlace_scanline_linear_blend2_packed_c (GstDeinterlaceSimpleMethod * self,
       scanlines->b1, self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_blend2_planar_y_c (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
+      scanlines->b1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_blend2_planar_u_c (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
+      scanlines->b1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_blend2_planar_v_c (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_c (self, out, scanlines->m0, scanlines->t1,
+      scanlines->b1, self->parent.row_stride[2]);
+}
+
 #ifdef BUILD_X86_ASM
 #include "mmx.h"
 static inline void
@@ -145,6 +193,30 @@ deinterlace_scanline_linear_blend_packed_mmx (GstDeinterlaceSimpleMethod * self,
       scanlines->b0, scanlines->m1, self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_blend_planar_y_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_mmx (self, out, scanlines->t0,
+      scanlines->b0, scanlines->m1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_blend_planar_u_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_mmx (self, out, scanlines->t0,
+      scanlines->b0, scanlines->m1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_blend_planar_v_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend_mmx (self, out, scanlines->t0,
+      scanlines->b0, scanlines->m1, self->parent.row_stride[2]);
+}
+
 static inline void
 deinterlace_scanline_linear_blend2_mmx (GstDeinterlaceSimpleMethod * self,
     guint8 * out, const guint8 * m0, const guint8 * t1, const guint8 * b1,
@@ -206,6 +278,29 @@ deinterlace_scanline_linear_blend2_packed_mmx (GstDeinterlaceSimpleMethod *
       scanlines->t1, scanlines->b1, self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_linear_blend2_planar_y_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_mmx (self, out, scanlines->m0,
+      scanlines->t1, scanlines->b1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_linear_blend2_planar_u_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_mmx (self, out, scanlines->m0,
+      scanlines->t1, scanlines->b1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_linear_blend2_planar_v_mmx (GstDeinterlaceSimpleMethod *
+    self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  deinterlace_scanline_linear_blend2_mmx (self, out, scanlines->m0,
+      scanlines->t1, scanlines->b1, self->parent.row_stride[2]);
+}
 #endif
 
 G_DEFINE_TYPE (GstDeinterlaceMethodLinearBlend,
@@ -231,8 +326,20 @@ static void
       deinterlace_scanline_linear_blend_packed_c;
   dism_class->interpolate_scanline_yvyu =
       deinterlace_scanline_linear_blend_packed_c;
+  dism_class->interpolate_scanline_planar_y =
+      deinterlace_scanline_linear_blend_planar_y_c;
+  dism_class->interpolate_scanline_planar_u =
+      deinterlace_scanline_linear_blend_planar_u_c;
+  dism_class->interpolate_scanline_planar_v =
+      deinterlace_scanline_linear_blend_planar_v_c;
   dism_class->copy_scanline_yuy2 = deinterlace_scanline_linear_blend2_packed_c;
   dism_class->copy_scanline_yvyu = deinterlace_scanline_linear_blend2_packed_c;
+  dism_class->copy_scanline_planar_y =
+      deinterlace_scanline_linear_blend2_planar_y_c;
+  dism_class->copy_scanline_planar_u =
+      deinterlace_scanline_linear_blend2_planar_u_c;
+  dism_class->copy_scanline_planar_v =
+      deinterlace_scanline_linear_blend2_planar_v_c;
 
 #ifdef BUILD_X86_ASM
   if (cpu_flags & OIL_IMPL_FLAG_MMX) {
@@ -240,10 +347,23 @@ static void
         deinterlace_scanline_linear_blend_packed_mmx;
     dism_class->interpolate_scanline_yvyu =
         deinterlace_scanline_linear_blend_packed_mmx;
+    dism_class->interpolate_scanline_planar_y =
+        deinterlace_scanline_linear_blend_planar_y_mmx;
+    dism_class->interpolate_scanline_planar_u =
+        deinterlace_scanline_linear_blend_planar_u_mmx;
+    dism_class->interpolate_scanline_planar_v =
+        deinterlace_scanline_linear_blend_planar_v_mmx;
+
     dism_class->copy_scanline_yuy2 =
         deinterlace_scanline_linear_blend2_packed_mmx;
     dism_class->copy_scanline_yvyu =
         deinterlace_scanline_linear_blend2_packed_mmx;
+    dism_class->copy_scanline_planar_y =
+        deinterlace_scanline_linear_blend2_planar_y_mmx;
+    dism_class->copy_scanline_planar_u =
+        deinterlace_scanline_linear_blend2_planar_u_mmx;
+    dism_class->copy_scanline_planar_v =
+        deinterlace_scanline_linear_blend2_planar_v_mmx;
   }
 #endif
 }
index d08b396..94bfa92 100644 (file)
@@ -45,6 +45,27 @@ deinterlace_scanline_scaler_bob_packed (GstDeinterlaceSimpleMethod * self,
   oil_memcpy (out, scanlines->t0, self->parent.row_stride[0]);
 }
 
+static void
+deinterlace_scanline_scaler_bob_planar_y (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->t0, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_scaler_bob_planar_u (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->t0, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_scaler_bob_planar_v (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->t0, self->parent.row_stride[2]);
+}
+
 G_DEFINE_TYPE (GstDeinterlaceMethodScalerBob, gst_deinterlace_method_scaler_bob,
     GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
 
@@ -65,6 +86,12 @@ gst_deinterlace_method_scaler_bob_class_init (GstDeinterlaceMethodScalerBobClass
       deinterlace_scanline_scaler_bob_packed;
   dism_class->interpolate_scanline_yvyu =
       deinterlace_scanline_scaler_bob_packed;
+  dism_class->interpolate_scanline_planar_y =
+      deinterlace_scanline_scaler_bob_planar_y;
+  dism_class->interpolate_scanline_planar_u =
+      deinterlace_scanline_scaler_bob_planar_u;
+  dism_class->interpolate_scanline_planar_v =
+      deinterlace_scanline_scaler_bob_planar_v;
 }
 
 static void
index ce040a4..46893db 100644 (file)
@@ -52,12 +52,54 @@ deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
 }
 
 static void
+deinterlace_scanline_weave_planar_y (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_weave_planar_u (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_weave_planar_v (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[2]);
+}
+
+static void
 copy_scanline_packed (GstDeinterlaceSimpleMethod * self, guint8 * out,
     const GstDeinterlaceScanlineData * scanlines)
 {
   oil_memcpy (out, scanlines->m0, self->parent.row_stride[0]);
 }
 
+static void
+copy_scanline_planar_y (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m0, self->parent.row_stride[0]);
+}
+
+static void
+copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m0, self->parent.row_stride[1]);
+}
+
+static void
+copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m0, self->parent.row_stride[2]);
+}
+
 G_DEFINE_TYPE (GstDeinterlaceMethodWeave, gst_deinterlace_method_weave,
     GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
 
@@ -75,7 +117,17 @@ gst_deinterlace_method_weave_class_init (GstDeinterlaceMethodWeaveClass * klass)
 
   dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_yvyu = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_planar_y =
+      deinterlace_scanline_weave_planar_y;
+  dism_class->interpolate_scanline_planar_u =
+      deinterlace_scanline_weave_planar_u;
+  dism_class->interpolate_scanline_planar_v =
+      deinterlace_scanline_weave_planar_v;
+  dism_class->copy_scanline_yuy2 = copy_scanline_packed;
   dism_class->copy_scanline_yvyu = copy_scanline_packed;
+  dism_class->copy_scanline_planar_y = copy_scanline_planar_y;
+  dism_class->copy_scanline_planar_u = copy_scanline_planar_u;
+  dism_class->copy_scanline_planar_v = copy_scanline_planar_v;
 }
 
 static void
index a4ed57e..cba13d3 100644 (file)
@@ -52,6 +52,27 @@ deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
 }
 
 static void
+deinterlace_scanline_weave_planar_y (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_weave_planar_u (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_weave_planar_v (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[2]);
+}
+
+static void
 copy_scanline_packed (GstDeinterlaceSimpleMethod * self, guint8 * out,
     const GstDeinterlaceScanlineData * scanlines)
 {
@@ -63,6 +84,42 @@ copy_scanline_packed (GstDeinterlaceSimpleMethod * self, guint8 * out,
   }
 }
 
+static void
+copy_scanline_planar_y (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  /* FIXME: original code used m2 and m0 but this looks really bad */
+  if (scanlines->bottom_field) {
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
+  } else {
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
+  }
+}
+
+static void
+copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  /* FIXME: original code used m2 and m0 but this looks really bad */
+  if (scanlines->bottom_field) {
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[1]);
+  } else {
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[1]);
+  }
+}
+
+static void
+copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self, guint8 * out,
+    const GstDeinterlaceScanlineData * scanlines)
+{
+  /* FIXME: original code used m2 and m0 but this looks really bad */
+  if (scanlines->bottom_field) {
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[2]);
+  } else {
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[2]);
+  }
+}
+
 G_DEFINE_TYPE (GstDeinterlaceMethodWeaveBFF, gst_deinterlace_method_weave_bff,
     GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
 
@@ -81,8 +138,17 @@ gst_deinterlace_method_weave_bff_class_init (GstDeinterlaceMethodWeaveBFFClass *
 
   dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_yvyu = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_planar_y =
+      deinterlace_scanline_weave_planar_y;
+  dism_class->interpolate_scanline_planar_u =
+      deinterlace_scanline_weave_planar_u;
+  dism_class->interpolate_scanline_planar_v =
+      deinterlace_scanline_weave_planar_v;
   dism_class->copy_scanline_yuy2 = copy_scanline_packed;
   dism_class->copy_scanline_yvyu = copy_scanline_packed;
+  dism_class->copy_scanline_planar_y = copy_scanline_planar_y;
+  dism_class->copy_scanline_planar_u = copy_scanline_planar_u;
+  dism_class->copy_scanline_planar_v = copy_scanline_planar_v;
 }
 
 static void
index 3f60839..522d195 100644 (file)
@@ -53,6 +53,27 @@ deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
 }
 
 static void
+deinterlace_scanline_weave_planar_y (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[0]);
+}
+
+static void
+deinterlace_scanline_weave_planar_u (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[1]);
+}
+
+static void
+deinterlace_scanline_weave_planar_v (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  oil_memcpy (out, scanlines->m1, self->parent.row_stride[2]);
+}
+
+static void
 copy_scanline_packed (GstDeinterlaceSimpleMethod * self,
     guint8 * out, const GstDeinterlaceScanlineData * scanlines)
 {
@@ -64,6 +85,42 @@ copy_scanline_packed (GstDeinterlaceSimpleMethod * self,
   }
 }
 
+static void
+copy_scanline_planar_y (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  /* FIXME: original code used m2 and m0 but this looks really bad */
+  if (scanlines->bottom_field) {
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
+  } else {
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
+  }
+}
+
+static void
+copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  /* FIXME: original code used m2 and m0 but this looks really bad */
+  if (scanlines->bottom_field) {
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[1]);
+  } else {
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[1]);
+  }
+}
+
+static void
+copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self,
+    guint8 * out, const GstDeinterlaceScanlineData * scanlines)
+{
+  /* FIXME: original code used m2 and m0 but this looks really bad */
+  if (scanlines->bottom_field) {
+    oil_memcpy (out, scanlines->bb0, self->parent.row_stride[2]);
+  } else {
+    oil_memcpy (out, scanlines->bb2, self->parent.row_stride[2]);
+  }
+}
+
 G_DEFINE_TYPE (GstDeinterlaceMethodWeaveTFF, gst_deinterlace_method_weave_tff,
     GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
 
@@ -82,8 +139,17 @@ gst_deinterlace_method_weave_tff_class_init (GstDeinterlaceMethodWeaveTFFClass *
 
   dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_yvyu = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_planar_y =
+      deinterlace_scanline_weave_planar_y;
+  dism_class->interpolate_scanline_planar_u =
+      deinterlace_scanline_weave_planar_u;
+  dism_class->interpolate_scanline_planar_v =
+      deinterlace_scanline_weave_planar_v;
   dism_class->copy_scanline_yuy2 = copy_scanline_packed;
   dism_class->copy_scanline_yvyu = copy_scanline_packed;
+  dism_class->copy_scanline_planar_y = copy_scanline_planar_y;
+  dism_class->copy_scanline_planar_u = copy_scanline_planar_u;
+  dism_class->copy_scanline_planar_v = copy_scanline_planar_v;
 }
 
 static void