From: Sebastian Dröge Date: Sat, 24 Apr 2010 13:42:07 +0000 (+0200) Subject: deinterlace: Add support for planar YUV formats in greedyl method X-Git-Tag: RELEASE-0.10.23~174 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bdb9675519e672baeca6343542aa87b9c24855dc;p=platform%2Fupstream%2Fgst-plugins-good.git deinterlace: Add support for planar YUV formats in greedyl method --- diff --git a/gst/deinterlace/tvtime/greedy.c b/gst/deinterlace/tvtime/greedy.c index 139d3b5..36deb8f 100644 --- a/gst/deinterlace/tvtime/greedy.c +++ b/gst/deinterlace/tvtime/greedy.c @@ -52,12 +52,14 @@ typedef struct guint max_comb; } GstDeinterlaceMethodGreedyL; +typedef void (*GreedyLScanlineFunction) (GstDeinterlaceMethodGreedyL * self, + const guint8 * L2, const guint8 * L1, const guint8 * L3, const guint8 * L2P, + guint8 * Dest, gint width); + typedef struct { GstDeinterlaceMethodClass parent_class; - void (*scanline) (GstDeinterlaceMethodGreedyL * self, const guint8 * L2, - const guint8 * L1, const guint8 * L3, const guint8 * L2P, guint8 * Dest, - gint width); + GreedyLScanlineFunction scanline; } GstDeinterlaceMethodGreedyLClass; // This is a simple lightweight DeInterlace method that uses little CPU time @@ -387,7 +389,7 @@ deinterlace_frame_di_greedy_packed (GstDeinterlaceMethod * method, L2P += RowStride; // copy first even line - oil_memcpy (Dest, GST_BUFFER_DATA (history[0].buf), RowStride); + oil_memcpy (Dest, L1, RowStride); Dest += RowStride; // then first odd line oil_memcpy (Dest, L1, RowStride); @@ -411,6 +413,96 @@ deinterlace_frame_di_greedy_packed (GstDeinterlaceMethod * method, } } +static void +deinterlace_frame_di_greedy_planar_plane (GstDeinterlaceMethodGreedyL * self, + const guint8 * L1, const guint8 * L2, const guint8 * L3, const guint8 * L2P, + guint8 * Dest, gint RowStride, gint FieldHeight, gint Pitch, gint InfoIsOdd, + GreedyLScanlineFunction scanline) +{ + gint Line; + + // copy first even line no matter what, and the first odd line if we're + // processing an EVEN field. (note diff from other deint rtns.) + + if (InfoIsOdd) { + // copy first even line + oil_memcpy (Dest, L1, RowStride); + Dest += RowStride; + } else { + // copy first even line + oil_memcpy (Dest, L1, RowStride); + Dest += RowStride; + // then first odd line + oil_memcpy (Dest, L1, RowStride); + Dest += RowStride; + } + + for (Line = 0; Line < (FieldHeight - 1); ++Line) { + scanline (self, L2, L1, L3, L2P, Dest, RowStride); + Dest += RowStride; + oil_memcpy (Dest, L3, RowStride); + Dest += RowStride; + + L1 += Pitch; + L2 += Pitch; + L3 += Pitch; + L2P += Pitch; + } + + if (InfoIsOdd) { + oil_memcpy (Dest, L2, RowStride); + } +} + +static void +deinterlace_frame_di_greedy_planar (GstDeinterlaceMethod * method, + const GstDeinterlaceField * history, guint history_count, + GstBuffer * outbuf) +{ + GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (method); + GstDeinterlaceMethodGreedyLClass *klass = + GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS (self); + gint InfoIsOdd; + gint RowStride; + gint FieldHeight; + gint Pitch; + const guint8 *L1; // ptr to Line1, of 3 + const guint8 *L2; // ptr to Line2, the weave line + const guint8 *L3; // ptr to Line3 + const guint8 *L2P; // ptr to prev Line2 + guint8 *Dest; + gint i; + gint Offset; + GreedyLScanlineFunction scanline = klass->scanline; + + for (i = 0; i < 3; i++) { + Offset = method->offset[i]; + + InfoIsOdd = (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM); + RowStride = method->row_stride[i]; + FieldHeight = method->height[i] / 2; + Pitch = method->row_stride[i] * 2; + + Dest = GST_BUFFER_DATA (outbuf) + Offset; + + L1 = GST_BUFFER_DATA (history[history_count - 2].buf) + Offset; + if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM) + L1 += RowStride; + + L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Offset; + if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM) + L2 += RowStride; + + L3 = L1 + Pitch; + L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Offset; + if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM) + L2P += RowStride; + + deinterlace_frame_di_greedy_planar_plane (self, L1, L2, L3, L2P, Dest, + RowStride, FieldHeight, Pitch, InfoIsOdd, scanline); + } +} + G_DEFINE_TYPE (GstDeinterlaceMethodGreedyL, gst_deinterlace_method_greedy_l, GST_TYPE_DEINTERLACE_METHOD); @@ -476,6 +568,11 @@ gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass * dim_class->deinterlace_frame_yuy2 = deinterlace_frame_di_greedy_packed; dim_class->deinterlace_frame_yvyu = deinterlace_frame_di_greedy_packed; + dim_class->deinterlace_frame_y444 = deinterlace_frame_di_greedy_planar; + dim_class->deinterlace_frame_y42b = deinterlace_frame_di_greedy_planar; + dim_class->deinterlace_frame_i420 = deinterlace_frame_di_greedy_planar; + dim_class->deinterlace_frame_yv12 = deinterlace_frame_di_greedy_planar; + dim_class->deinterlace_frame_y41b = deinterlace_frame_di_greedy_planar; #ifdef BUILD_X86_ASM if (cpu_flags & OIL_IMPL_FLAG_MMXEXT) {