
---
 gst/deinterlace/gstdeinterlace.c       |    2 +-
 gst/deinterlace/gstdeinterlacemethod.c |   67 +++++++++++++++++++++++++++++++-
 gst/deinterlace/gstdeinterlacemethod.h |    4 ++
 gst/deinterlace/tvtime/linear.c        |    1 +
 gst/deinterlace/tvtime/linearblend.c   |    2 +
 gst/deinterlace/tvtime/scalerbob.c     |    2 +
 gst/deinterlace/tvtime/vfir.c          |    3 +
 gst/deinterlace/tvtime/weave.c         |    2 +
 gst/deinterlace/tvtime/weavebff.c      |    2 +
 gst/deinterlace/tvtime/weavetff.c      |    2 +
 10 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c
index 2f7d2ea..0d1f919 100644
--- a/gst/deinterlace/gstdeinterlace.c
+++ b/gst/deinterlace/gstdeinterlace.c
@@ -161,7 +161,7 @@ gst_deinterlace_modes_get_type (void)
 }
 
 #define DEINTERLACE_CAPS \
-    GST_VIDEO_CAPS_YUV ("{ AYUV, Y444, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B }") ";" \
+    GST_VIDEO_CAPS_YUV ("{ AYUV, Y444, YUY2, YVYU, UYVY, Y42B, I420, YV12, Y41B, NV12 }") ";" \
     GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR ";" \
     GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA ";" \
     GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" \
diff --git a/gst/deinterlace/gstdeinterlacemethod.c b/gst/deinterlace/gstdeinterlacemethod.c
index 7228f01..fe7da21 100644
--- a/gst/deinterlace/gstdeinterlacemethod.c
+++ b/gst/deinterlace/gstdeinterlacemethod.c
@@ -69,6 +69,8 @@ gst_deinterlace_method_supported_impl (GstDeinterlaceMethodClass * klass,
       return (klass->deinterlace_frame_y41b != NULL);
     case GST_VIDEO_FORMAT_AYUV:
       return (klass->deinterlace_frame_ayuv != NULL);
+    case GST_VIDEO_FORMAT_NV12:
+		return (klass->deinterlace_frame_nv12 != NULL);
     case GST_VIDEO_FORMAT_ARGB:
     case GST_VIDEO_FORMAT_xRGB:
       return (klass->deinterlace_frame_argb != NULL);
@@ -152,6 +154,9 @@ gst_deinterlace_method_setup_impl (GstDeinterlaceMethod * self,
     case GST_VIDEO_FORMAT_AYUV:
       self->deinterlace_frame = klass->deinterlace_frame_ayuv;
       break;
+	case GST_VIDEO_FORMAT_NV12:
+      self->deinterlace_frame = klass->deinterlace_frame_nv12;
+      break;
     case GST_VIDEO_FORMAT_ARGB:
     case GST_VIDEO_FORMAT_xRGB:
       self->deinterlace_frame = klass->deinterlace_frame_argb;
@@ -268,6 +273,9 @@ gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass,
     case GST_VIDEO_FORMAT_AYUV:
       return (klass->interpolate_scanline_ayuv != NULL
           && klass->copy_scanline_ayuv != NULL);
+    case GST_VIDEO_FORMAT_NV12:
+      return (klass->interpolate_scanline_nv12 != NULL
+          && klass->copy_scanline_nv12 != NULL);
     case GST_VIDEO_FORMAT_I420:
     case GST_VIDEO_FORMAT_YV12:
     case GST_VIDEO_FORMAT_Y444:
@@ -279,7 +287,7 @@ gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass,
           && klass->copy_scanline_planar_u != NULL &&
           klass->interpolate_scanline_planar_v != NULL
           && klass->copy_scanline_planar_v != NULL);
-    default:
+	default:
       return FALSE;
   }
 }
@@ -546,6 +554,52 @@ gst_deinterlace_simple_method_deinterlace_frame_planar (GstDeinterlaceMethod *
 }
 
 static void
