4 * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.net>
5 * Copyright (C) 2008,2010 Sebastian Dröge <slomo@collabora.co.uk>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Relicensed for GStreamer from GPL to LGPL with permit from Billy Biggs.
25 * See: http://bugzilla.gnome.org/show_bug.cgi?id=163578
32 #include "greedyhmacros.h"
39 #include "gstdeinterlacemethod.h"
44 #define GST_TYPE_DEINTERLACE_METHOD_GREEDY_H (gst_deinterlace_method_greedy_h_get_type ())
45 #define GST_IS_DEINTERLACE_METHOD_GREEDY_H(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H))
46 #define GST_IS_DEINTERLACE_METHOD_GREEDY_H_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H))
47 #define GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyHClass))
48 #define GST_DEINTERLACE_METHOD_GREEDY_H(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyH))
49 #define GST_DEINTERLACE_METHOD_GREEDY_H_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEINTERLACE_METHOD_GREEDY_H, GstDeinterlaceMethodGreedyHClass))
50 #define GST_DEINTERLACE_METHOD_GREEDY_H_CAST(obj) ((GstDeinterlaceMethodGreedyH*)(obj))
54 GstDeinterlaceMethod parent;
56 guint max_comb, motion_threshold, motion_sense;
57 } GstDeinterlaceMethodGreedyH;
59 typedef void (*ScanlineFunction) (GstDeinterlaceMethodGreedyH * self,
60 const guint8 * L2, const guint8 * L1, const guint8 * L3, const guint8 * L2P,
61 guint8 * Dest, gint width);
65 GstDeinterlaceMethodClass parent_class;
66 ScanlineFunction scanline_yuy2; /* This is for YVYU too */
67 ScanlineFunction scanline_uyvy;
68 ScanlineFunction scanline_ayuv;
69 ScanlineFunction scanline_planar_y;
70 ScanlineFunction scanline_planar_uv;
71 } GstDeinterlaceMethodGreedyHClass;
74 greedyh_scanline_C_ayuv (GstDeinterlaceMethodGreedyH * self, const guint8 * L1,
75 const guint8 * L2, const guint8 * L3, const guint8 * L2P, guint8 * Dest,
79 guint8 l1, l1_1, l3, l3_1;
81 guint8 avg__1[4] = { 0, };
88 guint8 l2_diff, lp2_diff;
90 guint max_comb = self->max_comb;
91 guint motion_sense = self->motion_sense;
92 guint motion_threshold = self->motion_threshold;
95 for (Pos = 0; Pos < width; Pos++) {
96 for (Comp = 0; Comp < 4; Comp++) {
100 if (Pos == width - 1) {
108 /* Average of L1 and L3 */
115 /* Average of next L1 and next L3 */
116 avg_1 = (l1_1 + l3_1) / 2;
118 /* Calculate average of one pixel forward and previous */
119 avg_s = (avg__1[Comp] + avg_1) / 2;
121 /* Calculate average of center and surrounding pixels */
122 avg_sc = (avg + avg_s) / 2;
127 /* Get best L2/L2P, i.e. least diff from above average */
131 l2_diff = ABS (l2 - avg_sc);
133 lp2_diff = ABS (lp2 - avg_sc);
135 if (l2_diff > lp2_diff)
140 /* Clip this best L2/L2P by L1/L3 and allow to differ by GreedyMaxComb */
144 if (max < 256 - max_comb)
154 out = CLAMP (best, min, max);
157 /* Do motion compensation for luma, i.e. how much
158 * the weave pixel differs */
159 mov = ABS (l2 - lp2);
160 if (mov > motion_threshold)
161 mov -= motion_threshold;
165 mov = mov * motion_sense;
169 /* Weighted sum on clipped weave pixel and average */
170 out = (out * (256 - mov) + avg_sc * mov) / 256;
185 greedyh_scanline_C_yuy2 (GstDeinterlaceMethodGreedyH * self, const guint8 * L1,
186 const guint8 * L2, const guint8 * L3, const guint8 * L2P, guint8 * Dest,
190 guint8 l1_l, l1_1_l, l3_l, l3_1_l;
191 guint8 l1_c, l1_1_c, l3_c, l3_1_c;
192 guint8 avg_l, avg_c, avg_l_1, avg_c_1;
193 guint8 avg_l__1 = 0, avg_c__1 = 0;
194 guint8 avg_s_l, avg_s_c;
195 guint8 avg_sc_l, avg_sc_c;
196 guint8 best_l, best_c;
199 guint8 l2_l, l2_c, lp2_l, lp2_c;
200 guint8 l2_l_diff, l2_c_diff, lp2_l_diff, lp2_c_diff;
201 guint8 min_l, min_c, max_l, max_c;
202 guint max_comb = self->max_comb;
203 guint motion_sense = self->motion_sense;
204 guint motion_threshold = self->motion_threshold;
207 for (Pos = 0; Pos < width; Pos++) {
213 if (Pos == width - 1) {
225 /* Average of L1 and L3 */
226 avg_l = (l1_l + l3_l) / 2;
227 avg_c = (l1_c + l3_c) / 2;
234 /* Average of next L1 and next L3 */
235 avg_l_1 = (l1_1_l + l3_1_l) / 2;
236 avg_c_1 = (l1_1_c + l3_1_c) / 2;
238 /* Calculate average of one pixel forward and previous */
239 avg_s_l = (avg_l__1 + avg_l_1) / 2;
240 avg_s_c = (avg_c__1 + avg_c_1) / 2;
242 /* Calculate average of center and surrounding pixels */
243 avg_sc_l = (avg_l + avg_s_l) / 2;
244 avg_sc_c = (avg_c + avg_s_c) / 2;
250 /* Get best L2/L2P, i.e. least diff from above average */
256 l2_l_diff = ABS (l2_l - avg_sc_l);
257 l2_c_diff = ABS (l2_c - avg_sc_c);
259 lp2_l_diff = ABS (lp2_l - avg_sc_l);
260 lp2_c_diff = ABS (lp2_c - avg_sc_c);
262 if (l2_l_diff > lp2_l_diff)
267 if (l2_c_diff > lp2_c_diff)
272 /* Clip this best L2/L2P by L1/L3 and allow to differ by GreedyMaxComb */
273 max_l = MAX (l1_l, l3_l);
274 min_l = MIN (l1_l, l3_l);
276 if (max_l < 256 - max_comb)
281 if (min_l > max_comb)
286 max_c = MAX (l1_c, l3_c);
287 min_c = MIN (l1_c, l3_c);
289 if (max_c < 256 - max_comb)
294 if (min_c > max_comb)
299 out_l = CLAMP (best_l, min_l, max_l);
300 out_c = CLAMP (best_c, min_c, max_c);
302 /* Do motion compensation for luma, i.e. how much
303 * the weave pixel differs */
304 mov_l = ABS (l2_l - lp2_l);
305 if (mov_l > motion_threshold)
306 mov_l -= motion_threshold;
310 mov_l = mov_l * motion_sense;
314 /* Weighted sum on clipped weave pixel and average */
315 out_l = (out_l * (256 - mov_l) + avg_sc_l * mov_l) / 256;
329 greedyh_scanline_C_uyvy (GstDeinterlaceMethodGreedyH * self, const guint8 * L1,
330 const guint8 * L2, const guint8 * L3, const guint8 * L2P, guint8 * Dest,
334 guint8 l1_l, l1_1_l, l3_l, l3_1_l;
335 guint8 l1_c, l1_1_c, l3_c, l3_1_c;
336 guint8 avg_l, avg_c, avg_l_1, avg_c_1;
337 guint8 avg_l__1 = 0, avg_c__1 = 0;
338 guint8 avg_s_l, avg_s_c;
339 guint8 avg_sc_l, avg_sc_c;
340 guint8 best_l, best_c;
343 guint8 l2_l, l2_c, lp2_l, lp2_c;
344 guint8 l2_l_diff, l2_c_diff, lp2_l_diff, lp2_c_diff;
345 guint8 min_l, min_c, max_l, max_c;
346 guint max_comb = self->max_comb;
347 guint motion_sense = self->motion_sense;
348 guint motion_threshold = self->motion_threshold;
351 for (Pos = 0; Pos < width; Pos++) {
357 if (Pos == width - 1) {
369 /* Average of L1 and L3 */
370 avg_l = (l1_l + l3_l) / 2;
371 avg_c = (l1_c + l3_c) / 2;
378 /* Average of next L1 and next L3 */
379 avg_l_1 = (l1_1_l + l3_1_l) / 2;
380 avg_c_1 = (l1_1_c + l3_1_c) / 2;
382 /* Calculate average of one pixel forward and previous */
383 avg_s_l = (avg_l__1 + avg_l_1) / 2;
384 avg_s_c = (avg_c__1 + avg_c_1) / 2;
386 /* Calculate average of center and surrounding pixels */
387 avg_sc_l = (avg_l + avg_s_l) / 2;
388 avg_sc_c = (avg_c + avg_s_c) / 2;
394 /* Get best L2/L2P, i.e. least diff from above average */
400 l2_l_diff = ABS (l2_l - avg_sc_l);
401 l2_c_diff = ABS (l2_c - avg_sc_c);
403 lp2_l_diff = ABS (lp2_l - avg_sc_l);
404 lp2_c_diff = ABS (lp2_c - avg_sc_c);
406 if (l2_l_diff > lp2_l_diff)
411 if (l2_c_diff > lp2_c_diff)
416 /* Clip this best L2/L2P by L1/L3 and allow to differ by GreedyMaxComb */
417 max_l = MAX (l1_l, l3_l);
418 min_l = MIN (l1_l, l3_l);
420 if (max_l < 256 - max_comb)
425 if (min_l > max_comb)
430 max_c = MAX (l1_c, l3_c);
431 min_c = MIN (l1_c, l3_c);
433 if (max_c < 256 - max_comb)
438 if (min_c > max_comb)
443 out_l = CLAMP (best_l, min_l, max_l);
444 out_c = CLAMP (best_c, min_c, max_c);
446 /* Do motion compensation for luma, i.e. how much
447 * the weave pixel differs */
448 mov_l = ABS (l2_l - lp2_l);
449 if (mov_l > motion_threshold)
450 mov_l -= motion_threshold;
454 mov_l = mov_l * motion_sense;
458 /* Weighted sum on clipped weave pixel and average */
459 out_l = (out_l * (256 - mov_l) + avg_sc_l * mov_l) / 256;
473 greedyh_scanline_C_planar_y (GstDeinterlaceMethodGreedyH * self,
474 const guint8 * L1, const guint8 * L2, const guint8 * L3, const guint8 * L2P,
475 guint8 * Dest, gint width)
478 guint8 l1, l1_1, l3, l3_1;
487 guint8 l2_diff, lp2_diff;
489 guint max_comb = self->max_comb;
490 guint motion_sense = self->motion_sense;
491 guint motion_threshold = self->motion_threshold;
493 for (Pos = 0; Pos < width; Pos++) {
497 if (Pos == width - 1) {
505 /* Average of L1 and L3 */
512 /* Average of next L1 and next L3 */
513 avg_1 = (l1_1 + l3_1) / 2;
515 /* Calculate average of one pixel forward and previous */
516 avg_s = (avg__1 + avg_1) / 2;
518 /* Calculate average of center and surrounding pixels */
519 avg_sc = (avg + avg_s) / 2;
524 /* Get best L2/L2P, i.e. least diff from above average */
528 l2_diff = ABS (l2 - avg_sc);
530 lp2_diff = ABS (lp2 - avg_sc);
532 if (l2_diff > lp2_diff)
537 /* Clip this best L2/L2P by L1/L3 and allow to differ by GreedyMaxComb */
541 if (max < 256 - max_comb)
551 out = CLAMP (best, min, max);
553 /* Do motion compensation for luma, i.e. how much
554 * the weave pixel differs */
555 mov = ABS (l2 - lp2);
556 if (mov > motion_threshold)
557 mov -= motion_threshold;
561 mov = mov * motion_sense;
565 /* Weighted sum on clipped weave pixel and average */
566 out = (out * (256 - mov) + avg_sc * mov) / 256;
579 greedyh_scanline_C_planar_uv (GstDeinterlaceMethodGreedyH * self,
580 const guint8 * L1, const guint8 * L2, const guint8 * L3, const guint8 * L2P,
581 guint8 * Dest, gint width)
584 guint8 l1, l1_1, l3, l3_1;
592 guint8 l2_diff, lp2_diff;
594 guint max_comb = self->max_comb;
596 for (Pos = 0; Pos < width; Pos++) {
600 if (Pos == width - 1) {
608 /* Average of L1 and L3 */
615 /* Average of next L1 and next L3 */
616 avg_1 = (l1_1 + l3_1) / 2;
618 /* Calculate average of one pixel forward and previous */
619 avg_s = (avg__1 + avg_1) / 2;
621 /* Calculate average of center and surrounding pixels */
622 avg_sc = (avg + avg_s) / 2;
627 /* Get best L2/L2P, i.e. least diff from above average */
631 l2_diff = ABS (l2 - avg_sc);
633 lp2_diff = ABS (lp2 - avg_sc);
635 if (l2_diff > lp2_diff)
640 /* Clip this best L2/L2P by L1/L3 and allow to differ by GreedyMaxComb */
644 if (max < 256 - max_comb)
654 out = CLAMP (best, min, max);
669 #define SIMD_TYPE MMXEXT
670 #define C_FUNCT_YUY2 greedyh_scanline_C_yuy2
671 #define C_FUNCT_UYVY greedyh_scanline_C_uyvy
672 #define C_FUNCT_PLANAR_Y greedyh_scanline_C_planar_y
673 #define C_FUNCT_PLANAR_UV greedyh_scanline_C_planar_uv
674 #define FUNCT_NAME_YUY2 greedyh_scanline_MMXEXT_yuy2
675 #define FUNCT_NAME_UYVY greedyh_scanline_MMXEXT_uyvy
676 #define FUNCT_NAME_PLANAR_Y greedyh_scanline_MMXEXT_planar_y
677 #define FUNCT_NAME_PLANAR_UV greedyh_scanline_MMXEXT_planar_uv
678 #include "greedyh.asm"
681 #undef FUNCT_NAME_YUY2
682 #undef FUNCT_NAME_UYVY
683 #undef FUNCT_NAME_PLANAR_Y
684 #undef FUNCT_NAME_PLANAR_UV
687 #define SIMD_TYPE 3DNOW
688 #define FUNCT_NAME_YUY2 greedyh_scanline_3DNOW_yuy2
689 #define FUNCT_NAME_UYVY greedyh_scanline_3DNOW_uyvy
690 #define FUNCT_NAME_PLANAR_Y greedyh_scanline_3DNOW_planar_y
691 #define FUNCT_NAME_PLANAR_UV greedyh_scanline_3DNOW_planar_uv
692 #include "greedyh.asm"
695 #undef FUNCT_NAME_YUY2
696 #undef FUNCT_NAME_UYVY
697 #undef FUNCT_NAME_PLANAR_Y
698 #undef FUNCT_NAME_PLANAR_UV
701 #define SIMD_TYPE MMX
702 #define FUNCT_NAME_YUY2 greedyh_scanline_MMX_yuy2
703 #define FUNCT_NAME_UYVY greedyh_scanline_MMX_uyvy
704 #define FUNCT_NAME_PLANAR_Y greedyh_scanline_MMX_planar_y
705 #define FUNCT_NAME_PLANAR_UV greedyh_scanline_MMX_planar_uv
706 #include "greedyh.asm"
709 #undef FUNCT_NAME_YUY2
710 #undef FUNCT_NAME_UYVY
711 #undef FUNCT_NAME_PLANAR_Y
712 #undef FUNCT_NAME_PLANAR_UV
714 #undef C_FUNCT_PLANAR_Y
715 #undef C_FUNCT_PLANAR_UV
720 deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method,
721 const GstDeinterlaceField * history, guint history_count,
724 GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method);
725 GstDeinterlaceMethodGreedyHClass *klass =
726 GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self);
729 gint RowStride = method->row_stride[0];
730 gint FieldHeight = method->frame_height / 2;
731 gint Pitch = method->row_stride[0] * 2;
732 const guint8 *L1; // ptr to Line1, of 3
733 const guint8 *L2; // ptr to Line2, the weave line
734 const guint8 *L3; // ptr to Line3
735 const guint8 *L2P; // ptr to prev Line2
736 guint8 *Dest = GST_BUFFER_DATA (outbuf);
737 ScanlineFunction scanline;
739 switch (method->format) {
740 case GST_VIDEO_FORMAT_YUY2:
741 case GST_VIDEO_FORMAT_YVYU:
742 scanline = klass->scanline_yuy2;
744 case GST_VIDEO_FORMAT_UYVY:
745 scanline = klass->scanline_uyvy;
747 case GST_VIDEO_FORMAT_AYUV:
748 scanline = klass->scanline_ayuv;
751 g_assert_not_reached ();
755 // copy first even line no matter what, and the first odd line if we're
756 // processing an EVEN field. (note diff from other deint rtns.)
758 if (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM) {
761 L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
762 if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
765 L2 = GST_BUFFER_DATA (history[history_count - 1].buf);
766 if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
770 L2P = GST_BUFFER_DATA (history[history_count - 3].buf);
771 if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
774 // copy first even line
775 memcpy (Dest, L1, RowStride);
779 L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
780 if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
783 L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Pitch;
784 if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
788 L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Pitch;
789 if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
792 // copy first even line
793 memcpy (Dest, L1, RowStride);
795 // then first odd line
796 memcpy (Dest, L1, RowStride);
800 for (Line = 0; Line < (FieldHeight - 1); ++Line) {
801 scanline (self, L1, L2, L3, L2P, Dest, RowStride);
803 memcpy (Dest, L3, RowStride);
813 memcpy (Dest, L2, RowStride);
818 deinterlace_frame_di_greedyh_planar_plane (GstDeinterlaceMethodGreedyH * self,
819 const guint8 * L1, const guint8 * L2, const guint8 * L3, const guint8 * L2P,
820 guint8 * Dest, gint RowStride, gint FieldHeight, gint Pitch, gint InfoIsOdd,
821 ScanlineFunction scanline)
825 // copy first even line no matter what, and the first odd line if we're
826 // processing an EVEN field. (note diff from other deint rtns.)
829 // copy first even line
830 memcpy (Dest, L1, RowStride);
833 // copy first even line
834 memcpy (Dest, L1, RowStride);
836 // then first odd line
837 memcpy (Dest, L1, RowStride);
841 for (Line = 0; Line < (FieldHeight - 1); ++Line) {
842 scanline (self, L1, L2, L3, L2P, Dest, RowStride);
844 memcpy (Dest, L3, RowStride);
854 memcpy (Dest, L2, RowStride);
859 deinterlace_frame_di_greedyh_planar (GstDeinterlaceMethod * method,
860 const GstDeinterlaceField * history, guint history_count,
863 GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method);
864 GstDeinterlaceMethodGreedyHClass *klass =
865 GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self);
870 const guint8 *L1; // ptr to Line1, of 3
871 const guint8 *L2; // ptr to Line2, the weave line
872 const guint8 *L3; // ptr to Line3
873 const guint8 *L2P; // ptr to prev Line2
877 ScanlineFunction scanline;
879 for (i = 0; i < 3; i++) {
880 Offset = method->offset[i];
882 InfoIsOdd = (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM);
883 RowStride = method->row_stride[i];
884 FieldHeight = method->height[i] / 2;
885 Pitch = method->row_stride[i] * 2;
888 scanline = klass->scanline_planar_y;
890 scanline = klass->scanline_planar_uv;
892 Dest = GST_BUFFER_DATA (outbuf) + Offset;
894 L1 = GST_BUFFER_DATA (history[history_count - 2].buf) + Offset;
895 if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
898 L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Offset;
899 if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
903 L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Offset;
904 if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
907 deinterlace_frame_di_greedyh_planar_plane (self, L1, L2, L3, L2P, Dest,
908 RowStride, FieldHeight, Pitch, InfoIsOdd, scanline);
912 G_DEFINE_TYPE (GstDeinterlaceMethodGreedyH, gst_deinterlace_method_greedy_h,
913 GST_TYPE_DEINTERLACE_METHOD);
919 PROP_MOTION_THRESHOLD,
924 gst_deinterlace_method_greedy_h_set_property (GObject * object, guint prop_id,
925 const GValue * value, GParamSpec * pspec)
927 GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object);
931 self->max_comb = g_value_get_uint (value);
933 case PROP_MOTION_THRESHOLD:
934 self->motion_threshold = g_value_get_uint (value);
936 case PROP_MOTION_SENSE:
937 self->motion_sense = g_value_get_uint (value);
940 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
945 gst_deinterlace_method_greedy_h_get_property (GObject * object, guint prop_id,
946 GValue * value, GParamSpec * pspec)
948 GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (object);
952 g_value_set_uint (value, self->max_comb);
954 case PROP_MOTION_THRESHOLD:
955 g_value_set_uint (value, self->motion_threshold);
957 case PROP_MOTION_SENSE:
958 g_value_set_uint (value, self->motion_sense);
961 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
966 gst_deinterlace_method_greedy_h_class_init (GstDeinterlaceMethodGreedyHClass *
969 GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
970 GObjectClass *gobject_class = (GObjectClass *) klass;
973 orc_target_get_default_flags (orc_target_get_by_name ("mmx"));
976 gobject_class->set_property = gst_deinterlace_method_greedy_h_set_property;
977 gobject_class->get_property = gst_deinterlace_method_greedy_h_get_property;
979 g_object_class_install_property (gobject_class, PROP_MAX_COMB,
980 g_param_spec_uint ("max-comb",
982 "Max Comb", 0, 255, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
985 g_object_class_install_property (gobject_class, PROP_MOTION_THRESHOLD,
986 g_param_spec_uint ("motion-threshold",
989 0, 255, 25, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
992 g_object_class_install_property (gobject_class, PROP_MOTION_SENSE,
993 g_param_spec_uint ("motion-sense",
996 0, 255, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
999 dim_class->fields_required = 4;
1000 dim_class->name = "Motion Adaptive: Advanced Detection";
1001 dim_class->nick = "greedyh";
1002 dim_class->latency = 1;
1004 dim_class->deinterlace_frame_yuy2 = deinterlace_frame_di_greedyh_packed;
1005 dim_class->deinterlace_frame_yvyu = deinterlace_frame_di_greedyh_packed;
1006 dim_class->deinterlace_frame_uyvy = deinterlace_frame_di_greedyh_packed;
1007 dim_class->deinterlace_frame_ayuv = deinterlace_frame_di_greedyh_packed;
1008 dim_class->deinterlace_frame_y444 = deinterlace_frame_di_greedyh_planar;
1009 dim_class->deinterlace_frame_i420 = deinterlace_frame_di_greedyh_planar;
1010 dim_class->deinterlace_frame_yv12 = deinterlace_frame_di_greedyh_planar;
1011 dim_class->deinterlace_frame_y42b = deinterlace_frame_di_greedyh_planar;
1012 dim_class->deinterlace_frame_y41b = deinterlace_frame_di_greedyh_planar;
1014 #ifdef BUILD_X86_ASM
1015 if (cpu_flags & ORC_TARGET_MMX_MMXEXT) {
1016 klass->scanline_yuy2 = greedyh_scanline_MMXEXT_yuy2;
1017 klass->scanline_uyvy = greedyh_scanline_MMXEXT_uyvy;
1018 } else if (cpu_flags & ORC_TARGET_MMX_3DNOW) {
1019 klass->scanline_yuy2 = greedyh_scanline_3DNOW_yuy2;
1020 klass->scanline_uyvy = greedyh_scanline_3DNOW_uyvy;
1021 } else if (cpu_flags & ORC_TARGET_MMX_MMX) {
1022 klass->scanline_yuy2 = greedyh_scanline_MMX_yuy2;
1023 klass->scanline_uyvy = greedyh_scanline_MMX_uyvy;
1025 klass->scanline_yuy2 = greedyh_scanline_C_yuy2;
1026 klass->scanline_uyvy = greedyh_scanline_C_uyvy;
1029 klass->scanline_yuy2 = greedyh_scanline_C_yuy2;
1030 klass->scanline_uyvy = greedyh_scanline_C_uyvy;
1032 /* TODO: MMX implementation of these two */
1033 klass->scanline_ayuv = greedyh_scanline_C_ayuv;
1034 klass->scanline_planar_y = greedyh_scanline_C_planar_y;
1035 klass->scanline_planar_uv = greedyh_scanline_C_planar_uv;
1039 gst_deinterlace_method_greedy_h_init (GstDeinterlaceMethodGreedyH * self)
1042 self->motion_threshold = 25;
1043 self->motion_sense = 30;