diff --git a/gst/deinterlace/tvtime/greedy.c b/gst/deinterlace/tvtime/greedy.c index 383bc3409c..dcb495b7ee 100644 --- a/gst/deinterlace/tvtime/greedy.c +++ b/gst/deinterlace/tvtime/greedy.c @@ -49,20 +49,12 @@ GType gst_deinterlace_method_greedy_l_get_type (void); typedef struct { - GstDeinterlaceMethod parent; + GstDeinterlaceSimpleMethod parent; 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; - GreedyLScanlineFunction scanline; -} GstDeinterlaceMethodGreedyLClass; +typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodGreedyLClass; // This is a simple lightweight DeInterlace method that uses little CPU time // but gives very good results for low or intermedite motion. @@ -77,186 +69,61 @@ typedef struct // Blended Clip but this give too good results for the CPU to ignore here. static inline void -deinterlace_greedy_scanline_orc (GstDeinterlaceMethodGreedyL * self, - const guint8 * m0, const guint8 * t1, - const guint8 * b1, const guint8 * m2, guint8 * output, gint width) +deinterlace_greedy_interpolate_scanline_orc (GstDeinterlaceSimpleMethod * self, + guint8 * out, const GstDeinterlaceScanlineData * scanlines) { - deinterlace_line_greedy (output, m0, t1, b1, m2, self->max_comb, width); + /* FIXME - is this safe or just a hack? */ + guint max_comb = GST_DEINTERLACE_METHOD_GREEDY_L (self)->max_comb; + + deinterlace_line_greedy (out, scanlines->m3, scanlines->t2, scanlines->b2, + scanlines->m1, max_comb, self->parent.row_stride[0]); +} + +static inline void +deinterlace_greedy_interpolate_scanline_orc_planar_u (GstDeinterlaceSimpleMethod + * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines) +{ + /* FIXME - is this safe or just a hack? */ + guint max_comb = GST_DEINTERLACE_METHOD_GREEDY_L (self)->max_comb; + + deinterlace_line_greedy (out, scanlines->m3, scanlines->t2, scanlines->b2, + scanlines->m1, max_comb, self->parent.row_stride[1]); +} + +static inline void +deinterlace_greedy_interpolate_scanline_orc_planar_v (GstDeinterlaceSimpleMethod + * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines) +{ + /* FIXME - is this safe or just a hack? */ + guint max_comb = GST_DEINTERLACE_METHOD_GREEDY_L (self)->max_comb; + + deinterlace_line_greedy (out, scanlines->m3, scanlines->t2, scanlines->b2, + scanlines->m1, max_comb, self->parent.row_stride[2]); } static void -deinterlace_frame_di_greedy_packed (GstDeinterlaceMethod * method, - const GstDeinterlaceField * history, guint history_count, - GstBuffer * outbuf) +deinterlace_greedy_copy_scanline (GstDeinterlaceSimpleMethod * self, + guint8 * out, const GstDeinterlaceScanlineData * scanlines) { - GstDeinterlaceMethodGreedyL *self = GST_DEINTERLACE_METHOD_GREEDY_L (method); - GstDeinterlaceMethodGreedyLClass *klass = - GST_DEINTERLACE_METHOD_GREEDY_L_GET_CLASS (self); - gint InfoIsOdd = 0; - gint Line; - gint RowStride = method->row_stride[0]; - gint FieldHeight = method->frame_height / 2; - gint Pitch = method->row_stride[0] * 2; - 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 = GST_BUFFER_DATA (outbuf); - - // 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 (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM) { - InfoIsOdd = 1; - - L1 = GST_BUFFER_DATA (history[history_count - 2].buf); - if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM) - L1 += RowStride; - - L2 = GST_BUFFER_DATA (history[history_count - 1].buf); - if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM) - L2 += RowStride; - - L3 = L1 + Pitch; - L2P = GST_BUFFER_DATA (history[history_count - 3].buf); - if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM) - L2P += RowStride; - - // copy first even line - memcpy (Dest, L1, RowStride); - Dest += RowStride; - } else { - InfoIsOdd = 0; - L1 = GST_BUFFER_DATA (history[history_count - 2].buf); - if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM) - L1 += RowStride; - - L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Pitch; - if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM) - L2 += RowStride; - - L3 = L1 + Pitch; - L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Pitch; - if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM) - L2P += RowStride; - - // copy first even line - memcpy (Dest, L1, RowStride); - Dest += RowStride; - // then first odd line - memcpy (Dest, L1, RowStride); - Dest += RowStride; - } - - for (Line = 0; Line < (FieldHeight - 1); ++Line) { - klass->scanline (self, L2, L1, L3, L2P, Dest, RowStride); - Dest += RowStride; - memcpy (Dest, L3, RowStride); - Dest += RowStride; - - L1 += Pitch; - L2 += Pitch; - L3 += Pitch; - L2P += Pitch; - } - - if (InfoIsOdd) { - memcpy (Dest, L2, RowStride); - } + memcpy (out, scanlines->m2, self->parent.row_stride[0]); } 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) +deinterlace_greedy_copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self, + guint8 * out, const GstDeinterlaceScanlineData * scanlines) { - 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 - memcpy (Dest, L1, RowStride); - Dest += RowStride; - } else { - // copy first even line - memcpy (Dest, L1, RowStride); - Dest += RowStride; - // then first odd line - memcpy (Dest, L1, RowStride); - Dest += RowStride; - } - - for (Line = 0; Line < (FieldHeight - 1); ++Line) { - scanline (self, L2, L1, L3, L2P, Dest, RowStride); - Dest += RowStride; - memcpy (Dest, L3, RowStride); - Dest += RowStride; - - L1 += Pitch; - L2 += Pitch; - L3 += Pitch; - L2P += Pitch; - } - - if (InfoIsOdd) { - memcpy (Dest, L2, RowStride); - } + memcpy (out, scanlines->m2, self->parent.row_stride[1]); } static void -deinterlace_frame_di_greedy_planar (GstDeinterlaceMethod * method, - const GstDeinterlaceField * history, guint history_count, - GstBuffer * outbuf) +deinterlace_greedy_copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self, + guint8 * out, const GstDeinterlaceScanlineData * scanlines) { - 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); - } + memcpy (out, scanlines->m2, self->parent.row_stride[2]); } G_DEFINE_TYPE (GstDeinterlaceMethodGreedyL, gst_deinterlace_method_greedy_l, - GST_TYPE_DEINTERLACE_METHOD); + GST_TYPE_DEINTERLACE_SIMPLE_METHOD); enum { @@ -299,6 +166,8 @@ gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass * klass) { GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass; + GstDeinterlaceSimpleMethodClass *dism_class = + (GstDeinterlaceSimpleMethodClass *) klass; GObjectClass *gobject_class = (GObjectClass *) klass; gobject_class->set_property = gst_deinterlace_method_greedy_l_set_property; @@ -315,23 +184,48 @@ gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass * dim_class->nick = "greedyl"; dim_class->latency = 1; - dim_class->deinterlace_frame_yuy2 = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_yvyu = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_uyvy = 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; - dim_class->deinterlace_frame_ayuv = deinterlace_frame_di_greedy_planar; - dim_class->deinterlace_frame_argb = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_rgba = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_abgr = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_bgra = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_rgb = deinterlace_frame_di_greedy_packed; - dim_class->deinterlace_frame_bgr = deinterlace_frame_di_greedy_packed; + dism_class->interpolate_scanline_ayuv = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_yuy2 = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_yvyu = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_uyvy = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_argb = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_abgr = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_rgba = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_bgra = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_rgb = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_bgr = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_planar_y = + deinterlace_greedy_interpolate_scanline_orc; + dism_class->interpolate_scanline_planar_u = + deinterlace_greedy_interpolate_scanline_orc_planar_u; + dism_class->interpolate_scanline_planar_v = + deinterlace_greedy_interpolate_scanline_orc_planar_v; - klass->scanline = deinterlace_greedy_scanline_orc; + dism_class->copy_scanline_ayuv = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_yuy2 = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_yvyu = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_uyvy = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_argb = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_abgr = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_rgba = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_bgra = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_rgb = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_bgr = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_planar_y = deinterlace_greedy_copy_scanline; + dism_class->copy_scanline_planar_u = + deinterlace_greedy_copy_scanline_planar_u; + dism_class->copy_scanline_planar_v = + deinterlace_greedy_copy_scanline_planar_v; } static void