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, GstVideoInfo * vinfo)
100 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
102 klass->setup (self, vinfo);
106 gst_deinterlace_method_setup_impl (GstDeinterlaceMethod * self,
107 GstVideoInfo * vinfo)
110 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
114 self->deinterlace_frame = NULL;
116 if (GST_VIDEO_INFO_FORMAT (self->vinfo) == GST_VIDEO_FORMAT_UNKNOWN)
119 for (i = 0; i < 4; i++) {
120 self->width[i] = GST_VIDEO_INFO_COMP_WIDTH (vinfo, i);
121 self->height[i] = GST_VIDEO_INFO_COMP_HEIGHT (vinfo, i);
122 self->offset[i] = GST_VIDEO_INFO_COMP_OFFSET (vinfo, i);
123 self->row_stride[i] = GST_VIDEO_INFO_COMP_STRIDE (vinfo, i);
124 self->pixel_stride[i] = GST_VIDEO_INFO_COMP_PSTRIDE (vinfo, i);
127 switch (GST_VIDEO_INFO_FORMAT (self->vinfo)) {
128 case GST_VIDEO_FORMAT_YUY2:
129 self->deinterlace_frame = klass->deinterlace_frame_yuy2;
131 case GST_VIDEO_FORMAT_YVYU:
132 self->deinterlace_frame = klass->deinterlace_frame_yvyu;
134 case GST_VIDEO_FORMAT_UYVY:
135 self->deinterlace_frame = klass->deinterlace_frame_uyvy;
137 case GST_VIDEO_FORMAT_I420:
138 self->deinterlace_frame = klass->deinterlace_frame_i420;
140 case GST_VIDEO_FORMAT_YV12:
141 self->deinterlace_frame = klass->deinterlace_frame_yv12;
143 case GST_VIDEO_FORMAT_Y444:
144 self->deinterlace_frame = klass->deinterlace_frame_y444;
146 case GST_VIDEO_FORMAT_Y42B:
147 self->deinterlace_frame = klass->deinterlace_frame_y42b;
149 case GST_VIDEO_FORMAT_Y41B:
150 self->deinterlace_frame = klass->deinterlace_frame_y41b;
152 case GST_VIDEO_FORMAT_AYUV:
153 self->deinterlace_frame = klass->deinterlace_frame_ayuv;
155 case GST_VIDEO_FORMAT_NV12:
156 self->deinterlace_frame = klass->deinterlace_frame_nv12;
158 case GST_VIDEO_FORMAT_NV21:
159 self->deinterlace_frame = klass->deinterlace_frame_nv21;
161 case GST_VIDEO_FORMAT_ARGB:
162 case GST_VIDEO_FORMAT_xRGB:
163 self->deinterlace_frame = klass->deinterlace_frame_argb;
165 case GST_VIDEO_FORMAT_ABGR:
166 case GST_VIDEO_FORMAT_xBGR:
167 self->deinterlace_frame = klass->deinterlace_frame_abgr;
169 case GST_VIDEO_FORMAT_RGBA:
170 case GST_VIDEO_FORMAT_RGBx:
171 self->deinterlace_frame = klass->deinterlace_frame_rgba;
173 case GST_VIDEO_FORMAT_BGRA:
174 case GST_VIDEO_FORMAT_BGRx:
175 self->deinterlace_frame = klass->deinterlace_frame_bgra;
177 case GST_VIDEO_FORMAT_RGB:
178 self->deinterlace_frame = klass->deinterlace_frame_rgb;
180 case GST_VIDEO_FORMAT_BGR:
181 self->deinterlace_frame = klass->deinterlace_frame_bgr;
184 self->deinterlace_frame = NULL;
190 gst_deinterlace_method_class_init (GstDeinterlaceMethodClass * klass)
192 klass->setup = gst_deinterlace_method_setup_impl;
193 klass->supported = gst_deinterlace_method_supported_impl;
197 gst_deinterlace_method_init (GstDeinterlaceMethod * self)
203 gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self,
204 const GstDeinterlaceField * history, guint history_count,
205 GstVideoFrame * outframe, int cur_field_idx)
207 g_assert (self->deinterlace_frame != NULL);
208 self->deinterlace_frame (self, history, history_count, outframe,
213 gst_deinterlace_method_get_fields_required (GstDeinterlaceMethod * self)
215 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
217 return klass->fields_required;
221 gst_deinterlace_method_get_latency (GstDeinterlaceMethod * self)
223 GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
225 return klass->latency;
228 G_DEFINE_ABSTRACT_TYPE (GstDeinterlaceSimpleMethod,
229 gst_deinterlace_simple_method, GST_TYPE_DEINTERLACE_METHOD);
232 gst_deinterlace_simple_method_supported (GstDeinterlaceMethodClass * mklass,
233 GstVideoFormat format, gint width, gint height)
235 GstDeinterlaceSimpleMethodClass *klass =
236 GST_DEINTERLACE_SIMPLE_METHOD_CLASS (mklass);
238 if (!GST_DEINTERLACE_METHOD_CLASS
239 (gst_deinterlace_simple_method_parent_class)->supported (mklass, format,
244 case GST_VIDEO_FORMAT_ARGB:
245 case GST_VIDEO_FORMAT_xRGB:
246 return (klass->interpolate_scanline_argb != NULL
247 && klass->copy_scanline_argb != NULL);
248 case GST_VIDEO_FORMAT_RGBA:
249 case GST_VIDEO_FORMAT_RGBx:
250 return (klass->interpolate_scanline_rgba != NULL
251 && klass->copy_scanline_rgba != NULL);
252 case GST_VIDEO_FORMAT_ABGR:
253 case GST_VIDEO_FORMAT_xBGR:
254 return (klass->interpolate_scanline_abgr != NULL
255 && klass->copy_scanline_abgr != NULL);
256 case GST_VIDEO_FORMAT_BGRA:
257 case GST_VIDEO_FORMAT_BGRx:
258 return (klass->interpolate_scanline_bgra != NULL
259 && klass->copy_scanline_bgra != NULL);
260 case GST_VIDEO_FORMAT_RGB:
261 return (klass->interpolate_scanline_rgb != NULL
262 && klass->copy_scanline_rgb != NULL);
263 case GST_VIDEO_FORMAT_BGR:
264 return (klass->interpolate_scanline_bgr != NULL
265 && klass->copy_scanline_bgr != NULL);
266 case GST_VIDEO_FORMAT_YUY2:
267 return (klass->interpolate_scanline_yuy2 != NULL
268 && klass->copy_scanline_yuy2 != NULL);
269 case GST_VIDEO_FORMAT_YVYU:
270 return (klass->interpolate_scanline_yvyu != NULL
271 && klass->copy_scanline_yvyu != NULL);
272 case GST_VIDEO_FORMAT_UYVY:
273 return (klass->interpolate_scanline_uyvy != NULL
274 && klass->copy_scanline_uyvy != NULL);
275 case GST_VIDEO_FORMAT_AYUV:
276 return (klass->interpolate_scanline_ayuv != NULL
277 && klass->copy_scanline_ayuv != NULL);
278 case GST_VIDEO_FORMAT_NV12:
279 return (klass->interpolate_scanline_nv12 != NULL
280 && klass->copy_scanline_nv12 != NULL);
281 case GST_VIDEO_FORMAT_NV21:
282 return (klass->interpolate_scanline_nv21 != NULL
283 && klass->copy_scanline_nv21 != NULL);
284 case GST_VIDEO_FORMAT_I420:
285 case GST_VIDEO_FORMAT_YV12:
286 case GST_VIDEO_FORMAT_Y444:
287 case GST_VIDEO_FORMAT_Y42B:
288 case GST_VIDEO_FORMAT_Y41B:
289 return (klass->interpolate_scanline_planar_y != NULL
290 && klass->copy_scanline_planar_y != NULL &&
291 klass->interpolate_scanline_planar_u != NULL
292 && klass->copy_scanline_planar_u != NULL &&
293 klass->interpolate_scanline_planar_v != NULL
294 && klass->copy_scanline_planar_v != NULL);
301 gst_deinterlace_simple_method_interpolate_scanline_packed
302 (GstDeinterlaceSimpleMethod * self, guint8 * out,
303 const GstDeinterlaceScanlineData * scanlines)
305 memcpy (out, scanlines->m1, self->parent.row_stride[0]);
309 gst_deinterlace_simple_method_copy_scanline_packed (GstDeinterlaceSimpleMethod *
310 self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
312 memcpy (out, scanlines->m0, self->parent.row_stride[0]);
316 gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
317 method, const GstDeinterlaceField * history, guint history_count,
318 GstVideoFrame * outframe, gint cur_field_idx)
320 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
321 GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
322 GstDeinterlaceScanlineData scanlines;
324 const guint8 *field0, *field1, *field2, *fieldp;
325 guint cur_field_flags = history[cur_field_idx].flags;
327 gint frame_height = GST_VIDEO_INFO_HEIGHT (self->parent.vinfo);
328 gint stride = self->parent.row_stride[0];
330 g_assert (self->interpolate_scanline_packed != NULL);
331 g_assert (self->copy_scanline_packed != NULL);
333 if (cur_field_idx > 0) {
334 fieldp = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx - 1].frame, 0);
339 dest = GST_VIDEO_FRAME_COMP_DATA (outframe, 0);
341 field0 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx].frame, 0);
343 g_assert (dm_class->fields_required <= 4);
345 if (cur_field_idx + 1 < history_count) {
346 field1 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx + 1].frame, 0);
351 if (cur_field_idx + 2 < history_count) {
352 field2 = GST_VIDEO_FRAME_COMP_DATA (history[cur_field_idx + 2].frame, 0);
357 #define CLAMP_LOW(i) (((i)<0) ? (i+2) : (i))
358 #define CLAMP_HI(i) (((i)>=(frame_height)) ? (i-2) : (i))
359 #define LINE(x,i) ((x) + CLAMP_HI(CLAMP_LOW(i)) * (stride))
360 #define LINE2(x,i) ((x) ? LINE(x,i) : NULL)
362 for (i = 0; i < frame_height; i++) {
363 memset (&scanlines, 0, sizeof (scanlines));
364 scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
366 if (!((i & 1) ^ scanlines.bottom_field)) {
368 scanlines.tp = LINE2 (fieldp, i - 1);
369 scanlines.bp = LINE2 (fieldp, i + 1);
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 self->copy_scanline_packed (self, LINE (dest, i), &scanlines);
385 scanlines.ttp = LINE2 (fieldp, (i - 2 >= 0) ? i - 2 : i);
386 scanlines.mp = LINE2 (fieldp, i);
387 scanlines.bbp = LINE2 (fieldp, (i + 2 < frame_height ? i + 2 : i));
389 scanlines.t0 = LINE2 (field0, i - 1);
390 scanlines.b0 = LINE2 (field0, i + 1);
392 scanlines.tt1 = LINE2 (field1, (i - 2 >= 0) ? i - 2 : i);
393 scanlines.m1 = LINE2 (field1, i);
394 scanlines.bb1 = LINE2 (field1, (i + 2 < frame_height ? i + 2 : i));
396 scanlines.t2 = LINE2 (field2, i - 1);
397 scanlines.b2 = LINE2 (field2, i + 1);
399 self->interpolate_scanline_packed (self, LINE (dest, i), &scanlines);
405 gst_deinterlace_simple_method_interpolate_scanline_planar_y
406 (GstDeinterlaceSimpleMethod * self, guint8 * out,
407 const GstDeinterlaceScanlineData * scanlines)
409 memcpy (out, scanlines->m1, self->parent.row_stride[0]);
413 gst_deinterlace_simple_method_copy_scanline_planar_y (GstDeinterlaceSimpleMethod
414 * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
416 memcpy (out, scanlines->m0, self->parent.row_stride[0]);
420 gst_deinterlace_simple_method_interpolate_scanline_planar_u
421 (GstDeinterlaceSimpleMethod * self, guint8 * out,
422 const GstDeinterlaceScanlineData * scanlines)
424 memcpy (out, scanlines->m1, self->parent.row_stride[1]);
428 gst_deinterlace_simple_method_copy_scanline_planar_u (GstDeinterlaceSimpleMethod
429 * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
431 memcpy (out, scanlines->m0, self->parent.row_stride[1]);
435 gst_deinterlace_simple_method_interpolate_scanline_planar_v
436 (GstDeinterlaceSimpleMethod * self, guint8 * out,
437 const GstDeinterlaceScanlineData * scanlines)
439 memcpy (out, scanlines->m1, self->parent.row_stride[2]);
443 gst_deinterlace_simple_method_copy_scanline_planar_v (GstDeinterlaceSimpleMethod
444 * self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
446 memcpy (out, scanlines->m0, self->parent.row_stride[2]);
450 gst_deinterlace_simple_method_deinterlace_frame_planar_plane
451 (GstDeinterlaceSimpleMethod * self, guint8 * dest, const guint8 * field0,
452 const guint8 * field1, const guint8 * field2, const guint8 * fieldp,
453 guint cur_field_flags,
454 gint plane, GstDeinterlaceSimpleMethodFunction copy_scanline,
455 GstDeinterlaceSimpleMethodFunction interpolate_scanline)
457 GstDeinterlaceScanlineData scanlines;
459 gint frame_height = self->parent.height[plane];
460 gint stride = self->parent.row_stride[plane];
462 g_assert (interpolate_scanline != NULL);
463 g_assert (copy_scanline != NULL);
465 for (i = 0; i < frame_height; i++) {
466 memset (&scanlines, 0, sizeof (scanlines));
467 scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
469 if (!((i & 1) ^ scanlines.bottom_field)) {
471 scanlines.tp = LINE2 (fieldp, i - 1);
472 scanlines.bp = LINE2 (fieldp, i + 1);
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 copy_scanline (self, LINE (dest, i), &scanlines);
488 scanlines.ttp = LINE2 (fieldp, (i - 2 >= 0) ? i - 2 : i);
489 scanlines.mp = LINE2 (fieldp, i);
490 scanlines.bbp = LINE2 (fieldp, (i + 2 < frame_height ? i + 2 : i));
492 scanlines.t0 = LINE2 (field0, i - 1);
493 scanlines.b0 = LINE2 (field0, i + 1);
495 scanlines.tt1 = LINE2 (field1, (i - 2 >= 0) ? i - 2 : i);
496 scanlines.m1 = LINE2 (field1, i);
497 scanlines.bb1 = LINE2 (field1, (i + 2 < frame_height ? i + 2 : i));
499 scanlines.t2 = LINE2 (field2, i - 1);
500 scanlines.b2 = LINE2 (field2, i + 1);
502 interpolate_scanline (self, LINE (dest, i), &scanlines);
508 gst_deinterlace_simple_method_deinterlace_frame_planar (GstDeinterlaceMethod *
509 method, const GstDeinterlaceField * history, guint history_count,
510 GstVideoFrame * outframe, gint cur_field_idx)
512 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
513 GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
515 const guint8 *field0, *field1, *field2, *fieldp;
516 guint cur_field_flags = history[cur_field_idx].flags;
518 GstDeinterlaceSimpleMethodFunction copy_scanline;
519 GstDeinterlaceSimpleMethodFunction interpolate_scanline;
521 g_assert (self->interpolate_scanline_planar[0] != NULL);
522 g_assert (self->interpolate_scanline_planar[1] != NULL);
523 g_assert (self->interpolate_scanline_planar[2] != NULL);
524 g_assert (self->copy_scanline_planar[0] != NULL);
525 g_assert (self->copy_scanline_planar[1] != NULL);
526 g_assert (self->copy_scanline_planar[2] != NULL);
528 for (i = 0; i < 3; i++) {
529 copy_scanline = self->copy_scanline_planar[i];
530 interpolate_scanline = self->interpolate_scanline_planar[i];
532 out = GST_VIDEO_FRAME_PLANE_DATA (outframe, i);
535 if (cur_field_idx > 0) {
536 fieldp = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx - 1].frame, i);
539 field0 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx].frame, i);
541 g_assert (dm_class->fields_required <= 4);
544 if (cur_field_idx + 1 < history_count) {
545 field1 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx + 1].frame, i);
549 if (cur_field_idx + 2 < history_count) {
550 field2 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx + 2].frame, i);
553 gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
554 field0, field1, field2, fieldp, cur_field_flags, i, copy_scanline,
555 interpolate_scanline);
560 gst_deinterlace_simple_method_deinterlace_frame_nv12 (GstDeinterlaceMethod *
561 method, const GstDeinterlaceField * history, guint history_count,
562 GstVideoFrame * outframe, gint cur_field_idx)
564 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
565 GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
567 const guint8 *field0, *field1, *field2, *fieldp;
568 guint cur_field_flags = history[cur_field_idx].flags;
571 g_assert (self->interpolate_scanline_packed != NULL);
572 g_assert (self->copy_scanline_packed != NULL);
574 for (i = 0; i < 2; i++) {
575 out = GST_VIDEO_FRAME_PLANE_DATA (outframe, i);
578 if (cur_field_idx > 0) {
579 fieldp = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx - 1].frame, i);
582 field0 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx].frame, i);
584 g_assert (dm_class->fields_required <= 4);
587 if (cur_field_idx + 1 < history_count) {
588 field1 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx + 1].frame, i);
592 if (cur_field_idx + 2 < history_count) {
593 field2 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx + 2].frame, i);
596 gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
597 field0, field1, field2, fieldp, cur_field_flags, i,
598 self->copy_scanline_packed, self->interpolate_scanline_packed);
603 gst_deinterlace_simple_method_setup (GstDeinterlaceMethod * method,
604 GstVideoInfo * vinfo)
606 GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
607 GstDeinterlaceSimpleMethodClass *klass =
608 GST_DEINTERLACE_SIMPLE_METHOD_GET_CLASS (self);
610 GST_DEINTERLACE_METHOD_CLASS
611 (gst_deinterlace_simple_method_parent_class)->setup (method, vinfo);
613 self->interpolate_scanline_packed = NULL;
614 self->copy_scanline_packed = NULL;
616 self->interpolate_scanline_planar[0] = NULL;
617 self->interpolate_scanline_planar[1] = NULL;
618 self->interpolate_scanline_planar[2] = NULL;
619 self->copy_scanline_planar[0] = NULL;
620 self->copy_scanline_planar[1] = NULL;
621 self->copy_scanline_planar[2] = NULL;
623 if (GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_UNKNOWN)
626 switch (GST_VIDEO_INFO_FORMAT (vinfo)) {
627 case GST_VIDEO_FORMAT_YUY2:
628 self->interpolate_scanline_packed = klass->interpolate_scanline_yuy2;
629 self->copy_scanline_packed = klass->copy_scanline_yuy2;
631 case GST_VIDEO_FORMAT_YVYU:
632 self->interpolate_scanline_packed = klass->interpolate_scanline_yvyu;
633 self->copy_scanline_packed = klass->copy_scanline_yvyu;
635 case GST_VIDEO_FORMAT_UYVY:
636 self->interpolate_scanline_packed = klass->interpolate_scanline_uyvy;
637 self->copy_scanline_packed = klass->copy_scanline_uyvy;
639 case GST_VIDEO_FORMAT_AYUV:
640 self->interpolate_scanline_packed = klass->interpolate_scanline_ayuv;
641 self->copy_scanline_packed = klass->copy_scanline_ayuv;
643 case GST_VIDEO_FORMAT_ARGB:
644 case GST_VIDEO_FORMAT_xRGB:
645 self->interpolate_scanline_packed = klass->interpolate_scanline_argb;
646 self->copy_scanline_packed = klass->copy_scanline_argb;
648 case GST_VIDEO_FORMAT_ABGR:
649 case GST_VIDEO_FORMAT_xBGR:
650 self->interpolate_scanline_packed = klass->interpolate_scanline_abgr;
651 self->copy_scanline_packed = klass->copy_scanline_abgr;
653 case GST_VIDEO_FORMAT_RGBA:
654 case GST_VIDEO_FORMAT_RGBx:
655 self->interpolate_scanline_packed = klass->interpolate_scanline_rgba;
656 self->copy_scanline_packed = klass->copy_scanline_rgba;
658 case GST_VIDEO_FORMAT_BGRA:
659 case GST_VIDEO_FORMAT_BGRx:
660 self->interpolate_scanline_packed = klass->interpolate_scanline_bgra;
661 self->copy_scanline_packed = klass->copy_scanline_bgra;
663 case GST_VIDEO_FORMAT_RGB:
664 self->interpolate_scanline_packed = klass->interpolate_scanline_rgb;
665 self->copy_scanline_packed = klass->copy_scanline_rgb;
667 case GST_VIDEO_FORMAT_BGR:
668 self->interpolate_scanline_packed = klass->interpolate_scanline_bgr;
669 self->copy_scanline_packed = klass->copy_scanline_bgr;
671 case GST_VIDEO_FORMAT_NV12:
672 self->interpolate_scanline_packed = klass->interpolate_scanline_nv12;
673 self->copy_scanline_packed = klass->copy_scanline_nv12;
675 case GST_VIDEO_FORMAT_NV21:
676 self->interpolate_scanline_packed = klass->interpolate_scanline_nv21;
677 self->copy_scanline_packed = klass->copy_scanline_nv21;
679 case GST_VIDEO_FORMAT_I420:
680 case GST_VIDEO_FORMAT_YV12:
681 case GST_VIDEO_FORMAT_Y444:
682 case GST_VIDEO_FORMAT_Y42B:
683 case GST_VIDEO_FORMAT_Y41B:
684 self->interpolate_scanline_planar[0] =
685 klass->interpolate_scanline_planar_y;
686 self->copy_scanline_planar[0] = klass->copy_scanline_planar_y;
687 self->interpolate_scanline_planar[1] =
688 klass->interpolate_scanline_planar_u;
689 self->copy_scanline_planar[1] = klass->copy_scanline_planar_u;
690 self->interpolate_scanline_planar[2] =
691 klass->interpolate_scanline_planar_v;
692 self->copy_scanline_planar[2] = klass->copy_scanline_planar_v;
700 gst_deinterlace_simple_method_class_init (GstDeinterlaceSimpleMethodClass
703 GstDeinterlaceMethodClass *dm_class = (GstDeinterlaceMethodClass *) klass;
705 dm_class->deinterlace_frame_ayuv =
706 gst_deinterlace_simple_method_deinterlace_frame_packed;
707 dm_class->deinterlace_frame_yuy2 =
708 gst_deinterlace_simple_method_deinterlace_frame_packed;
709 dm_class->deinterlace_frame_yvyu =
710 gst_deinterlace_simple_method_deinterlace_frame_packed;
711 dm_class->deinterlace_frame_uyvy =
712 gst_deinterlace_simple_method_deinterlace_frame_packed;
713 dm_class->deinterlace_frame_argb =
714 gst_deinterlace_simple_method_deinterlace_frame_packed;
715 dm_class->deinterlace_frame_abgr =
716 gst_deinterlace_simple_method_deinterlace_frame_packed;
717 dm_class->deinterlace_frame_rgba =
718 gst_deinterlace_simple_method_deinterlace_frame_packed;
719 dm_class->deinterlace_frame_bgra =
720 gst_deinterlace_simple_method_deinterlace_frame_packed;
721 dm_class->deinterlace_frame_rgb =
722 gst_deinterlace_simple_method_deinterlace_frame_packed;
723 dm_class->deinterlace_frame_bgr =
724 gst_deinterlace_simple_method_deinterlace_frame_packed;
725 dm_class->deinterlace_frame_i420 =
726 gst_deinterlace_simple_method_deinterlace_frame_planar;
727 dm_class->deinterlace_frame_yv12 =
728 gst_deinterlace_simple_method_deinterlace_frame_planar;
729 dm_class->deinterlace_frame_y444 =
730 gst_deinterlace_simple_method_deinterlace_frame_planar;
731 dm_class->deinterlace_frame_y42b =
732 gst_deinterlace_simple_method_deinterlace_frame_planar;
733 dm_class->deinterlace_frame_y41b =
734 gst_deinterlace_simple_method_deinterlace_frame_planar;
735 dm_class->deinterlace_frame_nv12 =
736 gst_deinterlace_simple_method_deinterlace_frame_nv12;
737 dm_class->deinterlace_frame_nv21 =
738 gst_deinterlace_simple_method_deinterlace_frame_nv12;
739 dm_class->fields_required = 2;
740 dm_class->setup = gst_deinterlace_simple_method_setup;
741 dm_class->supported = gst_deinterlace_simple_method_supported;
743 klass->interpolate_scanline_yuy2 =
744 gst_deinterlace_simple_method_interpolate_scanline_packed;
745 klass->copy_scanline_yuy2 =
746 gst_deinterlace_simple_method_copy_scanline_packed;
747 klass->interpolate_scanline_yvyu =
748 gst_deinterlace_simple_method_interpolate_scanline_packed;
749 klass->copy_scanline_yvyu =
750 gst_deinterlace_simple_method_copy_scanline_packed;
751 klass->interpolate_scanline_ayuv =
752 gst_deinterlace_simple_method_interpolate_scanline_packed;
753 klass->copy_scanline_ayuv =
754 gst_deinterlace_simple_method_copy_scanline_packed;
755 klass->interpolate_scanline_uyvy =
756 gst_deinterlace_simple_method_interpolate_scanline_packed;
757 klass->copy_scanline_uyvy =
758 gst_deinterlace_simple_method_copy_scanline_packed;
759 klass->interpolate_scanline_nv12 =
760 gst_deinterlace_simple_method_interpolate_scanline_packed;
761 klass->copy_scanline_nv12 =
762 gst_deinterlace_simple_method_copy_scanline_packed;
764 klass->interpolate_scanline_argb =
765 gst_deinterlace_simple_method_interpolate_scanline_packed;
766 klass->copy_scanline_argb =
767 gst_deinterlace_simple_method_copy_scanline_packed;
768 klass->interpolate_scanline_abgr =
769 gst_deinterlace_simple_method_interpolate_scanline_packed;
770 klass->copy_scanline_abgr =
771 gst_deinterlace_simple_method_copy_scanline_packed;
773 klass->interpolate_scanline_rgba =
774 gst_deinterlace_simple_method_interpolate_scanline_packed;
775 klass->copy_scanline_rgba =
776 gst_deinterlace_simple_method_copy_scanline_packed;
777 klass->interpolate_scanline_bgra =
778 gst_deinterlace_simple_method_interpolate_scanline_packed;
779 klass->copy_scanline_bgra =
780 gst_deinterlace_simple_method_copy_scanline_packed;
781 klass->interpolate_scanline_rgb =
782 gst_deinterlace_simple_method_interpolate_scanline_packed;
783 klass->copy_scanline_rgb = gst_deinterlace_simple_method_copy_scanline_packed;
784 klass->interpolate_scanline_bgr =
785 gst_deinterlace_simple_method_interpolate_scanline_packed;
786 klass->copy_scanline_bgr = gst_deinterlace_simple_method_copy_scanline_packed;
788 klass->interpolate_scanline_planar_y =
789 gst_deinterlace_simple_method_interpolate_scanline_planar_y;
790 klass->copy_scanline_planar_y =
791 gst_deinterlace_simple_method_copy_scanline_planar_y;
792 klass->interpolate_scanline_planar_u =
793 gst_deinterlace_simple_method_interpolate_scanline_planar_u;
794 klass->copy_scanline_planar_u =
795 gst_deinterlace_simple_method_copy_scanline_planar_u;
796 klass->interpolate_scanline_planar_v =
797 gst_deinterlace_simple_method_interpolate_scanline_planar_v;
798 klass->copy_scanline_planar_v =
799 gst_deinterlace_simple_method_copy_scanline_planar_v;
803 gst_deinterlace_simple_method_init (GstDeinterlaceSimpleMethod * self)