+gst_deinterlace_simple_method_deinterlace_frame_nv12 (GstDeinterlaceMethod *
+    method, const GstDeinterlaceField * history, guint history_count,
+    GstBuffer * outbuf)
+{
+  GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
+  GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
+  guint8 *out;
+  const guint8 *field0, *field1, *field2, *field3;
+  gint cur_field_idx = history_count - dm_class->fields_required;
+  guint cur_field_flags = history[cur_field_idx].flags;
+  gint i, offset;
+  
+  g_assert (self->interpolate_scanline_packed != NULL);
+  g_assert (self->copy_scanline_packed != NULL);
+
+  for (i=0;i<2;i++){
+    offset = self->parent.offset[i];
+
+    out = GST_BUFFER_DATA (outbuf) + offset;
+
+    field0 = GST_BUFFER_DATA (history[cur_field_idx].buf) + offset;
+
+    g_assert (dm_class->fields_required <= 4);
+
+    field1 = NULL;
+    if (dm_class->fields_required >= 2) {
+	  field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf) + offset;
+    }
+
+    field2 = NULL;
+    if (dm_class->fields_required >= 3) {
+	  field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf) + offset;
+    }
+
+    field3 = NULL;
+    if (dm_class->fields_required >= 4) {
+	  field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf) + offset;
+    }
+
+    gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
+	    field0, field1, field2, field3, cur_field_flags, i, self->copy_scanline_packed,
+	    self->interpolate_scanline_packed);
+  }
+}
+
+static void
 gst_deinterlace_simple_method_setup (GstDeinterlaceMethod * method,
     GstVideoFormat format, gint width, gint height)
 {
@@ -615,6 +669,10 @@ gst_deinterlace_simple_method_setup (GstDeinterlaceMethod * method,
       self->interpolate_scanline_packed = klass->interpolate_scanline_bgr;
       self->copy_scanline_packed = klass->copy_scanline_bgr;
       break;
+    case GST_VIDEO_FORMAT_NV12:
+      self->interpolate_scanline_packed = klass->interpolate_scanline_nv12;
+      self->copy_scanline_packed = klass->copy_scanline_nv12;
+      break;
     case GST_VIDEO_FORMAT_I420:
     case GST_VIDEO_FORMAT_YV12:
     case GST_VIDEO_FORMAT_Y444:
@@ -671,6 +729,8 @@ gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass
       gst_deinterlace_simple_method_deinterlace_frame_planar;
   dm_class->deinterlace_frame_y41b =
       gst_deinterlace_simple_method_deinterlace_frame_planar;
+  dm_class->deinterlace_frame_nv12 =
+      gst_deinterlace_simple_method_deinterlace_frame_nv12;
   dm_class->fields_required = 2;
   dm_class->setup = gst_deinterlace_simple_method_setup;
   dm_class->supported = gst_deinterlace_simple_method_supported;
@@ -690,6 +750,10 @@ gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass
   klass->interpolate_scanline_uyvy =
       gst_deinterlace_simple_method_interpolate_scanline_packed;
   klass->copy_scanline_uyvy =
+	  gst_deinterlace_simple_method_copy_scanline_packed;
+  klass->interpolate_scanline_nv12 =
+      gst_deinterlace_simple_method_interpolate_scanline_packed;
+  klass->copy_scanline_nv12 =
       gst_deinterlace_simple_method_copy_scanline_packed;
 
   klass->interpolate_scanline_argb =
@@ -709,7 +773,6 @@ gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass
       gst_deinterlace_simple_method_interpolate_scanline_packed;
   klass->copy_scanline_bgra =
       gst_deinterlace_simple_method_copy_scanline_packed;
-
   klass->interpolate_scanline_rgb =
       gst_deinterlace_simple_method_interpolate_scanline_packed;
   klass->copy_scanline_rgb = gst_deinterlace_simple_method_copy_scanline_packed;
diff --git a/gst/deinterlace/gstdeinterlacemethod.h b/gst/deinterlace/gstdeinterlacemethod.h
index d8d3343..f8a047e 100644
--- a/gst/deinterlace/gstdeinterlacemethod.h
+++ b/gst/deinterlace/gstdeinterlacemethod.h
@@ -95,6 +95,7 @@ struct _GstDeinterlaceMethodClass {
   GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_y42b;
   GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_y41b;
   GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_ayuv;
+  GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_nv12;
   GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_argb;
   GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_abgr;
   GstDeinterlaceMethodDeinterlaceFunction deinterlace_frame_rgba;
@@ -198,6 +199,9 @@ struct _GstDeinterlaceSimpleMethodClass {
   GstDeinterlaceSimpleMethodFunction copy_scanline_rgb;
   GstDeinterlaceSimpleMethodFunction interpolate_scanline_bgr;
   GstDeinterlaceSimpleMethodFunction copy_scanline_bgr;
+  GstDeinterlaceSimpleMethodFunction interpolate_scanline_nv12;
+  GstDeinterlaceSimpleMethodFunction copy_scanline_nv12;
+
 
   /* Planar formats */
   GstDeinterlaceSimpleMethodFunction copy_scanline_planar_y;
diff --git a/gst/deinterlace/tvtime/linear.c b/gst/deinterlace/tvtime/linear.c
index 97bb7e5..ff4c278 100644
--- a/gst/deinterlace/tvtime/linear.c
+++ b/gst/deinterlace/tvtime/linear.c
@@ -112,6 +112,7 @@ gst_deinterlace_method_linear_class_init (GstDeinterlaceMethodLinearClass *
   dism_class->interpolate_scanline_bgra = deinterlace_scanline_linear_packed_c;
   dism_class->interpolate_scanline_rgb = deinterlace_scanline_linear_packed_c;
   dism_class->interpolate_scanline_bgr = deinterlace_scanline_linear_packed_c;
+  dism_class->interpolate_scanline_nv12 = deinterlace_scanline_linear_packed_c;
   dism_class->interpolate_scanline_planar_y =
       deinterlace_scanline_linear_planar_y_c;
   dism_class->interpolate_scanline_planar_u =
diff --git a/gst/deinterlace/tvtime/linearblend.c b/gst/deinterlace/tvtime/linearblend.c
index 548ce7c..1c2ccbc 100644
--- a/gst/deinterlace/tvtime/linearblend.c
+++ b/gst/deinterlace/tvtime/linearblend.c
@@ -167,6 +167,8 @@ static void
       deinterlace_scanline_linear_blend_packed_c;
   dism_class->interpolate_scanline_bgr =
       deinterlace_scanline_linear_blend_packed_c;
+  dism_class->interpolate_scanline_nv12 =
+      deinterlace_scanline_linear_blend_packed_c;
 
   dism_class->interpolate_scanline_planar_y =
       deinterlace_scanline_linear_blend_planar_y_c;
diff --git a/gst/deinterlace/tvtime/scalerbob.c b/gst/deinterlace/tvtime/scalerbob.c
index 4612ef0..4e57e08 100644
--- a/gst/deinterlace/tvtime/scalerbob.c
+++ b/gst/deinterlace/tvtime/scalerbob.c
@@ -90,6 +90,8 @@ gst_deinterlace_method_scaler_bob_class_init (GstDeinterlaceMethodScalerBobClass
       deinterlace_scanline_scaler_bob_packed;
   dism_class->interpolate_scanline_uyvy =
       deinterlace_scanline_scaler_bob_packed;
+  dism_class->interpolate_scanline_nv12 =
+	  deinterlace_scanline_scaler_bob_packed;
   dism_class->interpolate_scanline_argb =
       deinterlace_scanline_scaler_bob_packed;
   dism_class->interpolate_scanline_abgr =
diff --git a/gst/deinterlace/tvtime/vfir.c b/gst/deinterlace/tvtime/vfir.c
index da32bf6..6b38664 100644
--- a/gst/deinterlace/tvtime/vfir.c
+++ b/gst/deinterlace/tvtime/vfir.c
@@ -259,6 +259,7 @@ gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
     dism_class->interpolate_scanline_yuy2 = deinterlace_line_packed_mmx;
     dism_class->interpolate_scanline_yvyu = deinterlace_line_packed_mmx;
     dism_class->interpolate_scanline_uyvy = deinterlace_line_packed_mmx;
+	dism_class->interpolate_scanline_nv12 = deinterlace_line_packed_mmx;
     dism_class->interpolate_scanline_argb = deinterlace_line_packed_mmx;
     dism_class->interpolate_scanline_abgr = deinterlace_line_packed_mmx;
     dism_class->interpolate_scanline_rgba = deinterlace_line_packed_mmx;
@@ -273,6 +274,7 @@ gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
     dism_class->interpolate_scanline_yvyu = deinterlace_line_packed_c;
     dism_class->interpolate_scanline_uyvy = deinterlace_line_packed_c;
     dism_class->interpolate_scanline_ayuv = deinterlace_line_packed_c;
+	dism_class->interpolate_scanline_nv12 = deinterlace_line_packed_c;
     dism_class->interpolate_scanline_argb = deinterlace_line_packed_c;
     dism_class->interpolate_scanline_abgr = deinterlace_line_packed_c;
     dism_class->interpolate_scanline_rgba = deinterlace_line_packed_c;
@@ -288,6 +290,7 @@ gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
   dism_class->interpolate_scanline_yuy2 = deinterlace_line_packed_c;
   dism_class->interpolate_scanline_yvyu = deinterlace_line_packed_c;
   dism_class->interpolate_scanline_uyvy = deinterlace_line_packed_c;
+  dism_class->interpolate_scanline_nv12 = deinterlace_line_packed_c;
   dism_class->interpolate_scanline_argb = deinterlace_line_packed_c;
   dism_class->interpolate_scanline_abgr = deinterlace_line_packed_c;
   dism_class->interpolate_scanline_rgba = deinterlace_line_packed_c;
diff --git a/gst/deinterlace/tvtime/weave.c b/gst/deinterlace/tvtime/weave.c
index 0f97142..c44b624 100644
--- a/gst/deinterlace/tvtime/weave.c
+++ b/gst/deinterlace/tvtime/weave.c
@@ -119,6 +119,7 @@ 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_uyvy = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_nv12 = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_argb = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_abgr = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_rgba = deinterlace_scanline_weave_packed;
@@ -136,6 +137,7 @@ gst_deinterlace_method_weave_class_init (GstDeinterlaceMethodWeaveClass * klass)
   dism_class->copy_scanline_yuy2 = copy_scanline_packed;
   dism_class->copy_scanline_yvyu = copy_scanline_packed;
   dism_class->copy_scanline_uyvy = copy_scanline_packed;
+  dism_class->copy_scanline_nv12 = copy_scanline_packed;
   dism_class->copy_scanline_argb = copy_scanline_packed;
   dism_class->copy_scanline_abgr = copy_scanline_packed;
   dism_class->copy_scanline_rgba = copy_scanline_packed;
diff --git a/gst/deinterlace/tvtime/weavebff.c b/gst/deinterlace/tvtime/weavebff.c
index 9c95ba8..664d2c8 100644
--- a/gst/deinterlace/tvtime/weavebff.c
+++ b/gst/deinterlace/tvtime/weavebff.c
@@ -140,6 +140,7 @@ 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_uyvy = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_nv12 = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_argb = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_abgr = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_rgba = deinterlace_scanline_weave_packed;
@@ -157,6 +158,7 @@ gst_deinterlace_method_weave_bff_class_init (GstDeinterlaceMethodWeaveBFFClass *
   dism_class->copy_scanline_yuy2 = copy_scanline_packed;
   dism_class->copy_scanline_yvyu = copy_scanline_packed;
   dism_class->copy_scanline_uyvy = copy_scanline_packed;
+  dism_class->copy_scanline_nv12 = copy_scanline_packed;
   dism_class->copy_scanline_argb = copy_scanline_packed;
   dism_class->copy_scanline_abgr = copy_scanline_packed;
   dism_class->copy_scanline_rgba = copy_scanline_packed;
diff --git a/gst/deinterlace/tvtime/weavetff.c b/gst/deinterlace/tvtime/weavetff.c
index 2df0863..cf08753 100644
--- a/gst/deinterlace/tvtime/weavetff.c
+++ b/gst/deinterlace/tvtime/weavetff.c
@@ -141,6 +141,7 @@ 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_uyvy = deinterlace_scanline_weave_packed;
+  dism_class->interpolate_scanline_nv12 = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_argb = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_abgr = deinterlace_scanline_weave_packed;
   dism_class->interpolate_scanline_rgba = deinterlace_scanline_weave_packed;
@@ -158,6 +159,7 @@ gst_deinterlace_method_weave_tff_class_init (GstDeinterlaceMethodWeaveTFFClass *
   dism_class->copy_scanline_yuy2 = copy_scanline_packed;
   dism_class->copy_scanline_yvyu = copy_scanline_packed;
   dism_class->copy_scanline_uyvy = copy_scanline_packed;
+  dism_class->copy_scanline_nv12 = copy_scanline_packed;
   dism_class->copy_scanline_argb = copy_scanline_packed;
   dism_class->copy_scanline_abgr = copy_scanline_packed;
   dism_class->copy_scanline_rgba = copy_scanline_packed;
-- 
1.6.5.1.1367.gcd48

