3 * Copyright (C) 2008-2010 Sebastian Dröge <slomo@collabora.co.uk>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
27 #include "gstdeinterlacemethod.h"
29 G_DEFINE_ABSTRACT_TYPE (GstDeinterlaceMethod, gst_deinterlace_method,
33 gst_deinterlace_method_supported (GType type, GstVideoFormat format, gint width,
36 GstDeinterlaceMethodClass *klass =
37 GST_DEINTERLACE_METHOD_CLASS (g_type_class_ref (type));
40 if (format == GST_VIDEO_FORMAT_UNKNOWN)
43 ret = klass->supported (klass, format, width, height);
44 g_type_class_unref (klass);
50 gst_deinterlace_method_supported_impl (GstDeinterlaceMethodClass * klass,
51 GstVideoFormat format, gint width, gint height)
54 case GST_VIDEO_FORMAT_YUY2:
55 return (klass->deinterlace_frame_yuy2 != NULL);
56 case GST_VIDEO_FORMAT_YVYU:
57 return (klass->deinterlace_frame_yvyu != NULL);
58 case GST_VIDEO_FORMAT_UYVY:
59 return (klass->deinterlace_frame_uyvy != NULL);
60 case GST_VIDEO_FORMAT_I420:
61 return (klass->deinterlace_frame_i420 != NULL);
62 case GST_VIDEO_FORMAT_YV12:
63 return (klass->deinterlace_frame_yv12 != NULL);
64 case GST_VIDEO_FORMAT_Y444:
65 return (klass->deinterlace_frame_y444 != NULL);
66 case GST_VIDEO_FORMAT_Y42B:
67 return (klass->deinterlace_frame_y42b != NULL);
68 case GST_VIDEO_FORMAT_Y41B:
69 return (klass->deinterlace_frame_y41b != NULL);
70 case GST_VIDEO_FORMAT_AYUV:
71 return (klass->deinterlace_frame_ayuv != NULL);
72 case GST_VIDEO_FORMAT_NV12:
73 return (klass->deinterlace_frame_nv12 != NULL);
74 case GST_VIDEO_FORMAT_NV21:
75 return (klass->deinterlace_frame_nv21 != NULL);
76 case GST_VIDEO_FORMAT_ARGB:
77 case GST_VIDEO_FORMAT_xRGB:
78 return (klass->deinterlace_frame_argb != NULL);
79 case GST_VIDEO_FORMAT_ABGR:
80 case GST_VIDEO_FORMAT_xBGR:
81 return (klass->deinterlace_frame_abgr != NULL);
82 case GST_VIDEO_FORMAT_RGBA:
83 case GST_VIDEO_FORMAT_RGBx:
84 return (klass->deinterlace_frame_rgba != NULL);
85 case GST_VIDEO_FORMAT_BGRA:
86 case GST_VIDEO_FORMAT_BGRx:
87 return (klass->deinterlace_frame_bgra != NULL);
88 case GST_VIDEO_FORMAT_RGB:
89 return (klass->deinterlace_frame_rgb != NULL);
90 case GST_VIDEO_FORMAT_BGR:
91 return (klass->deinterlace_frame_bgr != NULL);
98 gst_deinterlace_method_setup (GstDeinterlaceMethod * self,
99 GstVideoFormat format, gint width, gint height)
101 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
103 klass->setup (self, format, width, height);
107 gst_deinterlace_method_setup_impl (GstDeinterlaceMethod * self,
108 GstVideoFormat format, gint width, gint height)
111 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
113 self->format = format;
114 self->frame_width = width;
115 self->frame_height = height;
117 self->deinterlace_frame = NULL;
119 if (format == GST_VIDEO_FORMAT_UNKNOWN)
122 for (i = 0; i < 4; i++) {
123 self->width[i] = gst_video_format_get_component_width (format, i, width);
124 self->height[i] = gst_video_format_get_component_height (format, i, height);
126 gst_video_format_get_component_offset (format, i, width, height);
127 self->row_stride[i] = gst_video_format_get_row_stride (format, i, width);
128 self->pixel_stride[i] = gst_video_format_get_pixel_stride (format, i);
132 case GST_VIDEO_FORMAT_YUY2:
133 self->deinterlace_frame = klass->deinterlace_frame_yuy2;
135 case GST_VIDEO_FORMAT_YVYU:
136 self->deinterlace_frame = klass->deinterlace_frame_yvyu;
138 case GST_VIDEO_FORMAT_UYVY:
139 self->deinterlace_frame = klass->deinterlace_frame_uyvy;
141 case GST_VIDEO_FORMAT_I420:
142 self->deinterlace_frame = klass->deinterlace_frame_i420;
144 case GST_VIDEO_FORMAT_YV12:
145 self->deinterlace_frame = klass->deinterlace_frame_yv12;
147 case GST_VIDEO_FORMAT_Y444:
148 self->deinterlace_frame = klass->deinterlace_frame_y444;
150 case GST_VIDEO_FORMAT_Y42B:
151 self->deinterlace_frame = klass->deinterlace_frame_y42b;
153 case GST_VIDEO_FORMAT_Y41B:
154 self->deinterlace_frame = klass->deinterlace_frame_y41b;
156 case GST_VIDEO_FORMAT_AYUV:
157 self->deinterlace_frame = klass->deinterlace_frame_ayuv;
159 case GST_VIDEO_FORMAT_NV12:
160 self->deinterlace_frame = klass->deinterlace_frame_nv12;
162 case GST_VIDEO_FORMAT_NV21:
163 self->deinterlace_frame = klass->deinterlace_frame_nv21;
165 case GST_VIDEO_FORMAT_ARGB:
166 case GST_VIDEO_FORMAT_xRGB:
167 self->deinterlace_frame = klass->deinterlace_frame_argb;
169 case GST_VIDEO_FORMAT_ABGR:
170 case GST_VIDEO_FORMAT_xBGR:
171 self->deinterlace_frame = klass->deinterlace_frame_abgr;
173 case GST_VIDEO_FORMAT_RGBA:
174 case GST_VIDEO_FORMAT_RGBx:
175 self->deinterlace_frame = klass->deinterlace_frame_rgba;
177 case GST_VIDEO_FORMAT_BGRA:
178 case GST_VIDEO_FORMAT_BGRx:
179 self->deinterlace_frame = klass->deinterlace_frame_bgra;
181 case GST_VIDEO_FORMAT_RGB:
182 self->deinterlace_frame = klass->deinterlace_frame_rgb;
184 case GST_VIDEO_FORMAT_BGR:
185 self->deinterlace_frame = klass->deinterlace_frame_bgr;
188 self->deinterlace_frame = NULL;
194 gst_deinterlace_method_class_init (GstDeinterlaceMethodClass * klass)
196 klass->setup = gst_deinterlace_method_setup_impl;
197 klass->supported = gst_deinterlace_method_supported_impl;
201 gst_deinterlace_method_init (GstDeinterlaceMethod * self)
203 self->format = GST_VIDEO_FORMAT_UNKNOWN;
207 gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self,
208 const GstDeinterlaceField * history, guint history_count,
211 g_assert (self->deinterlace_frame != NULL);
212 self->deinterlace_frame (self, history, history_count, outbuf);
216 gst_deinterlace_method_get_fields_required (GstDeinterlaceMethod * self)
218 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
220 return klass->fields_required;
224 gst_deinterlace_method_get_latency (GstDeinterlaceMethod * self)
226 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
228 return klass->latency;
231 G_DEFINE_ABSTRACT_TYPE (GstDeinterlaceSimpleMethod,
232 gst_deinterlace_simple_method, GST_TYPE_DEINTERLACE_METHOD);
235 gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass,
236 GstVideoFormat format, gint width, gint height)
238 GstDeinterlaceSimpleMethodClass *klass =
239 GST_DEINTERLACE_SIMPLE_METHOD_CLASS (mklass);
241 if (!GST_DEINTERLACE_METHOD_CLASS
242 (gst_deinterlace_simple_method_parent_class)->supported (mklass, format,
247 case GST_VIDEO_FORMAT_ARGB:
248 case GST_VIDEO_FORMAT_xRGB:
249 return (klass->interpolate_scanline_argb != NULL
250 && klass->copy_scanline_argb != NULL);
251 case GST_VIDEO_FORMAT_RGBA:
252 case GST_VIDEO_FORMAT_RGBx:
253 return (klass->interpolate_scanline_rgba != NULL
254 && klass->copy_scanline_rgba != NULL);
255 case GST_VIDEO_FORMAT_ABGR:
256 case GST_VIDEO_FORMAT_xBGR:
257 return (klass->interpolate_scanline_abgr != NULL
258 && klass->copy_scanline_abgr != NULL);
259 case GST_VIDEO_FORMAT_BGRA:
260 case GST_VIDEO_FORMAT_BGRx:
261 return (klass->interpolate_scanline_bgra != NULL
262 && klass->copy_scanline_bgra != NULL);
263 case GST_VIDEO_FORMAT_RGB:
264 return (klass->interpolate_scanline_rgb != NULL
265 && klass->copy_scanline_rgb != NULL);
266 case GST_VIDEO_FORMAT_BGR:
267 return (klass->interpolate_scanline_bgr != NULL
268 && klass->copy_scanline_bgr != NULL);
269 case GST_VIDEO_FORMAT_YUY2:
270 return (klass->interpolate_scanline_yuy2 != NULL
271 && klass->copy_scanline_yuy2 != NULL);
272 case GST_VIDEO_FORMAT_YVYU:
273 return (klass->interpolate_scanline_yvyu != NULL
274 && klass->copy_scanline_yvyu != NULL);
275 case GST_VIDEO_FORMAT_UYVY:
276 return (klass->interpolate_scanline_uyvy != NULL
277 && klass->copy_scanline_uyvy != NULL);
278 case GST_VIDEO_FORMAT_AYUV:
279 return (klass->interpolate_scanline_ayuv != NULL
280 && klass->copy_scanline_ayuv != NULL);
281 case GST_VIDEO_FORMAT_NV12:
282 return (klass->interpolate_scanline_nv12 != NULL
283 && klass->copy_scanline_nv12 != NULL);
284 case GST_VIDEO_FORMAT_NV21:
285 return (klass->interpolate_scanline_nv21 != NULL
286 && klass->copy_scanline_nv21 != NULL);
287 case GST_VIDEO_FORMAT_I420:
288 case GST_VIDEO_FORMAT_YV12:
289 case GST_VIDEO_FORMAT_Y444:
290 case GST_VIDEO_FORMAT_Y42B:
291 case GST_VIDEO_FORMAT_Y41B:
292 return (klass->interpolate_scanline_planar_y != NULL
293 && klass->copy_scanline_planar_y != NULL &&
294 klass->interpolate_scanline_planar_u != NULL
295 && klass->copy_scanline_planar_u != NULL &&
296 klass->interpolate_scanline_planar_v != NULL
297 && klass->copy_scanline_planar_v != NULL);
304 gst_deinterlace_simple_method_interpolate_scanline_packed
305 (GstDeinterlaceSimpleMethod * self, guint8 * out,
306 const GstDeinterlaceScanlineData * scanlines)
308 memcpy (out, scanlines->m1, self->parent.row_stride[0]);
312 gst_deinterlace_simple_method_copy_scanline_packed (GstDeinterlaceSimpleMethod *
313 self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
315 memcpy (out, scanlines->m0, self->parent.row_stride[0]);
319 gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
320 method, const GstDeinterlaceField * history, guint history_count,
323 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
324 GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
325 GstDeinterlaceScanlineData scanlines;
327 const guint8 *field0, *field1, *field2, *field3;
328 gint cur_field_idx = history_count - dm_class->fields_required;
329 guint cur_field_flags = history[cur_field_idx].flags;
331 gint frame_height = self->parent.frame_height;
332 gint stride = self->parent.row_stride[0];
334 g_assert (self->interpolate_scanline_packed != NULL);
335 g_assert (self->copy_scanline_packed != NULL);
337 dest = GST_BUFFER_DATA (outbuf);
338 field0 = GST_BUFFER_DATA (history[cur_field_idx].buf);
340 g_assert (dm_class->fields_required <= 4);
342 if (dm_class->fields_required >= 2) {
343 field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf);
348 if (dm_class->fields_required >= 3) {
349 field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf);
354 if (dm_class->fields_required >= 4) {
355 field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf);
360 #define CLAMP_LOW(i) (((i)<0) ? (i+2) : (i))
361 #define CLAMP_HI(i) (((i)>=(frame_height)) ? (i-2) : (i))
362 #define LINE(x,i) ((x) + CLAMP_HI(CLAMP_LOW(i)) * (stride))
363 #define LINE2(x,i) ((x) ? LINE(x,i) : NULL)
365 for (i = 0; i < frame_height; i++) {
366 memset (&scanlines, 0, sizeof (scanlines));
367 scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
369 if (!((i & 1) ^ scanlines.bottom_field)) {
371 scanlines.tt0 = LINE2 (field0, (i - 2 >= 0) ? i - 2 : i);
372 scanlines.m0 = LINE2 (field0, i);
373 scanlines.bb0 = LINE2 (field0, (i + 2 < frame_height ? i + 2 : i));
375 scanlines.t1 = LINE2 (field1, i - 1);
376 scanlines.b1 = LINE2 (field1, i + 1);
378 scanlines.tt2 = LINE2 (field2, (i - 2 >= 0) ? i - 2 : i);
379 scanlines.m2 = LINE2 (field2, i);
380 scanlines.bb2 = LINE2 (field2, (i + 2 < frame_height ? i + 2 : i));
382 scanlines.t3 = LINE2 (field3, i - 1);
383 scanlines.b3 = LINE2 (field3, i + 1);
385 self->copy_scanline_packed (self, LINE (dest, i), &scanlines);
388 scanlines.t0 = LINE2 (field0, i - 1);
389 scanlines.b0 = LINE2 (field0, i + 1);
391 scanlines.tt1 = LINE2 (field1, (i - 2 >= 0) ? i - 2 : i);
392 scanlines.m1 = LINE2 (field1, i);
393 scanlines.bb1 = LINE2 (field1, (i + 2 < frame_height ? i + 2 : i));
395 scanlines.t2 = LINE2 (field2, i - 1);
396 scanlines.b2 = LINE2 (field2, i + 1);
398 scanlines.tt3 = LINE2 (field3, (i - 2 >= 0) ? i - 2 : i);
399 scanlines.m3 = LINE2 (field3, i);
400 scanlines.bb3 = LINE2 (field3, (i + 2 < frame_height ? i + 2 : i));
402 self->interpolate_scanline_packed (self, LINE (dest, i), &scanlines);
408 gst_deinterlace_simple_method_interpolate_scanline_planar_y
409 (GstDeinterlaceSimpleMethod * self, guint8 * out,
410 const GstDeinterlaceScanlineData * scanlines)
412 memcpy (out, scanlines->m1, self->parent.row_stride[0]);
416 gst_deinterlace_simple_method_copy_scanline_planar_y (GstDeinterlaceSimpleMethod
417 * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
419 memcpy (out, scanlines->m0, self->parent.row_stride[0]);
423 gst_deinterlace_simple_method_interpolate_scanline_planar_u
424 (GstDeinterlaceSimpleMethod * self, guint8 * out,
425 const GstDeinterlaceScanlineData * scanlines)
427 memcpy (out, scanlines->m1, self->parent.row_stride[1]);
431 gst_deinterlace_simple_method_copy_scanline_planar_u (GstDeinterlaceSimpleMethod
432 * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
434 memcpy (out, scanlines->m0, self->parent.row_stride[1]);
438 gst_deinterlace_simple_method_interpolate_scanline_planar_v
439 (GstDeinterlaceSimpleMethod * self, guint8 * out,
440 const GstDeinterlaceScanlineData * scanlines)
442 memcpy (out, scanlines->m1, self->parent.row_stride[2]);
446 gst_deinterlace_simple_method_copy_scanline_planar_v (GstDeinterlaceSimpleMethod
447 * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
449 memcpy (out, scanlines->m0, self->parent.row_stride[2]);
453 gst_deinterlace_simple_method_deinterlace_frame_planar_plane
454 (GstDeinterlaceSimpleMethod * self, guint8 * dest, const guint8 * field0,
455 const guint8 * field1, const guint8 * field2, const guint8 * field3,
456 guint cur_field_flags,
457 gint plane, GstDeinterlaceSimpleMethodFunction copy_scanline,
458 GstDeinterlaceSimpleMethodFunction interpolate_scanline)
460 GstDeinterlaceScanlineData scanlines;
462 gint frame_height = self->parent.height[plane];
463 gint stride = self->parent.row_stride[plane];
465 g_assert (interpolate_scanline != NULL);
466 g_assert (copy_scanline != NULL);
468 for (i = 0; i < frame_height; i++) {
469 memset (&scanlines, 0, sizeof (scanlines));
470 scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
472 if (!((i & 1) ^ scanlines.bottom_field)) {
474 scanlines.tt0 = LINE2 (field0, (i - 2 >= 0) ? i - 2 : i);
475 scanlines.m0 = LINE2 (field0, i);
476 scanlines.bb0 = LINE2 (field0, (i + 2 < frame_height ? i + 2 : i));
478 scanlines.t1 = LINE2 (field1, i - 1);
479 scanlines.b1 = LINE2 (field1, i + 1);
481 scanlines.tt2 = LINE2 (field2, (i - 2 >= 0) ? i - 2 : i);
482 scanlines.m2 = LINE2 (field2, i);
483 scanlines.bb2 = LINE2 (field2, (i + 2 < frame_height ? i + 2 : i));
485 scanlines.t3 = LINE2 (field3, i - 1);
486 scanlines.b3 = LINE2 (field3, i + 1);
488 copy_scanline (self, LINE (dest, i), &scanlines);
491 scanlines.t0 = LINE2 (field0, i - 1);
492 scanlines.b0 = LINE2 (field0, i + 1);
494 scanlines.tt1 = LINE2 (field1, (i - 2 >= 0) ? i - 2 : i);
495 scanlines.m1 = LINE2 (field1, i);
496 scanlines.bb1 = LINE2 (field1, (i + 2 < frame_height ? i + 2 : i));
498 scanlines.t2 = LINE2 (field2, i - 1);
499 scanlines.b2 = LINE2 (field2, i + 1);
501 scanlines.tt3 = LINE2 (field3, (i - 2 >= 0) ? i - 2 : i);
502 scanlines.m3 = LINE2 (field3, i);
503 scanlines.bb3 = LINE2 (field3, (i + 2 < frame_height ? i + 2 : i));
505 interpolate_scanline (self, LINE (dest, i), &scanlines);
511 gst_deinterlace_simple_method_deinterlace_frame_planar (GstDeinterlaceMethod *
512 method, const GstDeinterlaceField * history, guint history_count,
515 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
516 GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
518 const guint8 *field0, *field1, *field2, *field3;
519 gint cur_field_idx = history_count - dm_class->fields_required;
520 guint cur_field_flags = history[cur_field_idx].flags;
522 GstDeinterlaceSimpleMethodFunction copy_scanline;
523 GstDeinterlaceSimpleMethodFunction interpolate_scanline;
525 g_assert (self->interpolate_scanline_planar[0] != NULL);
526 g_assert (self->interpolate_scanline_planar[1] != NULL);
527 g_assert (self->interpolate_scanline_planar[2] != NULL);
528 g_assert (self->copy_scanline_planar[0] != NULL);
529 g_assert (self->copy_scanline_planar[1] != NULL);
530 g_assert (self->copy_scanline_planar[2] != NULL);
532 for (i = 0; i < 3; i++) {
533 offset = self->parent.offset[i];
534 copy_scanline = self->copy_scanline_planar[i];
535 interpolate_scanline = self->interpolate_scanline_planar[i];
537 out = GST_BUFFER_DATA (outbuf) + offset;
539 field0 = GST_BUFFER_DATA (history[cur_field_idx].buf) + offset;
541 g_assert (dm_class->fields_required <= 4);
544 if (dm_class->fields_required >= 2) {
545 field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf) + offset;
549 if (dm_class->fields_required >= 3) {
550 field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf) + offset;
554 if (dm_class->fields_required >= 4) {
555 field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf) + offset;
558 gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
559 field0, field1, field2, field3, cur_field_flags, i, copy_scanline,
560 interpolate_scanline);
565 gst_deinterlace_simple_method_deinterlace_frame_nv12 (GstDeinterlaceMethod *
566 method, const GstDeinterlaceField * history, guint history_count,
569 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
570 GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
572 const guint8 *field0, *field1, *field2, *field3;
573 gint cur_field_idx = history_count - dm_class->fields_required;
574 guint cur_field_flags = history[cur_field_idx].flags;
577 g_assert (self->interpolate_scanline_packed != NULL);
578 g_assert (self->copy_scanline_packed != NULL);
580 for (i = 0; i < 2; i++) {
581 offset = self->parent.offset[i];
583 out = GST_BUFFER_DATA (outbuf) + offset;
585 field0 = GST_BUFFER_DATA (history[cur_field_idx].buf) + offset;
587 g_assert (dm_class->fields_required <= 4);
590 if (dm_class->fields_required >= 2) {
591 field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf) + offset;
595 if (dm_class->fields_required >= 3) {
596 field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf) + offset;
600 if (dm_class->fields_required >= 4) {
601 field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf) + offset;
604 gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
605 field0, field1, field2, field3, cur_field_flags, i,
606 self->copy_scanline_packed, self->interpolate_scanline_packed);
611 gst_deinterlace_simple_method_setup (GstDeinterlaceMethod * method,
612 GstVideoFormat format, gint width, gint height)
614 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
615 GstDeinterlaceSimpleMethodClass *klass =
616 GST_DEINTERLACE_SIMPLE_METHOD_GET_CLASS (self);
618 GST_DEINTERLACE_METHOD_CLASS
619 (gst_deinterlace_simple_method_parent_class)->setup (method, format,
622 self->interpolate_scanline_packed = NULL;
623 self->copy_scanline_packed = NULL;
625 self->interpolate_scanline_planar[0] = NULL;
626 self->interpolate_scanline_planar[1] = NULL;
627 self->interpolate_scanline_planar[2] = NULL;
628 self->copy_scanline_planar[0] = NULL;
629 self->copy_scanline_planar[1] = NULL;
630 self->copy_scanline_planar[2] = NULL;
632 if (format == GST_VIDEO_FORMAT_UNKNOWN)
636 case GST_VIDEO_FORMAT_YUY2:
637 self->interpolate_scanline_packed = klass->interpolate_scanline_yuy2;
638 self->copy_scanline_packed = klass->copy_scanline_yuy2;
640 case GST_VIDEO_FORMAT_YVYU:
641 self->interpolate_scanline_packed = klass->interpolate_scanline_yvyu;
642 self->copy_scanline_packed = klass->copy_scanline_yvyu;
644 case GST_VIDEO_FORMAT_UYVY:
645 self->interpolate_scanline_packed = klass->interpolate_scanline_uyvy;
646 self->copy_scanline_packed = klass->copy_scanline_uyvy;
648 case GST_VIDEO_FORMAT_AYUV:
649 self->interpolate_scanline_packed = klass->interpolate_scanline_ayuv;
650 self->copy_scanline_packed = klass->copy_scanline_ayuv;
652 case GST_VIDEO_FORMAT_ARGB:
653 case GST_VIDEO_FORMAT_xRGB:
654 self->interpolate_scanline_packed = klass->interpolate_scanline_argb;
655 self->copy_scanline_packed = klass->copy_scanline_argb;
657 case GST_VIDEO_FORMAT_ABGR:
658 case GST_VIDEO_FORMAT_xBGR:
659 self->interpolate_scanline_packed = klass->interpolate_scanline_abgr;
660 self->copy_scanline_packed = klass->copy_scanline_abgr;
662 case GST_VIDEO_FORMAT_RGBA:
663 case GST_VIDEO_FORMAT_RGBx:
664 self->interpolate_scanline_packed = klass->interpolate_scanline_rgba;
665 self->copy_scanline_packed = klass->copy_scanline_rgba;
667 case GST_VIDEO_FORMAT_BGRA:
668 case GST_VIDEO_FORMAT_BGRx:
669 self->interpolate_scanline_packed = klass->interpolate_scanline_bgra;
670 self->copy_scanline_packed = klass->copy_scanline_bgra;
672 case GST_VIDEO_FORMAT_RGB:
673 self->interpolate_scanline_packed = klass->interpolate_scanline_rgb;
674 self->copy_scanline_packed = klass->copy_scanline_rgb;
676 case GST_VIDEO_FORMAT_BGR:
677 self->interpolate_scanline_packed = klass->interpolate_scanline_bgr;
678 self->copy_scanline_packed = klass->copy_scanline_bgr;
680 case GST_VIDEO_FORMAT_NV12:
681 self->interpolate_scanline_packed = klass->interpolate_scanline_nv12;
682 self->copy_scanline_packed = klass->copy_scanline_nv12;
684 case GST_VIDEO_FORMAT_NV21:
685 self->interpolate_scanline_packed = klass->interpolate_scanline_nv21;
686 self->copy_scanline_packed = klass->copy_scanline_nv21;
688 case GST_VIDEO_FORMAT_I420:
689 case GST_VIDEO_FORMAT_YV12:
690 case GST_VIDEO_FORMAT_Y444:
691 case GST_VIDEO_FORMAT_Y42B:
692 case GST_VIDEO_FORMAT_Y41B:
693 self->interpolate_scanline_planar[0] =
694 klass->interpolate_scanline_planar_y;
695 self->copy_scanline_planar[0] = klass->copy_scanline_planar_y;
696 self->interpolate_scanline_planar[1] =
697 klass->interpolate_scanline_planar_u;
698 self->copy_scanline_planar[1] = klass->copy_scanline_planar_u;
699 self->interpolate_scanline_planar[2] =
700 klass->interpolate_scanline_planar_v;
701 self->copy_scanline_planar[2] = klass->copy_scanline_planar_v;
709 gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass
712 GstDeinterlaceMethodClass *dm_class = (GstDeinterlaceMethodClass *) klass;
714 dm_class->deinterlace_frame_ayuv =
715 gst_deinterlace_simple_method_deinterlace_frame_packed;
716 dm_class->deinterlace_frame_yuy2 =
717 gst_deinterlace_simple_method_deinterlace_frame_packed;
718 dm_class->deinterlace_frame_yvyu =
719 gst_deinterlace_simple_method_deinterlace_frame_packed;
720 dm_class->deinterlace_frame_uyvy =
721 gst_deinterlace_simple_method_deinterlace_frame_packed;
722 dm_class->deinterlace_frame_argb =
723 gst_deinterlace_simple_method_deinterlace_frame_packed;
724 dm_class->deinterlace_frame_abgr =
725 gst_deinterlace_simple_method_deinterlace_frame_packed;
726 dm_class->deinterlace_frame_rgba =
727 gst_deinterlace_simple_method_deinterlace_frame_packed;
728 dm_class->deinterlace_frame_bgra =
729 gst_deinterlace_simple_method_deinterlace_frame_packed;
730 dm_class->deinterlace_frame_rgb =
731 gst_deinterlace_simple_method_deinterlace_frame_packed;
732 dm_class->deinterlace_frame_bgr =
733 gst_deinterlace_simple_method_deinterlace_frame_packed;
734 dm_class->deinterlace_frame_i420 =
735 gst_deinterlace_simple_method_deinterlace_frame_planar;
736 dm_class->deinterlace_frame_yv12 =
737 gst_deinterlace_simple_method_deinterlace_frame_planar;
738 dm_class->deinterlace_frame_y444 =
739 gst_deinterlace_simple_method_deinterlace_frame_planar;
740 dm_class->deinterlace_frame_y42b =
741 gst_deinterlace_simple_method_deinterlace_frame_planar;
742 dm_class->deinterlace_frame_y41b =
743 gst_deinterlace_simple_method_deinterlace_frame_planar;
744 dm_class->deinterlace_frame_nv12 =
745 gst_deinterlace_simple_method_deinterlace_frame_nv12;
746 dm_class->deinterlace_frame_nv21 =
747 gst_deinterlace_simple_method_deinterlace_frame_nv12;
748 dm_class->fields_required = 2;
749 dm_class->setup = gst_deinterlace_simple_method_setup;
750 dm_class->supported = gst_deinterlace_simple_method_supported;
752 klass->interpolate_scanline_yuy2 =
753 gst_deinterlace_simple_method_interpolate_scanline_packed;
754 klass->copy_scanline_yuy2 =
755 gst_deinterlace_simple_method_copy_scanline_packed;
756 klass->interpolate_scanline_yvyu =
757 gst_deinterlace_simple_method_interpolate_scanline_packed;
758 klass->copy_scanline_yvyu =
759 gst_deinterlace_simple_method_copy_scanline_packed;
760 klass->interpolate_scanline_ayuv =
761 gst_deinterlace_simple_method_interpolate_scanline_packed;
762 klass->copy_scanline_ayuv =
763 gst_deinterlace_simple_method_copy_scanline_packed;
764 klass->interpolate_scanline_uyvy =
765 gst_deinterlace_simple_method_interpolate_scanline_packed;
766 klass->copy_scanline_uyvy =
767 gst_deinterlace_simple_method_copy_scanline_packed;
768 klass->interpolate_scanline_nv12 =
769 gst_deinterlace_simple_method_interpolate_scanline_packed;
770 klass->copy_scanline_nv12 =
771 gst_deinterlace_simple_method_copy_scanline_packed;
773 klass->interpolate_scanline_argb =
774 gst_deinterlace_simple_method_interpolate_scanline_packed;
775 klass->copy_scanline_argb =
776 gst_deinterlace_simple_method_copy_scanline_packed;
777 klass->interpolate_scanline_abgr =
778 gst_deinterlace_simple_method_interpolate_scanline_packed;
779 klass->copy_scanline_abgr =
780 gst_deinterlace_simple_method_copy_scanline_packed;
782 klass->interpolate_scanline_rgba =
783 gst_deinterlace_simple_method_interpolate_scanline_packed;
784 klass->copy_scanline_rgba =
785 gst_deinterlace_simple_method_copy_scanline_packed;
786 klass->interpolate_scanline_bgra =
787 gst_deinterlace_simple_method_interpolate_scanline_packed;
788 klass->copy_scanline_bgra =
789 gst_deinterlace_simple_method_copy_scanline_packed;
790 klass->interpolate_scanline_rgb =
791 gst_deinterlace_simple_method_interpolate_scanline_packed;
792 klass->copy_scanline_rgb = gst_deinterlace_simple_method_copy_scanline_packed;
793 klass->interpolate_scanline_bgr =
794 gst_deinterlace_simple_method_interpolate_scanline_packed;
795 klass->copy_scanline_bgr = gst_deinterlace_simple_method_copy_scanline_packed;
797 klass->interpolate_scanline_planar_y =
798 gst_deinterlace_simple_method_interpolate_scanline_planar_y;
799 klass->copy_scanline_planar_y =
800 gst_deinterlace_simple_method_copy_scanline_planar_y;
801 klass->interpolate_scanline_planar_u =
802 gst_deinterlace_simple_method_interpolate_scanline_planar_u;
803 klass->copy_scanline_planar_u =
804 gst_deinterlace_simple_method_copy_scanline_planar_u;
805 klass->interpolate_scanline_planar_v =
806 gst_deinterlace_simple_method_interpolate_scanline_planar_v;
807 klass->copy_scanline_planar_v =
808 gst_deinterlace_simple_method_copy_scanline_planar_v;
812 gst_deinterlace_simple_method_init (GstDeinterlaceSimpleMethod * self)