2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
4 * Copyright (C) <2010> Sebastian Dröge <sebastian.droege@collabora.co.uk>
5 * Copyright (C) <2011> Youness Alaoui <youness.alaoui@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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 * This file was (probably) generated from gstvideoflip.c,
25 * gstvideoflip.c,v 1.7 2003/11/08 02:48:59 dschleef Exp
28 * SECTION:element-videoflip
30 * Flips and rotates video.
33 * <title>Example launch line</title>
35 * gst-launch-1.0 videotestsrc ! videoflip method=clockwise ! videoconvert ! ximagesink
36 * ]| This pipeline flips the test image 90 degrees clockwise.
45 #include "gstvideoflip.h"
49 #include <gst/video/video.h>
51 /* GstVideoFlip properties */
60 #define PROP_METHOD_DEFAULT GST_VIDEO_FLIP_METHOD_IDENTITY
62 GST_DEBUG_CATEGORY_STATIC (video_flip_debug);
63 #define GST_CAT_DEFAULT video_flip_debug
65 static GstStaticPadTemplate gst_video_flip_src_template =
66 GST_STATIC_PAD_TEMPLATE ("src",
69 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
70 "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, "
71 "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, "
72 "GRAY8, GRAY16_BE, GRAY16_LE }"))
75 static GstStaticPadTemplate gst_video_flip_sink_template =
76 GST_STATIC_PAD_TEMPLATE ("sink",
79 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
80 "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, "
81 "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, "
82 "GRAY8, GRAY16_BE, GRAY16_LE }"))
85 #define GST_TYPE_VIDEO_FLIP_METHOD (gst_video_flip_method_get_type())
87 static const GEnumValue video_flip_methods[] = {
88 {GST_VIDEO_FLIP_METHOD_IDENTITY, "Identity (no rotation)", "none"},
89 {GST_VIDEO_FLIP_METHOD_90R, "Rotate clockwise 90 degrees", "clockwise"},
90 {GST_VIDEO_FLIP_METHOD_180, "Rotate 180 degrees", "rotate-180"},
91 {GST_VIDEO_FLIP_METHOD_90L, "Rotate counter-clockwise 90 degrees",
93 {GST_VIDEO_FLIP_METHOD_HORIZ, "Flip horizontally", "horizontal-flip"},
94 {GST_VIDEO_FLIP_METHOD_VERT, "Flip vertically", "vertical-flip"},
95 {GST_VIDEO_FLIP_METHOD_TRANS,
96 "Flip across upper left/lower right diagonal", "upper-left-diagonal"},
97 {GST_VIDEO_FLIP_METHOD_OTHER,
98 "Flip across upper right/lower left diagonal", "upper-right-diagonal"},
99 {GST_VIDEO_FLIP_METHOD_AUTO,
100 "Select flip method based on image-orientation tag", "automatic"},
105 gst_video_flip_method_get_type (void)
107 static GType video_flip_method_type = 0;
109 if (!video_flip_method_type) {
110 video_flip_method_type = g_enum_register_static ("GstVideoFlipMethod",
113 return video_flip_method_type;
117 gst_video_flip_video_direction_interface_init (GstVideoDirectionInterface *
120 /* We implement the video-direction property */
123 #define gst_video_flip_parent_class parent_class
124 G_DEFINE_TYPE_WITH_CODE (GstVideoFlip, gst_video_flip, GST_TYPE_VIDEO_FILTER,
125 G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_DIRECTION,
126 gst_video_flip_video_direction_interface_init));
129 gst_video_flip_transform_caps (GstBaseTransform * trans,
130 GstPadDirection direction, GstCaps * caps, GstCaps * filter)
132 GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
134 gint width, height, i;
136 ret = gst_caps_copy (caps);
138 for (i = 0; i < gst_caps_get_size (ret); i++) {
139 GstStructure *structure = gst_caps_get_structure (ret, i);
142 if (gst_structure_get_int (structure, "width", &width) &&
143 gst_structure_get_int (structure, "height", &height)) {
145 switch (videoflip->active_method) {
146 case GST_VIDEO_ORIENTATION_90R:
147 case GST_VIDEO_ORIENTATION_90L:
148 case GST_VIDEO_ORIENTATION_UL_LR:
149 case GST_VIDEO_ORIENTATION_UR_LL:
150 gst_structure_set (structure, "width", G_TYPE_INT, height,
151 "height", G_TYPE_INT, width, NULL);
152 if (gst_structure_get_fraction (structure, "pixel-aspect-ratio",
154 if (par_n != 1 || par_d != 1) {
157 g_value_init (&val, GST_TYPE_FRACTION);
158 gst_value_set_fraction (&val, par_d, par_n);
159 gst_structure_set_value (structure, "pixel-aspect-ratio", &val);
160 g_value_unset (&val);
164 case GST_VIDEO_ORIENTATION_IDENTITY:
165 case GST_VIDEO_ORIENTATION_180:
166 case GST_VIDEO_ORIENTATION_HORIZ:
167 case GST_VIDEO_ORIENTATION_VERT:
168 gst_structure_set (structure, "width", G_TYPE_INT, width,
169 "height", G_TYPE_INT, height, NULL);
171 case GST_VIDEO_ORIENTATION_CUSTOM:
172 GST_WARNING_OBJECT (videoflip, "unsuported custom orientation");
175 g_assert_not_reached ();
181 GST_DEBUG_OBJECT (videoflip, "transformed %" GST_PTR_FORMAT " to %"
182 GST_PTR_FORMAT, caps, ret);
185 GstCaps *intersection;
187 GST_DEBUG_OBJECT (videoflip, "Using filter caps %" GST_PTR_FORMAT, filter);
189 gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
190 gst_caps_unref (ret);
192 GST_DEBUG_OBJECT (videoflip, "Intersection %" GST_PTR_FORMAT, ret);
199 gst_video_flip_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest,
200 const GstVideoFrame * src)
205 gint src_y_stride, src_u_stride, src_v_stride;
206 gint src_y_height, src_u_height, src_v_height;
207 gint src_y_width, src_u_width, src_v_width;
208 gint dest_y_stride, dest_u_stride, dest_v_stride;
209 gint dest_y_height, dest_u_height, dest_v_height;
210 gint dest_y_width, dest_u_width, dest_v_width;
212 src_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
213 src_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 1);
214 src_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 2);
216 dest_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
217 dest_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 1);
218 dest_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 2);
220 src_y_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 0);
221 src_u_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 1);
222 src_v_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 2);
224 dest_y_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 0);
225 dest_u_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 1);
226 dest_v_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 2);
228 src_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 0);
229 src_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 1);
230 src_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 2);
232 dest_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 0);
233 dest_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 1);
234 dest_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 2);
236 switch (videoflip->active_method) {
237 case GST_VIDEO_ORIENTATION_90R:
239 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
240 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
241 for (y = 0; y < dest_y_height; y++) {
242 for (x = 0; x < dest_y_width; x++) {
243 d[y * dest_y_stride + x] =
244 s[(src_y_height - 1 - x) * src_y_stride + y];
248 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
249 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
250 for (y = 0; y < dest_u_height; y++) {
251 for (x = 0; x < dest_u_width; x++) {
252 d[y * dest_u_stride + x] =
253 s[(src_u_height - 1 - x) * src_u_stride + y];
257 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
258 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
259 for (y = 0; y < dest_v_height; y++) {
260 for (x = 0; x < dest_v_width; x++) {
261 d[y * dest_v_stride + x] =
262 s[(src_v_height - 1 - x) * src_v_stride + y];
266 case GST_VIDEO_ORIENTATION_90L:
268 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
269 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
270 for (y = 0; y < dest_y_height; y++) {
271 for (x = 0; x < dest_y_width; x++) {
272 d[y * dest_y_stride + x] =
273 s[x * src_y_stride + (src_y_width - 1 - y)];
277 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
278 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
279 for (y = 0; y < dest_u_height; y++) {
280 for (x = 0; x < dest_u_width; x++) {
281 d[y * dest_u_stride + x] =
282 s[x * src_u_stride + (src_u_width - 1 - y)];
286 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
287 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
288 for (y = 0; y < dest_v_height; y++) {
289 for (x = 0; x < dest_v_width; x++) {
290 d[y * dest_v_stride + x] =
291 s[x * src_v_stride + (src_v_width - 1 - y)];
295 case GST_VIDEO_ORIENTATION_180:
297 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
298 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
299 for (y = 0; y < dest_y_height; y++) {
300 for (x = 0; x < dest_y_width; x++) {
301 d[y * dest_y_stride + x] =
302 s[(src_y_height - 1 - y) * src_y_stride + (src_y_width - 1 - x)];
306 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
307 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
308 for (y = 0; y < dest_u_height; y++) {
309 for (x = 0; x < dest_u_width; x++) {
310 d[y * dest_u_stride + x] =
311 s[(src_u_height - 1 - y) * src_u_stride + (src_u_width - 1 - x)];
315 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
316 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
317 for (y = 0; y < dest_v_height; y++) {
318 for (x = 0; x < dest_v_width; x++) {
319 d[y * dest_v_stride + x] =
320 s[(src_v_height - 1 - y) * src_v_stride + (src_v_width - 1 - x)];
324 case GST_VIDEO_ORIENTATION_HORIZ:
326 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
327 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
328 for (y = 0; y < dest_y_height; y++) {
329 for (x = 0; x < dest_y_width; x++) {
330 d[y * dest_y_stride + x] =
331 s[y * src_y_stride + (src_y_width - 1 - x)];
335 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
336 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
337 for (y = 0; y < dest_u_height; y++) {
338 for (x = 0; x < dest_u_width; x++) {
339 d[y * dest_u_stride + x] =
340 s[y * src_u_stride + (src_u_width - 1 - x)];
344 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
345 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
346 for (y = 0; y < dest_v_height; y++) {
347 for (x = 0; x < dest_v_width; x++) {
348 d[y * dest_v_stride + x] =
349 s[y * src_v_stride + (src_v_width - 1 - x)];
353 case GST_VIDEO_ORIENTATION_VERT:
355 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
356 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
357 for (y = 0; y < dest_y_height; y++) {
358 for (x = 0; x < dest_y_width; x++) {
359 d[y * dest_y_stride + x] =
360 s[(src_y_height - 1 - y) * src_y_stride + x];
364 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
365 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
366 for (y = 0; y < dest_u_height; y++) {
367 for (x = 0; x < dest_u_width; x++) {
368 d[y * dest_u_stride + x] =
369 s[(src_u_height - 1 - y) * src_u_stride + x];
373 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
374 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
375 for (y = 0; y < dest_v_height; y++) {
376 for (x = 0; x < dest_v_width; x++) {
377 d[y * dest_v_stride + x] =
378 s[(src_v_height - 1 - y) * src_v_stride + x];
382 case GST_VIDEO_ORIENTATION_UL_LR:
384 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
385 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
386 for (y = 0; y < dest_y_height; y++) {
387 for (x = 0; x < dest_y_width; x++) {
388 d[y * dest_y_stride + x] = s[x * src_y_stride + y];
392 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
393 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
394 for (y = 0; y < dest_u_height; y++) {
395 for (x = 0; x < dest_u_width; x++) {
396 d[y * dest_u_stride + x] = s[x * src_u_stride + y];
400 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
401 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
402 for (y = 0; y < dest_u_height; y++) {
403 for (x = 0; x < dest_u_width; x++) {
404 d[y * dest_v_stride + x] = s[x * src_v_stride + y];
408 case GST_VIDEO_ORIENTATION_UR_LL:
410 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
411 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
412 for (y = 0; y < dest_y_height; y++) {
413 for (x = 0; x < dest_y_width; x++) {
414 d[y * dest_y_stride + x] =
415 s[(src_y_height - 1 - x) * src_y_stride + (src_y_width - 1 - y)];
419 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
420 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
421 for (y = 0; y < dest_u_height; y++) {
422 for (x = 0; x < dest_u_width; x++) {
423 d[y * dest_u_stride + x] =
424 s[(src_u_height - 1 - x) * src_u_stride + (src_u_width - 1 - y)];
428 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
429 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
430 for (y = 0; y < dest_v_height; y++) {
431 for (x = 0; x < dest_v_width; x++) {
432 d[y * dest_v_stride + x] =
433 s[(src_v_height - 1 - x) * src_v_stride + (src_v_width - 1 - y)];
437 case GST_VIDEO_ORIENTATION_IDENTITY:
438 g_assert_not_reached ();
441 g_assert_not_reached ();
447 gst_video_flip_semi_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest,
448 const GstVideoFrame * src)
454 gint src_y_stride, src_uv_stride;
455 gint src_y_height, src_uv_height;
456 gint src_y_width, src_uv_width;
457 gint dest_y_stride, dest_uv_stride;
458 gint dest_y_height, dest_uv_height;
459 gint dest_y_width, dest_uv_width;
462 src_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
463 src_uv_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 1);
465 dest_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
466 dest_uv_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 1);
468 src_y_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 0);
469 src_uv_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 1);
471 dest_y_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 0);
472 dest_uv_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 1);
474 src_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 0);
475 src_uv_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 1);
477 dest_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 0);
478 dest_uv_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 1);
480 switch (videoflip->active_method) {
481 case GST_VIDEO_ORIENTATION_90R:
483 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
484 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
485 for (y = 0; y < dest_y_height; y++) {
486 for (x = 0; x < dest_y_width; x++) {
487 d[y * dest_y_stride + x] =
488 s[(src_y_height - 1 - x) * src_y_stride + y];
492 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
493 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
494 for (y = 0; y < dest_uv_height; y++) {
495 for (x = 0; x < dest_uv_width; x++) {
496 d_off = y * dest_uv_stride + x * 2;
497 s_off = (src_uv_height - 1 - x) * src_uv_stride + y * 2;
499 d[d_off + 1] = s[s_off + 1];
503 case GST_VIDEO_ORIENTATION_90L:
505 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
506 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
507 for (y = 0; y < dest_y_height; y++) {
508 for (x = 0; x < dest_y_width; x++) {
509 d[y * dest_y_stride + x] =
510 s[x * src_y_stride + (src_y_width - 1 - y)];
514 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
515 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
516 for (y = 0; y < dest_uv_height; y++) {
517 for (x = 0; x < dest_uv_width; x++) {
518 d_off = y * dest_uv_stride + x * 2;
519 s_off = x * src_uv_stride + (src_uv_width - 1 - y) * 2;
521 d[d_off + 1] = s[s_off + 1];
525 case GST_VIDEO_ORIENTATION_180:
527 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
528 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
529 for (y = 0; y < dest_y_height; y++) {
530 for (x = 0; x < dest_y_width; x++) {
531 d[y * dest_y_stride + x] =
532 s[(src_y_height - 1 - y) * src_y_stride + (src_y_width - 1 - x)];
536 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
537 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
538 for (y = 0; y < dest_uv_height; y++) {
539 for (x = 0; x < dest_uv_width; x++) {
540 d_off = y * dest_uv_stride + x * 2;
541 s_off = (src_uv_height - 1 - y) * src_uv_stride + (src_uv_width - 1 -
544 d[d_off + 1] = s[s_off + 1];
548 case GST_VIDEO_ORIENTATION_HORIZ:
550 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
551 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
552 for (y = 0; y < dest_y_height; y++) {
553 for (x = 0; x < dest_y_width; x++) {
554 d[y * dest_y_stride + x] =
555 s[y * src_y_stride + (src_y_width - 1 - x)];
559 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
560 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
561 for (y = 0; y < dest_uv_height; y++) {
562 for (x = 0; x < dest_uv_width; x++) {
563 d_off = y * dest_uv_stride + x * 2;
564 s_off = y * src_uv_stride + (src_uv_width - 1 - x) * 2;
566 d[d_off + 1] = s[s_off + 1];
570 case GST_VIDEO_ORIENTATION_VERT:
572 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
573 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
574 for (y = 0; y < dest_y_height; y++) {
575 for (x = 0; x < dest_y_width; x++) {
576 d[y * dest_y_stride + x] =
577 s[(src_y_height - 1 - y) * src_y_stride + x];
581 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
582 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
583 for (y = 0; y < dest_uv_height; y++) {
584 for (x = 0; x < dest_uv_width; x++) {
585 d_off = y * dest_uv_stride + x * 2;
586 s_off = (src_uv_height - 1 - y) * src_uv_stride + x * 2;
588 d[d_off + 1] = s[s_off + 1];
592 case GST_VIDEO_ORIENTATION_UL_LR:
594 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
595 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
596 for (y = 0; y < dest_y_height; y++) {
597 for (x = 0; x < dest_y_width; x++) {
598 d[y * dest_y_stride + x] = s[x * src_y_stride + y];
602 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
603 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
604 for (y = 0; y < dest_uv_height; y++) {
605 for (x = 0; x < dest_uv_width; x++) {
606 d_off = y * dest_uv_stride + x * 2;
607 s_off = x * src_uv_stride + y * 2;
609 d[d_off + 1] = s[s_off + 1];
613 case GST_VIDEO_ORIENTATION_UR_LL:
615 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
616 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
617 for (y = 0; y < dest_y_height; y++) {
618 for (x = 0; x < dest_y_width; x++) {
619 d[y * dest_y_stride + x] =
620 s[(src_y_height - 1 - x) * src_y_stride + (src_y_width - 1 - y)];
624 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
625 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
626 for (y = 0; y < dest_uv_height; y++) {
627 for (x = 0; x < dest_uv_width; x++) {
628 d_off = y * dest_uv_stride + x * 2;
629 s_off = (src_uv_height - 1 - x) * src_uv_stride + (src_uv_width - 1 -
632 d[d_off + 1] = s[s_off + 1];
636 case GST_VIDEO_ORIENTATION_IDENTITY:
637 g_assert_not_reached ();
640 g_assert_not_reached ();
646 gst_video_flip_packed_simple (GstVideoFlip * videoflip, GstVideoFrame * dest,
647 const GstVideoFrame * src)
652 gint sw = GST_VIDEO_FRAME_WIDTH (src);
653 gint sh = GST_VIDEO_FRAME_HEIGHT (src);
654 gint dw = GST_VIDEO_FRAME_WIDTH (dest);
655 gint dh = GST_VIDEO_FRAME_HEIGHT (dest);
656 gint src_stride, dest_stride;
659 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
660 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
662 src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
663 dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
664 /* This is only true for non-subsampled formats! */
665 bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (src, 0);
667 switch (videoflip->active_method) {
668 case GST_VIDEO_ORIENTATION_90R:
669 for (y = 0; y < dh; y++) {
670 for (x = 0; x < dw; x++) {
671 for (z = 0; z < bpp; z++) {
672 d[y * dest_stride + x * bpp + z] =
673 s[(sh - 1 - x) * src_stride + y * bpp + z];
678 case GST_VIDEO_ORIENTATION_90L:
679 for (y = 0; y < dh; y++) {
680 for (x = 0; x < dw; x++) {
681 for (z = 0; z < bpp; z++) {
682 d[y * dest_stride + x * bpp + z] =
683 s[x * src_stride + (sw - 1 - y) * bpp + z];
688 case GST_VIDEO_ORIENTATION_180:
689 for (y = 0; y < dh; y++) {
690 for (x = 0; x < dw; x++) {
691 for (z = 0; z < bpp; z++) {
692 d[y * dest_stride + x * bpp + z] =
693 s[(sh - 1 - y) * src_stride + (sw - 1 - x) * bpp + z];
698 case GST_VIDEO_ORIENTATION_HORIZ:
699 for (y = 0; y < dh; y++) {
700 for (x = 0; x < dw; x++) {
701 for (z = 0; z < bpp; z++) {
702 d[y * dest_stride + x * bpp + z] =
703 s[y * src_stride + (sw - 1 - x) * bpp + z];
708 case GST_VIDEO_ORIENTATION_VERT:
709 for (y = 0; y < dh; y++) {
710 for (x = 0; x < dw; x++) {
711 for (z = 0; z < bpp; z++) {
712 d[y * dest_stride + x * bpp + z] =
713 s[(sh - 1 - y) * src_stride + x * bpp + z];
718 case GST_VIDEO_ORIENTATION_UL_LR:
719 for (y = 0; y < dh; y++) {
720 for (x = 0; x < dw; x++) {
721 for (z = 0; z < bpp; z++) {
722 d[y * dest_stride + x * bpp + z] = s[x * src_stride + y * bpp + z];
727 case GST_VIDEO_ORIENTATION_UR_LL:
728 for (y = 0; y < dh; y++) {
729 for (x = 0; x < dw; x++) {
730 for (z = 0; z < bpp; z++) {
731 d[y * dest_stride + x * bpp + z] =
732 s[(sh - 1 - x) * src_stride + (sw - 1 - y) * bpp + z];
737 case GST_VIDEO_ORIENTATION_IDENTITY:
738 g_assert_not_reached ();
741 g_assert_not_reached ();
748 gst_video_flip_y422 (GstVideoFlip * videoflip, GstVideoFrame * dest,
749 const GstVideoFrame * src)
754 gint sw = GST_VIDEO_FRAME_WIDTH (src);
755 gint sh = GST_VIDEO_FRAME_HEIGHT (src);
756 gint dw = GST_VIDEO_FRAME_WIDTH (dest);
757 gint dh = GST_VIDEO_FRAME_HEIGHT (dest);
758 gint src_stride, dest_stride;
765 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
766 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
768 src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
769 dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
771 y_offset = GST_VIDEO_FRAME_COMP_OFFSET (src, 0);
772 u_offset = GST_VIDEO_FRAME_COMP_OFFSET (src, 1);
773 v_offset = GST_VIDEO_FRAME_COMP_OFFSET (src, 2);
774 y_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (src, 0);
777 switch (videoflip->active_method) {
778 case GST_VIDEO_ORIENTATION_90R:
779 for (y = 0; y < dh; y++) {
780 for (x = 0; x < dw; x += 2) {
783 /* u/v must be calculated using the offset of the even column */
784 gint even_y = (y & ~1);
786 u = s[(sh - 1 - x) * src_stride + even_y * bpp + u_offset];
788 u = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + u_offset]
790 v = s[(sh - 1 - x) * src_stride + even_y * bpp + v_offset];
792 v = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + v_offset]
795 d[y * dest_stride + x * bpp + u_offset] = u;
796 d[y * dest_stride + x * bpp + v_offset] = v;
797 d[y * dest_stride + x * bpp + y_offset] =
798 s[(sh - 1 - x) * src_stride + y * bpp + y_offset];
800 d[y * dest_stride + (x + 1) * bpp + y_offset] =
801 s[(sh - 1 - (x + 1)) * src_stride + y * bpp + y_offset];
805 case GST_VIDEO_ORIENTATION_90L:
806 for (y = 0; y < dh; y++) {
807 for (x = 0; x < dw; x += 2) {
810 /* u/v must be calculated using the offset of the even column */
811 gint even_y = ((sw - 1 - y) & ~1);
813 u = s[x * src_stride + even_y * bpp + u_offset];
815 u = (s[(x + 1) * src_stride + even_y * bpp + u_offset] + u) >> 1;
816 v = s[x * src_stride + even_y * bpp + v_offset];
818 v = (s[(x + 1) * src_stride + even_y * bpp + v_offset] + v) >> 1;
820 d[y * dest_stride + x * bpp + u_offset] = u;
821 d[y * dest_stride + x * bpp + v_offset] = v;
822 d[y * dest_stride + x * bpp + y_offset] =
823 s[x * src_stride + (sw - 1 - y) * bpp + y_offset];
825 d[y * dest_stride + (x + 1) * bpp + y_offset] =
826 s[(x + 1) * src_stride + (sw - 1 - y) * bpp + y_offset];
830 case GST_VIDEO_ORIENTATION_180:
831 for (y = 0; y < dh; y++) {
832 for (x = 0; x < dw; x += 2) {
835 /* u/v must be calculated using the offset of the even column */
836 gint even_x = ((sw - 1 - x) & ~1);
838 u = (s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset] +
839 s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset]) / 2;
840 v = (s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset] +
841 s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset]) / 2;
843 d[y * dest_stride + x * bpp + u_offset] = u;
844 d[y * dest_stride + x * bpp + v_offset] = v;
845 d[y * dest_stride + x * bpp + y_offset] =
846 s[(sh - 1 - y) * src_stride + (sw - 1 - x) * bpp + y_offset];
848 d[y * dest_stride + (x + 1) * bpp + y_offset] =
849 s[(sh - 1 - y) * src_stride + (sw - 1 - (x + 1)) * bpp +
854 case GST_VIDEO_ORIENTATION_HORIZ:
855 for (y = 0; y < dh; y++) {
856 for (x = 0; x < dw; x += 2) {
859 /* u/v must be calculated using the offset of the even column */
860 gint even_x = ((sw - 1 - x) & ~1);
862 u = (s[y * src_stride + even_x * bpp + u_offset] +
863 s[y * src_stride + even_x * bpp + u_offset]) / 2;
864 v = (s[y * src_stride + even_x * bpp + v_offset] +
865 s[y * src_stride + even_x * bpp + v_offset]) / 2;
867 d[y * dest_stride + x * bpp + u_offset] = u;
868 d[y * dest_stride + x * bpp + v_offset] = v;
869 d[y * dest_stride + x * bpp + y_offset] =
870 s[y * src_stride + (sw - 1 - x) * bpp + y_offset];
872 d[y * dest_stride + (x + 1) * bpp + y_offset] =
873 s[y * src_stride + (sw - 1 - (x + 1)) * bpp + y_offset];
877 case GST_VIDEO_ORIENTATION_VERT:
878 for (y = 0; y < dh; y++) {
879 for (x = 0; x < dw; x += 2) {
882 /* u/v must be calculated using the offset of the even column */
883 gint even_x = (x & ~1);
885 u = (s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset] +
886 s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset]) / 2;
887 v = (s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset] +
888 s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset]) / 2;
890 d[y * dest_stride + x * bpp + u_offset] = u;
891 d[y * dest_stride + x * bpp + v_offset] = v;
892 d[y * dest_stride + x * bpp + y_offset] =
893 s[(sh - 1 - y) * src_stride + x * bpp + y_offset];
895 d[y * dest_stride + (x + 1) * bpp + y_offset] =
896 s[(sh - 1 - y) * src_stride + (x + 1) * bpp + y_offset];
900 case GST_VIDEO_ORIENTATION_UL_LR:
901 for (y = 0; y < dh; y++) {
902 for (x = 0; x < dw; x += 2) {
905 /* u/v must be calculated using the offset of the even column */
906 gint even_y = (y & ~1);
908 u = s[x * src_stride + even_y * bpp + u_offset];
910 u = (s[(x + 1) * src_stride + even_y * bpp + u_offset] + u) >> 1;
911 v = s[x * src_stride + even_y * bpp + v_offset];
913 v = (s[(x + 1) * src_stride + even_y * bpp + v_offset] + v) >> 1;
915 d[y * dest_stride + x * bpp + u_offset] = u;
916 d[y * dest_stride + x * bpp + v_offset] = v;
917 d[y * dest_stride + x * bpp + y_offset] =
918 s[x * src_stride + y * bpp + y_offset];
920 d[y * dest_stride + (x + 1) * bpp + y_offset] =
921 s[(x + 1) * src_stride + y * bpp + y_offset];
925 case GST_VIDEO_ORIENTATION_UR_LL:
926 for (y = 0; y < dh; y++) {
927 for (x = 0; x < dw; x += 2) {
930 /* u/v must be calculated using the offset of the even column */
931 gint even_y = ((sw - 1 - y) & ~1);
933 u = s[(sh - 1 - x) * src_stride + even_y * bpp + u_offset];
935 u = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + u_offset]
937 v = s[(sh - 1 - x) * src_stride + even_y * bpp + v_offset];
939 v = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + v_offset]
942 d[y * dest_stride + x * bpp + u_offset] = u;
943 d[y * dest_stride + x * bpp + v_offset] = v;
944 d[y * dest_stride + x * bpp + y_offset] =
945 s[(sh - 1 - x) * src_stride + (sw - 1 - y) * bpp + y_offset];
947 d[y * dest_stride + (x + 1) * bpp + y_offset] =
948 s[(sh - 1 - (x + 1)) * src_stride + (sw - 1 - y) * bpp +
953 case GST_VIDEO_ORIENTATION_IDENTITY:
954 g_assert_not_reached ();
957 g_assert_not_reached ();
964 gst_video_flip_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
965 GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
967 GstVideoFlip *vf = GST_VIDEO_FLIP (vfilter);
968 gboolean ret = FALSE;
972 if (GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_INFO_FORMAT (out_info))
975 /* Check that they are correct */
976 switch (vf->active_method) {
977 case GST_VIDEO_ORIENTATION_90R:
978 case GST_VIDEO_ORIENTATION_90L:
979 case GST_VIDEO_ORIENTATION_UL_LR:
980 case GST_VIDEO_ORIENTATION_UR_LL:
981 if ((in_info->width != out_info->height) ||
982 (in_info->height != out_info->width)) {
983 GST_ERROR_OBJECT (vf, "we are inverting width and height but caps "
984 "are not correct : %dx%d to %dx%d", in_info->width,
985 in_info->height, out_info->width, out_info->height);
989 case GST_VIDEO_ORIENTATION_IDENTITY:
992 case GST_VIDEO_ORIENTATION_180:
993 case GST_VIDEO_ORIENTATION_HORIZ:
994 case GST_VIDEO_ORIENTATION_VERT:
995 if ((in_info->width != out_info->width) ||
996 (in_info->height != out_info->height)) {
997 GST_ERROR_OBJECT (vf, "we are keeping width and height but caps "
998 "are not correct : %dx%d to %dx%d", in_info->width,
999 in_info->height, out_info->width, out_info->height);
1004 g_assert_not_reached ();
1010 switch (GST_VIDEO_INFO_FORMAT (in_info)) {
1011 case GST_VIDEO_FORMAT_I420:
1012 case GST_VIDEO_FORMAT_YV12:
1013 case GST_VIDEO_FORMAT_Y444:
1014 vf->process = gst_video_flip_planar_yuv;
1016 case GST_VIDEO_FORMAT_YUY2:
1017 case GST_VIDEO_FORMAT_UYVY:
1018 case GST_VIDEO_FORMAT_YVYU:
1019 vf->process = gst_video_flip_y422;
1021 case GST_VIDEO_FORMAT_AYUV:
1022 case GST_VIDEO_FORMAT_ARGB:
1023 case GST_VIDEO_FORMAT_ABGR:
1024 case GST_VIDEO_FORMAT_RGBA:
1025 case GST_VIDEO_FORMAT_BGRA:
1026 case GST_VIDEO_FORMAT_xRGB:
1027 case GST_VIDEO_FORMAT_xBGR:
1028 case GST_VIDEO_FORMAT_RGBx:
1029 case GST_VIDEO_FORMAT_BGRx:
1030 case GST_VIDEO_FORMAT_RGB:
1031 case GST_VIDEO_FORMAT_BGR:
1032 case GST_VIDEO_FORMAT_GRAY8:
1033 case GST_VIDEO_FORMAT_GRAY16_BE:
1034 case GST_VIDEO_FORMAT_GRAY16_LE:
1035 vf->process = gst_video_flip_packed_simple;
1037 case GST_VIDEO_FORMAT_NV12:
1038 case GST_VIDEO_FORMAT_NV21:
1039 vf->process = gst_video_flip_semi_planar_yuv;
1046 return ret && (vf->process != NULL);
1049 GST_ERROR_OBJECT (vf, "Invalid caps: %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT,
1055 gst_video_flip_set_method (GstVideoFlip * videoflip,
1056 GstVideoOrientationMethod method, gboolean from_tag)
1058 GST_OBJECT_LOCK (videoflip);
1060 if (method == GST_VIDEO_ORIENTATION_CUSTOM) {
1061 GST_WARNING_OBJECT (videoflip, "unsupported custom orientation");
1062 GST_OBJECT_UNLOCK (videoflip);
1066 /* Store updated method */
1068 videoflip->tag_method = method;
1070 videoflip->method = method;
1072 /* Get the new method */
1073 if (videoflip->method == GST_VIDEO_ORIENTATION_AUTO)
1074 method = videoflip->tag_method;
1076 method = videoflip->method;
1078 if (method != videoflip->active_method) {
1079 GEnumValue *active_method_enum, *method_enum;
1080 GstBaseTransform *btrans = GST_BASE_TRANSFORM (videoflip);
1081 GEnumClass *enum_class =
1082 g_type_class_ref (GST_TYPE_VIDEO_ORIENTATION_METHOD);
1084 active_method_enum =
1085 g_enum_get_value (enum_class, videoflip->active_method);
1086 method_enum = g_enum_get_value (enum_class, method);
1087 GST_DEBUG_OBJECT (videoflip, "Changing method from %s to %s",
1088 active_method_enum ? active_method_enum->value_nick : "(nil)",
1089 method_enum ? method_enum->value_nick : "(nil)");
1090 g_type_class_unref (enum_class);
1092 videoflip->active_method = method;
1094 GST_OBJECT_UNLOCK (videoflip);
1096 gst_base_transform_set_passthrough (btrans,
1097 method == GST_VIDEO_ORIENTATION_IDENTITY);
1098 gst_base_transform_reconfigure_src (btrans);
1100 GST_OBJECT_UNLOCK (videoflip);
1105 gst_video_flip_before_transform (GstBaseTransform * trans, GstBuffer * in)
1107 GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
1108 GstClockTime timestamp, stream_time;
1110 timestamp = GST_BUFFER_TIMESTAMP (in);
1112 gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
1114 GST_DEBUG_OBJECT (videoflip, "sync to %" GST_TIME_FORMAT,
1115 GST_TIME_ARGS (timestamp));
1117 if (GST_CLOCK_TIME_IS_VALID (stream_time))
1118 gst_object_sync_values (GST_OBJECT (videoflip), stream_time);
1121 static GstFlowReturn
1122 gst_video_flip_transform_frame (GstVideoFilter * vfilter,
1123 GstVideoFrame * in_frame, GstVideoFrame * out_frame)
1125 GEnumClass *enum_class;
1126 GEnumValue *active_method_enum;
1127 GstVideoFlip *videoflip = GST_VIDEO_FLIP (vfilter);
1129 if (G_UNLIKELY (videoflip->process == NULL))
1130 goto not_negotiated;
1132 enum_class = g_type_class_ref (GST_TYPE_VIDEO_ORIENTATION_METHOD);
1133 active_method_enum = g_enum_get_value (enum_class, videoflip->active_method);
1134 GST_LOG_OBJECT (videoflip, "videoflip: flipping (%s)",
1135 active_method_enum ? active_method_enum->value_nick : "(nil)");
1136 g_type_class_unref (enum_class);
1138 GST_OBJECT_LOCK (videoflip);
1139 videoflip->process (videoflip, out_frame, in_frame);
1140 GST_OBJECT_UNLOCK (videoflip);
1146 GST_ERROR_OBJECT (videoflip, "Not negotiated yet");
1147 return GST_FLOW_NOT_NEGOTIATED;
1152 gst_video_flip_src_event (GstBaseTransform * trans, GstEvent * event)
1154 GstVideoFlip *vf = GST_VIDEO_FLIP (trans);
1155 gdouble new_x, new_y, x, y;
1156 GstStructure *structure;
1158 GstVideoInfo *out_info = &GST_VIDEO_FILTER (trans)->out_info;
1160 GST_DEBUG_OBJECT (vf, "handling %s event", GST_EVENT_TYPE_NAME (event));
1162 switch (GST_EVENT_TYPE (event)) {
1163 case GST_EVENT_NAVIGATION:
1165 GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event)));
1167 structure = (GstStructure *) gst_event_get_structure (event);
1168 if (gst_structure_get_double (structure, "pointer_x", &x) &&
1169 gst_structure_get_double (structure, "pointer_y", &y)) {
1170 GST_DEBUG_OBJECT (vf, "converting %fx%f", x, y);
1171 switch (vf->active_method) {
1172 case GST_VIDEO_ORIENTATION_90R:
1174 new_y = out_info->width - x;
1176 case GST_VIDEO_ORIENTATION_90L:
1177 new_x = out_info->height - y;
1180 case GST_VIDEO_ORIENTATION_UR_LL:
1181 new_x = out_info->height - y;
1182 new_y = out_info->width - x;
1184 case GST_VIDEO_ORIENTATION_UL_LR:
1188 case GST_VIDEO_ORIENTATION_180:
1189 new_x = out_info->width - x;
1190 new_y = out_info->height - y;
1192 case GST_VIDEO_ORIENTATION_HORIZ:
1193 new_x = out_info->width - x;
1196 case GST_VIDEO_ORIENTATION_VERT:
1198 new_y = out_info->height - y;
1205 GST_DEBUG_OBJECT (vf, "to %fx%f", new_x, new_y);
1206 gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, new_x,
1207 "pointer_y", G_TYPE_DOUBLE, new_y, NULL);
1214 ret = GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event);
1220 gst_video_flip_sink_event (GstBaseTransform * trans, GstEvent * event)
1222 GstVideoFlip *vf = GST_VIDEO_FLIP (trans);
1223 GstTagList *taglist;
1227 GST_DEBUG_OBJECT (vf, "handling %s event", GST_EVENT_TYPE_NAME (event));
1229 switch (GST_EVENT_TYPE (event)) {
1231 gst_event_parse_tag (event, &taglist);
1233 if (gst_tag_list_get_string (taglist, "image-orientation", &orientation)) {
1234 if (!g_strcmp0 ("rotate-0", orientation))
1235 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_IDENTITY, TRUE);
1236 else if (!g_strcmp0 ("rotate-90", orientation))
1237 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_90R, TRUE);
1238 else if (!g_strcmp0 ("rotate-180", orientation))
1239 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_180, TRUE);
1240 else if (!g_strcmp0 ("rotate-270", orientation))
1241 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_90L, TRUE);
1242 else if (!g_strcmp0 ("flip-rotate-0", orientation))
1243 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_HORIZ, TRUE);
1244 else if (!g_strcmp0 ("flip-rotate-90", orientation))
1245 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_UL_LR, TRUE);
1246 else if (!g_strcmp0 ("flip-rotate-180", orientation))
1247 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_VERT, TRUE);
1248 else if (!g_strcmp0 ("flip-rotate-270", orientation))
1249 gst_video_flip_set_method (vf, GST_VIDEO_ORIENTATION_UR_LL, TRUE);
1251 g_free (orientation);
1258 ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
1264 gst_video_flip_set_property (GObject * object, guint prop_id,
1265 const GValue * value, GParamSpec * pspec)
1267 GstVideoFlip *videoflip = GST_VIDEO_FLIP (object);
1271 case PROP_VIDEO_DIRECTION:
1272 gst_video_flip_set_method (videoflip, g_value_get_enum (value), FALSE);
1275 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1281 gst_video_flip_get_property (GObject * object, guint prop_id, GValue * value,
1284 GstVideoFlip *videoflip = GST_VIDEO_FLIP (object);
1288 case PROP_VIDEO_DIRECTION:
1289 g_value_set_enum (value, videoflip->method);
1292 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1298 gst_video_flip_class_init (GstVideoFlipClass * klass)
1300 GObjectClass *gobject_class = (GObjectClass *) klass;
1301 GstElementClass *gstelement_class = (GstElementClass *) klass;
1302 GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
1303 GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;
1305 GST_DEBUG_CATEGORY_INIT (video_flip_debug, "videoflip", 0, "videoflip");
1307 gobject_class->set_property = gst_video_flip_set_property;
1308 gobject_class->get_property = gst_video_flip_get_property;
1310 g_object_class_install_property (gobject_class, PROP_METHOD,
1311 g_param_spec_enum ("method", "method",
1312 "method (deprecated, use video-direction instead)",
1313 GST_TYPE_VIDEO_FLIP_METHOD, PROP_METHOD_DEFAULT,
1314 GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
1315 G_PARAM_STATIC_STRINGS));
1316 g_object_class_override_property (gobject_class, PROP_VIDEO_DIRECTION,
1319 gst_element_class_set_static_metadata (gstelement_class, "Video flipper",
1320 "Filter/Effect/Video",
1321 "Flips and rotates video", "David Schleef <ds@schleef.org>");
1323 gst_element_class_add_static_pad_template (gstelement_class,
1324 &gst_video_flip_sink_template);
1325 gst_element_class_add_static_pad_template (gstelement_class,
1326 &gst_video_flip_src_template);
1328 trans_class->transform_caps =
1329 GST_DEBUG_FUNCPTR (gst_video_flip_transform_caps);
1330 trans_class->before_transform =
1331 GST_DEBUG_FUNCPTR (gst_video_flip_before_transform);
1332 trans_class->src_event = GST_DEBUG_FUNCPTR (gst_video_flip_src_event);
1333 trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_video_flip_sink_event);
1335 vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_flip_set_info);
1336 vfilter_class->transform_frame =
1337 GST_DEBUG_FUNCPTR (gst_video_flip_transform_frame);
1341 gst_video_flip_init (GstVideoFlip * videoflip)
1343 /* AUTO is not valid for active method, this is just to ensure we setup the
1344 * method in gst_video_flip_set_method() */
1345 videoflip->active_method = GST_VIDEO_ORIENTATION_AUTO;