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
31 * Flips and rotates video.
33 * ## Example launch line
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>
50 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
51 #include <gst/allocators/gsttizenbufferpool.h>
54 /* GstVideoFlip properties */
63 #define PROP_METHOD_DEFAULT GST_VIDEO_FLIP_METHOD_IDENTITY
64 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
65 #define TIZEN_BUFFER_POOL_MIN_BUFFERS 4
66 #define TIZEN_BUFFER_POOL_MAX_BUFFERS 10
69 GST_DEBUG_CATEGORY_STATIC (video_flip_debug);
70 #define GST_CAT_DEFAULT video_flip_debug
72 static GstStaticPadTemplate gst_video_flip_src_template =
73 GST_STATIC_PAD_TEMPLATE ("src",
76 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
77 "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, "
78 "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, "
79 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
82 "GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, "
83 "I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }"))
86 static GstStaticPadTemplate gst_video_flip_sink_template =
87 GST_STATIC_PAD_TEMPLATE ("sink",
90 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
91 "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, "
92 "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, "
93 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
96 "GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, "
97 "I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }"))
100 #define GST_TYPE_VIDEO_FLIP_METHOD (gst_video_flip_method_get_type())
102 static const GEnumValue video_flip_methods[] = {
103 {GST_VIDEO_FLIP_METHOD_IDENTITY, "Identity (no rotation)", "none"},
104 {GST_VIDEO_FLIP_METHOD_90R, "Rotate clockwise 90 degrees", "clockwise"},
105 {GST_VIDEO_FLIP_METHOD_180, "Rotate 180 degrees", "rotate-180"},
106 {GST_VIDEO_FLIP_METHOD_90L, "Rotate counter-clockwise 90 degrees",
108 {GST_VIDEO_FLIP_METHOD_HORIZ, "Flip horizontally", "horizontal-flip"},
109 {GST_VIDEO_FLIP_METHOD_VERT, "Flip vertically", "vertical-flip"},
110 {GST_VIDEO_FLIP_METHOD_TRANS,
111 "Flip across upper left/lower right diagonal", "upper-left-diagonal"},
112 {GST_VIDEO_FLIP_METHOD_OTHER,
113 "Flip across upper right/lower left diagonal", "upper-right-diagonal"},
114 {GST_VIDEO_FLIP_METHOD_AUTO,
115 "Select flip method based on image-orientation tag", "automatic"},
120 gst_video_flip_method_get_type (void)
122 static GType video_flip_method_type = 0;
124 if (!video_flip_method_type) {
125 video_flip_method_type = g_enum_register_static ("GstVideoFlipMethod",
128 return video_flip_method_type;
132 gst_video_flip_video_direction_interface_init (GstVideoDirectionInterface *
135 /* We implement the video-direction property */
138 #define gst_video_flip_parent_class parent_class
139 G_DEFINE_TYPE_WITH_CODE (GstVideoFlip, gst_video_flip, GST_TYPE_VIDEO_FILTER,
140 G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_DIRECTION,
141 gst_video_flip_video_direction_interface_init));
142 GST_ELEMENT_REGISTER_DEFINE (videoflip, "videoflip", GST_RANK_NONE,
143 GST_TYPE_VIDEO_FLIP);
146 gst_video_flip_transform_caps (GstBaseTransform * trans,
147 GstPadDirection direction, GstCaps * caps, GstCaps * filter)
149 GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
151 gint width, height, i;
153 ret = gst_caps_copy (caps);
155 GST_OBJECT_LOCK (videoflip);
157 if (videoflip->change_configuring_method) {
158 GEnumValue *configuring_method_enum, *method_enum;
159 GEnumClass *enum_class =
160 g_type_class_ref (GST_TYPE_VIDEO_ORIENTATION_METHOD);
162 configuring_method_enum =
163 g_enum_get_value (enum_class, videoflip->configuring_method);
164 method_enum = g_enum_get_value (enum_class, videoflip->proposed_method);
165 GST_LOG_OBJECT (videoflip,
166 "Changing configuring method from %s to proposed %s",
167 configuring_method_enum ? configuring_method_enum->value_nick : "(nil)",
168 method_enum ? method_enum->value_nick : "(nil)");
169 g_type_class_unref (enum_class);
171 videoflip->configuring_method = videoflip->proposed_method;
173 videoflip->change_configuring_method = FALSE;
175 for (i = 0; i < gst_caps_get_size (ret); i++) {
176 GstStructure *structure = gst_caps_get_structure (ret, i);
179 if (gst_structure_get_int (structure, "width", &width) &&
180 gst_structure_get_int (structure, "height", &height)) {
182 switch (videoflip->configuring_method) {
183 case GST_VIDEO_ORIENTATION_90R:
184 case GST_VIDEO_ORIENTATION_90L:
185 case GST_VIDEO_ORIENTATION_UL_LR:
186 case GST_VIDEO_ORIENTATION_UR_LL:
187 gst_structure_set (structure, "width", G_TYPE_INT, height,
188 "height", G_TYPE_INT, width, NULL);
189 if (gst_structure_get_fraction (structure, "pixel-aspect-ratio",
191 if (par_n != 1 || par_d != 1) {
194 g_value_init (&val, GST_TYPE_FRACTION);
195 gst_value_set_fraction (&val, par_d, par_n);
196 gst_structure_set_value (structure, "pixel-aspect-ratio", &val);
197 g_value_unset (&val);
201 case GST_VIDEO_ORIENTATION_IDENTITY:
202 case GST_VIDEO_ORIENTATION_180:
203 case GST_VIDEO_ORIENTATION_HORIZ:
204 case GST_VIDEO_ORIENTATION_VERT:
205 gst_structure_set (structure, "width", G_TYPE_INT, width,
206 "height", G_TYPE_INT, height, NULL);
208 case GST_VIDEO_ORIENTATION_CUSTOM:
209 GST_WARNING_OBJECT (videoflip, "unsupported custom orientation");
212 g_assert_not_reached ();
217 GST_OBJECT_UNLOCK (videoflip);
219 GST_DEBUG_OBJECT (videoflip, "transformed %" GST_PTR_FORMAT " to %"
220 GST_PTR_FORMAT, caps, ret);
223 GstCaps *intersection;
225 GST_DEBUG_OBJECT (videoflip, "Using filter caps %" GST_PTR_FORMAT, filter);
227 gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
228 gst_caps_unref (ret);
230 GST_DEBUG_OBJECT (videoflip, "Intersection %" GST_PTR_FORMAT, ret);
237 gst_video_flip_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest,
238 const GstVideoFrame * src)
243 gint src_y_stride, src_u_stride, src_v_stride;
244 gint src_y_height, src_u_height, src_v_height;
245 gint src_y_width, src_u_width, src_v_width;
246 gint dest_y_stride, dest_u_stride, dest_v_stride;
247 gint dest_y_height, dest_u_height, dest_v_height;
248 gint dest_y_width, dest_u_width, dest_v_width;
250 src_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
251 src_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 1);
252 src_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 2);
254 dest_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
255 dest_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 1);
256 dest_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 2);
258 src_y_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 0);
259 src_u_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 1);
260 src_v_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 2);
262 dest_y_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 0);
263 dest_u_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 1);
264 dest_v_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 2);
266 src_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 0);
267 src_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 1);
268 src_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 2);
270 dest_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 0);
271 dest_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 1);
272 dest_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 2);
274 switch (videoflip->active_method) {
275 case GST_VIDEO_ORIENTATION_90R:
277 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
278 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
279 for (y = 0; y < dest_y_height; y++) {
280 for (x = 0; x < dest_y_width; x++) {
281 d[y * dest_y_stride + x] =
282 s[(src_y_height - 1 - x) * src_y_stride + y];
286 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
287 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
288 for (y = 0; y < dest_u_height; y++) {
289 for (x = 0; x < dest_u_width; x++) {
290 d[y * dest_u_stride + x] =
291 s[(src_u_height - 1 - x) * src_u_stride + y];
295 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
296 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
297 for (y = 0; y < dest_v_height; y++) {
298 for (x = 0; x < dest_v_width; x++) {
299 d[y * dest_v_stride + x] =
300 s[(src_v_height - 1 - x) * src_v_stride + y];
304 case GST_VIDEO_ORIENTATION_90L:
306 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
307 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
308 for (y = 0; y < dest_y_height; y++) {
309 for (x = 0; x < dest_y_width; x++) {
310 d[y * dest_y_stride + x] =
311 s[x * src_y_stride + (src_y_width - 1 - y)];
315 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
316 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
317 for (y = 0; y < dest_u_height; y++) {
318 for (x = 0; x < dest_u_width; x++) {
319 d[y * dest_u_stride + x] =
320 s[x * src_u_stride + (src_u_width - 1 - y)];
324 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
325 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
326 for (y = 0; y < dest_v_height; y++) {
327 for (x = 0; x < dest_v_width; x++) {
328 d[y * dest_v_stride + x] =
329 s[x * src_v_stride + (src_v_width - 1 - y)];
333 case GST_VIDEO_ORIENTATION_180:
335 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
336 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
337 for (y = 0; y < dest_y_height; y++) {
338 for (x = 0; x < dest_y_width; x++) {
339 d[y * dest_y_stride + x] =
340 s[(src_y_height - 1 - y) * src_y_stride + (src_y_width - 1 - x)];
344 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
345 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
346 for (y = 0; y < dest_u_height; y++) {
347 for (x = 0; x < dest_u_width; x++) {
348 d[y * dest_u_stride + x] =
349 s[(src_u_height - 1 - y) * src_u_stride + (src_u_width - 1 - x)];
353 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
354 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
355 for (y = 0; y < dest_v_height; y++) {
356 for (x = 0; x < dest_v_width; x++) {
357 d[y * dest_v_stride + x] =
358 s[(src_v_height - 1 - y) * src_v_stride + (src_v_width - 1 - x)];
362 case GST_VIDEO_ORIENTATION_HORIZ:
364 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
365 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
366 for (y = 0; y < dest_y_height; y++) {
367 for (x = 0; x < dest_y_width; x++) {
368 d[y * dest_y_stride + x] =
369 s[y * src_y_stride + (src_y_width - 1 - x)];
373 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
374 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
375 for (y = 0; y < dest_u_height; y++) {
376 for (x = 0; x < dest_u_width; x++) {
377 d[y * dest_u_stride + x] =
378 s[y * src_u_stride + (src_u_width - 1 - x)];
382 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
383 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
384 for (y = 0; y < dest_v_height; y++) {
385 for (x = 0; x < dest_v_width; x++) {
386 d[y * dest_v_stride + x] =
387 s[y * src_v_stride + (src_v_width - 1 - x)];
391 case GST_VIDEO_ORIENTATION_VERT:
393 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
394 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
395 for (y = 0; y < dest_y_height; y++) {
396 for (x = 0; x < dest_y_width; x++) {
397 d[y * dest_y_stride + x] =
398 s[(src_y_height - 1 - y) * src_y_stride + x];
402 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
403 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
404 for (y = 0; y < dest_u_height; y++) {
405 for (x = 0; x < dest_u_width; x++) {
406 d[y * dest_u_stride + x] =
407 s[(src_u_height - 1 - y) * src_u_stride + x];
411 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
412 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
413 for (y = 0; y < dest_v_height; y++) {
414 for (x = 0; x < dest_v_width; x++) {
415 d[y * dest_v_stride + x] =
416 s[(src_v_height - 1 - y) * src_v_stride + x];
420 case GST_VIDEO_ORIENTATION_UL_LR:
422 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
423 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
424 for (y = 0; y < dest_y_height; y++) {
425 for (x = 0; x < dest_y_width; x++) {
426 d[y * dest_y_stride + x] = s[x * src_y_stride + y];
430 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
431 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
432 for (y = 0; y < dest_u_height; y++) {
433 for (x = 0; x < dest_u_width; x++) {
434 d[y * dest_u_stride + x] = s[x * src_u_stride + y];
438 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
439 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
440 for (y = 0; y < dest_v_height; y++) {
441 for (x = 0; x < dest_v_width; x++) {
442 d[y * dest_v_stride + x] = s[x * src_v_stride + y];
446 case GST_VIDEO_ORIENTATION_UR_LL:
448 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
449 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
450 for (y = 0; y < dest_y_height; y++) {
451 for (x = 0; x < dest_y_width; x++) {
452 d[y * dest_y_stride + x] =
453 s[(src_y_height - 1 - x) * src_y_stride + (src_y_width - 1 - y)];
457 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
458 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
459 for (y = 0; y < dest_u_height; y++) {
460 for (x = 0; x < dest_u_width; x++) {
461 d[y * dest_u_stride + x] =
462 s[(src_u_height - 1 - x) * src_u_stride + (src_u_width - 1 - y)];
466 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
467 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
468 for (y = 0; y < dest_v_height; y++) {
469 for (x = 0; x < dest_v_width; x++) {
470 d[y * dest_v_stride + x] =
471 s[(src_v_height - 1 - x) * src_v_stride + (src_v_width - 1 - y)];
475 case GST_VIDEO_ORIENTATION_IDENTITY:
476 gst_video_frame_copy (dest, src);
479 g_assert_not_reached ();
485 gst_video_flip_planar_yuv_16bit (GstVideoFlip * videoflip, GstVideoFrame * dest,
486 const GstVideoFrame * src)
491 gint src_y_stride, src_u_stride, src_v_stride;
492 gint src_y_height, src_u_height, src_v_height;
493 gint src_y_width, src_u_width, src_v_width;
494 gint dest_y_stride, dest_u_stride, dest_v_stride;
495 gint dest_y_height, dest_u_height, dest_v_height;
496 gint dest_y_width, dest_u_width, dest_v_width;
498 /* Divide strides by 2 because we're operating on guint16's */
499 src_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0) / 2;
500 src_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 1) / 2;
501 src_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 2) / 2;
503 dest_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0) / 2;
504 dest_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 1) / 2;
505 dest_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 2) / 2;
507 src_y_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 0);
508 src_u_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 1);
509 src_v_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 2);
511 dest_y_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 0);
512 dest_u_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 1);
513 dest_v_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 2);
515 src_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 0);
516 src_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 1);
517 src_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 2);
519 dest_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 0);
520 dest_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 1);
521 dest_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 2);
523 switch (videoflip->active_method) {
524 case GST_VIDEO_ORIENTATION_90R:
526 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
527 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
528 for (y = 0; y < dest_y_height; y++) {
529 for (x = 0; x < dest_y_width; x++) {
530 d[y * dest_y_stride + x] =
531 s[(src_y_height - 1 - x) * src_y_stride + y];
535 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
536 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
537 for (y = 0; y < dest_u_height; y++) {
538 for (x = 0; x < dest_u_width; x++) {
539 d[y * dest_u_stride + x] =
540 s[(src_u_height - 1 - x) * src_u_stride + y];
544 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
545 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
546 for (y = 0; y < dest_v_height; y++) {
547 for (x = 0; x < dest_v_width; x++) {
548 d[y * dest_v_stride + x] =
549 s[(src_v_height - 1 - x) * src_v_stride + y];
553 case GST_VIDEO_ORIENTATION_90L:
555 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
556 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
557 for (y = 0; y < dest_y_height; y++) {
558 for (x = 0; x < dest_y_width; x++) {
559 d[y * dest_y_stride + x] =
560 s[x * src_y_stride + (src_y_width - 1 - y)];
564 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
565 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
566 for (y = 0; y < dest_u_height; y++) {
567 for (x = 0; x < dest_u_width; x++) {
568 d[y * dest_u_stride + x] =
569 s[x * src_u_stride + (src_u_width - 1 - y)];
573 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
574 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
575 for (y = 0; y < dest_v_height; y++) {
576 for (x = 0; x < dest_v_width; x++) {
577 d[y * dest_v_stride + x] =
578 s[x * src_v_stride + (src_v_width - 1 - y)];
582 case GST_VIDEO_ORIENTATION_180:
584 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
585 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
586 for (y = 0; y < dest_y_height; y++) {
587 for (x = 0; x < dest_y_width; x++) {
588 d[y * dest_y_stride + x] =
589 s[(src_y_height - 1 - y) * src_y_stride + (src_y_width - 1 - x)];
593 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
594 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
595 for (y = 0; y < dest_u_height; y++) {
596 for (x = 0; x < dest_u_width; x++) {
597 d[y * dest_u_stride + x] =
598 s[(src_u_height - 1 - y) * src_u_stride + (src_u_width - 1 - x)];
602 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
603 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
604 for (y = 0; y < dest_v_height; y++) {
605 for (x = 0; x < dest_v_width; x++) {
606 d[y * dest_v_stride + x] =
607 s[(src_v_height - 1 - y) * src_v_stride + (src_v_width - 1 - x)];
611 case GST_VIDEO_ORIENTATION_HORIZ:
613 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
614 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
615 for (y = 0; y < dest_y_height; y++) {
616 for (x = 0; x < dest_y_width; x++) {
617 d[y * dest_y_stride + x] =
618 s[y * src_y_stride + (src_y_width - 1 - x)];
622 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
623 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
624 for (y = 0; y < dest_u_height; y++) {
625 for (x = 0; x < dest_u_width; x++) {
626 d[y * dest_u_stride + x] =
627 s[y * src_u_stride + (src_u_width - 1 - x)];
631 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
632 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
633 for (y = 0; y < dest_v_height; y++) {
634 for (x = 0; x < dest_v_width; x++) {
635 d[y * dest_v_stride + x] =
636 s[y * src_v_stride + (src_v_width - 1 - x)];
640 case GST_VIDEO_ORIENTATION_VERT:
642 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
643 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
644 for (y = 0; y < dest_y_height; y++) {
645 for (x = 0; x < dest_y_width; x++) {
646 d[y * dest_y_stride + x] =
647 s[(src_y_height - 1 - y) * src_y_stride + x];
651 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
652 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
653 for (y = 0; y < dest_u_height; y++) {
654 for (x = 0; x < dest_u_width; x++) {
655 d[y * dest_u_stride + x] =
656 s[(src_u_height - 1 - y) * src_u_stride + x];
660 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
661 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
662 for (y = 0; y < dest_v_height; y++) {
663 for (x = 0; x < dest_v_width; x++) {
664 d[y * dest_v_stride + x] =
665 s[(src_v_height - 1 - y) * src_v_stride + x];
669 case GST_VIDEO_ORIENTATION_UL_LR:
671 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
672 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
673 for (y = 0; y < dest_y_height; y++) {
674 for (x = 0; x < dest_y_width; x++) {
675 d[y * dest_y_stride + x] = s[x * src_y_stride + y];
679 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
680 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
681 for (y = 0; y < dest_u_height; y++) {
682 for (x = 0; x < dest_u_width; x++) {
683 d[y * dest_u_stride + x] = s[x * src_u_stride + y];
687 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
688 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
689 for (y = 0; y < dest_v_height; y++) {
690 for (x = 0; x < dest_v_width; x++) {
691 d[y * dest_v_stride + x] = s[x * src_v_stride + y];
695 case GST_VIDEO_ORIENTATION_UR_LL:
697 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
698 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
699 for (y = 0; y < dest_y_height; y++) {
700 for (x = 0; x < dest_y_width; x++) {
701 d[y * dest_y_stride + x] =
702 s[(src_y_height - 1 - x) * src_y_stride + (src_y_width - 1 - y)];
706 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
707 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
708 for (y = 0; y < dest_u_height; y++) {
709 for (x = 0; x < dest_u_width; x++) {
710 d[y * dest_u_stride + x] =
711 s[(src_u_height - 1 - x) * src_u_stride + (src_u_width - 1 - y)];
715 s = GST_VIDEO_FRAME_PLANE_DATA (src, 2);
716 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2);
717 for (y = 0; y < dest_v_height; y++) {
718 for (x = 0; x < dest_v_width; x++) {
719 d[y * dest_v_stride + x] =
720 s[(src_v_height - 1 - x) * src_v_stride + (src_v_width - 1 - y)];
724 case GST_VIDEO_ORIENTATION_IDENTITY:
725 gst_video_frame_copy (dest, src);
728 g_assert_not_reached ();
734 rotate_yuv422_plane (GstVideoFrame * dest, const GstVideoFrame * src,
735 gint plane_index, GstVideoOrientationMethod method,
736 gboolean is_chroma, gboolean is_le)
738 gint src_stride, src_height, src_width;
739 gint dest_stride, dest_height, dest_width;
742 guint16 const *s, *addr;
746 s = GST_VIDEO_FRAME_PLANE_DATA (src, plane_index);
747 d = GST_VIDEO_FRAME_PLANE_DATA (dest, plane_index);
749 /* Divide strides by 2 because we're operating on guint16's */
750 src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, plane_index) / 2;
751 src_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, plane_index);
752 src_width = GST_VIDEO_FRAME_COMP_WIDTH (src, plane_index);
754 dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, plane_index) / 2;
755 dest_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, plane_index);
756 dest_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, plane_index);
758 scale = is_chroma ? 2 : 1;
761 case GST_VIDEO_ORIENTATION_90R:
763 for (y = 0; y < dest_height; y++) {
764 for (x = 0; x < dest_width; x++) {
765 addr = s + (src_height - 1 - x * scale) * src_stride + y / scale;
766 val = GST_READ_UINT16_LE (addr);
768 if (is_chroma && x * 2 + 1 < src_height) {
769 addr = s + (src_height - 1 - (x * 2 + 1)) * src_stride + y / 2;
770 val2 = GST_READ_UINT16_LE (addr);
771 val = (val + val2) / 2;
774 GST_WRITE_UINT16_LE (d + y * dest_stride + x, val);
778 for (y = 0; y < dest_height; y++) {
779 for (x = 0; x < dest_width; x++) {
780 addr = s + (src_height - 1 - x * scale) * src_stride + y / scale;
781 val = GST_READ_UINT16_BE (addr);
783 if (is_chroma && x * 2 + 1 < src_height) {
784 addr = s + (src_height - 1 - (x * 2 + 1)) * src_stride + y / 2;
785 val2 = GST_READ_UINT16_BE (addr);
786 val = (val + val2) / 2;
789 GST_WRITE_UINT16_BE (d + y * dest_stride + x, val);
794 case GST_VIDEO_ORIENTATION_90L:
796 for (y = 0; y < dest_height; y++) {
797 for (x = 0; x < dest_width; x++) {
798 addr = s + x * scale * src_stride + (src_width - 1 - y / scale);
799 val = GST_READ_UINT16_LE (addr);
801 if (is_chroma && x * 2 + 1 < src_width) {
802 addr = s + (x * 2 + 1) * src_stride + (src_width - 1 - y / 2);
803 val2 = GST_READ_UINT16_LE (addr);
804 val = (val + val2) / 2;
807 GST_WRITE_UINT16_LE (d + y * dest_stride + x, val);
811 for (y = 0; y < dest_height; y++) {
812 for (x = 0; x < dest_width; x++) {
813 addr = s + x * scale * src_stride + (src_width - 1 - y / scale);
814 val = GST_READ_UINT16_BE (addr);
816 if (is_chroma && x * 2 + 1 < src_width) {
817 addr = s + (x * 2 + 1) * src_stride + (src_width - 1 - y / 2);
818 val2 = GST_READ_UINT16_BE (addr);
819 val = (val + val2) / 2;
822 GST_WRITE_UINT16_BE (d + y * dest_stride + x, val);
827 case GST_VIDEO_ORIENTATION_180:
828 for (y = 0; y < dest_height; y++) {
829 for (x = 0; x < dest_width; x++) {
830 d[y * dest_stride + x] =
831 s[(src_height - 1 - y) * src_stride + (src_width - 1 - x)];
835 case GST_VIDEO_ORIENTATION_HORIZ:
836 for (y = 0; y < dest_height; y++) {
837 for (x = 0; x < dest_width; x++) {
838 d[y * dest_stride + x] = s[y * src_stride + (src_width - 1 - x)];
842 case GST_VIDEO_ORIENTATION_VERT:
843 for (y = 0; y < dest_height; y++) {
844 for (x = 0; x < dest_width; x++) {
845 d[y * dest_stride + x] = s[(src_height - 1 - y) * src_stride + x];
849 case GST_VIDEO_ORIENTATION_UL_LR:
851 for (y = 0; y < dest_height; y++) {
852 for (x = 0; x < dest_width; x++) {
853 addr = s + x * scale * src_stride + y / scale;
854 val = GST_READ_UINT16_LE (addr);
856 if (is_chroma && x * 2 + 1 < src_width) {
857 addr = s + (x * 2 + 1) * src_stride + y / 2;
858 val2 = GST_READ_UINT16_LE (addr);
859 val = (val + val2) / 2;
862 GST_WRITE_UINT16_LE (d + y * dest_stride + x, val);
866 for (y = 0; y < dest_height; y++) {
867 for (x = 0; x < dest_width; x++) {
868 addr = s + x * scale * src_stride + y / scale;
869 val = GST_READ_UINT16_BE (addr);
871 if (is_chroma && x * 2 + 1 < src_width) {
872 addr = s + (x * 2 + 1) * src_stride + y / 2;
873 val2 = GST_READ_UINT16_BE (addr);
874 val = (val + val2) / 2;
877 GST_WRITE_UINT16_BE (d + y * dest_stride + x, val);
882 case GST_VIDEO_ORIENTATION_UR_LL:
884 for (y = 0; y < dest_height; y++) {
885 for (x = 0; x < dest_width; x++) {
887 + (src_height - 1 - x * scale) * src_stride
888 + (src_width - 1 - y / scale);
889 val = GST_READ_UINT16_LE (addr);
891 if (is_chroma && x * 2 + 1 < src_width) {
893 + (src_height - 1 - (x * 2 + 1)) * src_stride
894 + (src_width - 1 - y / 2);
895 val2 = GST_READ_UINT16_LE (addr);
896 val = (val + val2) / 2;
899 GST_WRITE_UINT16_LE (d + y * dest_stride + x, val);
903 for (y = 0; y < dest_height; y++) {
904 for (x = 0; x < dest_width; x++) {
906 + (src_height - 1 - x * scale) * src_stride
907 + (src_width - 1 - y / scale);
908 val = GST_READ_UINT16_BE (addr);
910 if (is_chroma && x * 2 + 1 < src_width) {
912 + (src_height - 1 - (x * 2 + 1)) * src_stride
913 + (src_width - 1 - y / 2);
914 val2 = GST_READ_UINT16_BE (addr);
915 val = (val + val2) / 2;
918 GST_WRITE_UINT16_BE (d + y * dest_stride + x, val);
923 case GST_VIDEO_ORIENTATION_IDENTITY:
924 gst_video_frame_copy (dest, src);
927 g_assert_not_reached ();
933 gst_video_flip_planar_yuv_422_16bit (GstVideoFlip * videoflip,
934 GstVideoFrame * dest, const GstVideoFrame * src)
936 gboolean format_is_le;
938 /* We need to consider the endianness during transforms
939 * which need average chrominance values between two pixels */
940 format_is_le = GST_VIDEO_FORMAT_INFO_IS_LE (dest->info.finfo);
942 /* Attempt to get the compiler to inline specialized variants of this function
943 * to avoid too much branching due to endianness checks */
945 rotate_yuv422_plane (dest, src, 0, videoflip->active_method, FALSE, TRUE);
946 rotate_yuv422_plane (dest, src, 1, videoflip->active_method, TRUE, TRUE);
947 rotate_yuv422_plane (dest, src, 2, videoflip->active_method, TRUE, TRUE);
949 rotate_yuv422_plane (dest, src, 0, videoflip->active_method, FALSE, FALSE);
950 rotate_yuv422_plane (dest, src, 1, videoflip->active_method, TRUE, FALSE);
951 rotate_yuv422_plane (dest, src, 2, videoflip->active_method, TRUE, FALSE);
956 gst_video_flip_semi_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest,
957 const GstVideoFrame * src)
963 gint src_y_stride, src_uv_stride;
964 gint src_y_height, src_uv_height;
965 gint src_y_width, src_uv_width;
966 gint dest_y_stride, dest_uv_stride;
967 gint dest_y_height, dest_uv_height;
968 gint dest_y_width, dest_uv_width;
971 src_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
972 src_uv_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 1);
974 dest_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
975 dest_uv_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 1);
977 src_y_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 0);
978 src_uv_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 1);
980 dest_y_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 0);
981 dest_uv_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 1);
983 src_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 0);
984 src_uv_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 1);
986 dest_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 0);
987 dest_uv_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 1);
989 switch (videoflip->active_method) {
990 case GST_VIDEO_ORIENTATION_90R:
992 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
993 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
994 for (y = 0; y < dest_y_height; y++) {
995 for (x = 0; x < dest_y_width; x++) {
996 d[y * dest_y_stride + x] =
997 s[(src_y_height - 1 - x) * src_y_stride + y];
1001 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1002 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1003 for (y = 0; y < dest_uv_height; y++) {
1004 for (x = 0; x < dest_uv_width; x++) {
1005 d_off = y * dest_uv_stride + x * 2;
1006 s_off = (src_uv_height - 1 - x) * src_uv_stride + y * 2;
1007 d[d_off] = s[s_off];
1008 d[d_off + 1] = s[s_off + 1];
1012 case GST_VIDEO_ORIENTATION_90L:
1014 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1015 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1016 for (y = 0; y < dest_y_height; y++) {
1017 for (x = 0; x < dest_y_width; x++) {
1018 d[y * dest_y_stride + x] =
1019 s[x * src_y_stride + (src_y_width - 1 - y)];
1023 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1024 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1025 for (y = 0; y < dest_uv_height; y++) {
1026 for (x = 0; x < dest_uv_width; x++) {
1027 d_off = y * dest_uv_stride + x * 2;
1028 s_off = x * src_uv_stride + (src_uv_width - 1 - y) * 2;
1029 d[d_off] = s[s_off];
1030 d[d_off + 1] = s[s_off + 1];
1034 case GST_VIDEO_ORIENTATION_180:
1036 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1037 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1038 for (y = 0; y < dest_y_height; y++) {
1039 for (x = 0; x < dest_y_width; x++) {
1040 d[y * dest_y_stride + x] =
1041 s[(src_y_height - 1 - y) * src_y_stride + (src_y_width - 1 - x)];
1045 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1046 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1047 for (y = 0; y < dest_uv_height; y++) {
1048 for (x = 0; x < dest_uv_width; x++) {
1049 d_off = y * dest_uv_stride + x * 2;
1050 s_off = (src_uv_height - 1 - y) * src_uv_stride + (src_uv_width - 1 -
1052 d[d_off] = s[s_off];
1053 d[d_off + 1] = s[s_off + 1];
1057 case GST_VIDEO_ORIENTATION_HORIZ:
1059 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1060 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1061 for (y = 0; y < dest_y_height; y++) {
1062 for (x = 0; x < dest_y_width; x++) {
1063 d[y * dest_y_stride + x] =
1064 s[y * src_y_stride + (src_y_width - 1 - x)];
1068 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1069 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1070 for (y = 0; y < dest_uv_height; y++) {
1071 for (x = 0; x < dest_uv_width; x++) {
1072 d_off = y * dest_uv_stride + x * 2;
1073 s_off = y * src_uv_stride + (src_uv_width - 1 - x) * 2;
1074 d[d_off] = s[s_off];
1075 d[d_off + 1] = s[s_off + 1];
1079 case GST_VIDEO_ORIENTATION_VERT:
1081 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1082 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1083 for (y = 0; y < dest_y_height; y++) {
1084 for (x = 0; x < dest_y_width; x++) {
1085 d[y * dest_y_stride + x] =
1086 s[(src_y_height - 1 - y) * src_y_stride + x];
1090 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1091 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1092 for (y = 0; y < dest_uv_height; y++) {
1093 for (x = 0; x < dest_uv_width; x++) {
1094 d_off = y * dest_uv_stride + x * 2;
1095 s_off = (src_uv_height - 1 - y) * src_uv_stride + x * 2;
1096 d[d_off] = s[s_off];
1097 d[d_off + 1] = s[s_off + 1];
1101 case GST_VIDEO_ORIENTATION_UL_LR:
1103 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1104 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1105 for (y = 0; y < dest_y_height; y++) {
1106 for (x = 0; x < dest_y_width; x++) {
1107 d[y * dest_y_stride + x] = s[x * src_y_stride + y];
1111 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1112 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1113 for (y = 0; y < dest_uv_height; y++) {
1114 for (x = 0; x < dest_uv_width; x++) {
1115 d_off = y * dest_uv_stride + x * 2;
1116 s_off = x * src_uv_stride + y * 2;
1117 d[d_off] = s[s_off];
1118 d[d_off + 1] = s[s_off + 1];
1122 case GST_VIDEO_ORIENTATION_UR_LL:
1124 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1125 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1126 for (y = 0; y < dest_y_height; y++) {
1127 for (x = 0; x < dest_y_width; x++) {
1128 d[y * dest_y_stride + x] =
1129 s[(src_y_height - 1 - x) * src_y_stride + (src_y_width - 1 - y)];
1133 s = GST_VIDEO_FRAME_PLANE_DATA (src, 1);
1134 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1);
1135 for (y = 0; y < dest_uv_height; y++) {
1136 for (x = 0; x < dest_uv_width; x++) {
1137 d_off = y * dest_uv_stride + x * 2;
1138 s_off = (src_uv_height - 1 - x) * src_uv_stride + (src_uv_width - 1 -
1140 d[d_off] = s[s_off];
1141 d[d_off + 1] = s[s_off + 1];
1145 case GST_VIDEO_ORIENTATION_IDENTITY:
1146 gst_video_frame_copy (dest, src);
1149 g_assert_not_reached ();
1155 gst_video_flip_packed_simple (GstVideoFlip * videoflip, GstVideoFrame * dest,
1156 const GstVideoFrame * src)
1161 gint sw = GST_VIDEO_FRAME_WIDTH (src);
1162 gint sh = GST_VIDEO_FRAME_HEIGHT (src);
1163 gint dw = GST_VIDEO_FRAME_WIDTH (dest);
1164 gint dh = GST_VIDEO_FRAME_HEIGHT (dest);
1165 gint src_stride, dest_stride;
1168 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1169 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1171 src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
1172 dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
1173 /* This is only true for non-subsampled formats! */
1174 bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (src, 0);
1176 switch (videoflip->active_method) {
1177 case GST_VIDEO_ORIENTATION_90R:
1178 for (y = 0; y < dh; y++) {
1179 for (x = 0; x < dw; x++) {
1180 for (z = 0; z < bpp; z++) {
1181 d[y * dest_stride + x * bpp + z] =
1182 s[(sh - 1 - x) * src_stride + y * bpp + z];
1187 case GST_VIDEO_ORIENTATION_90L:
1188 for (y = 0; y < dh; y++) {
1189 for (x = 0; x < dw; x++) {
1190 for (z = 0; z < bpp; z++) {
1191 d[y * dest_stride + x * bpp + z] =
1192 s[x * src_stride + (sw - 1 - y) * bpp + z];
1197 case GST_VIDEO_ORIENTATION_180:
1198 for (y = 0; y < dh; y++) {
1199 for (x = 0; x < dw; x++) {
1200 for (z = 0; z < bpp; z++) {
1201 d[y * dest_stride + x * bpp + z] =
1202 s[(sh - 1 - y) * src_stride + (sw - 1 - x) * bpp + z];
1207 case GST_VIDEO_ORIENTATION_HORIZ:
1208 for (y = 0; y < dh; y++) {
1209 for (x = 0; x < dw; x++) {
1210 for (z = 0; z < bpp; z++) {
1211 d[y * dest_stride + x * bpp + z] =
1212 s[y * src_stride + (sw - 1 - x) * bpp + z];
1217 case GST_VIDEO_ORIENTATION_VERT:
1218 for (y = 0; y < dh; y++) {
1219 for (x = 0; x < dw; x++) {
1220 for (z = 0; z < bpp; z++) {
1221 d[y * dest_stride + x * bpp + z] =
1222 s[(sh - 1 - y) * src_stride + x * bpp + z];
1227 case GST_VIDEO_ORIENTATION_UL_LR:
1228 for (y = 0; y < dh; y++) {
1229 for (x = 0; x < dw; x++) {
1230 for (z = 0; z < bpp; z++) {
1231 d[y * dest_stride + x * bpp + z] = s[x * src_stride + y * bpp + z];
1236 case GST_VIDEO_ORIENTATION_UR_LL:
1237 for (y = 0; y < dh; y++) {
1238 for (x = 0; x < dw; x++) {
1239 for (z = 0; z < bpp; z++) {
1240 d[y * dest_stride + x * bpp + z] =
1241 s[(sh - 1 - x) * src_stride + (sw - 1 - y) * bpp + z];
1246 case GST_VIDEO_ORIENTATION_IDENTITY:
1247 gst_video_frame_copy (dest, src);
1250 g_assert_not_reached ();
1256 gst_video_flip_y422 (GstVideoFlip * videoflip, GstVideoFrame * dest,
1257 const GstVideoFrame * src)
1262 gint sw = GST_VIDEO_FRAME_WIDTH (src);
1263 gint sh = GST_VIDEO_FRAME_HEIGHT (src);
1264 gint dw = GST_VIDEO_FRAME_WIDTH (dest);
1265 gint dh = GST_VIDEO_FRAME_HEIGHT (dest);
1266 gint src_stride, dest_stride;
1273 s = GST_VIDEO_FRAME_PLANE_DATA (src, 0);
1274 d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0);
1276 src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0);
1277 dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0);
1279 y_offset = GST_VIDEO_FRAME_COMP_OFFSET (src, 0);
1280 u_offset = GST_VIDEO_FRAME_COMP_OFFSET (src, 1);
1281 v_offset = GST_VIDEO_FRAME_COMP_OFFSET (src, 2);
1282 y_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (src, 0);
1285 switch (videoflip->active_method) {
1286 case GST_VIDEO_ORIENTATION_90R:
1287 for (y = 0; y < dh; y++) {
1288 for (x = 0; x < dw; x += 2) {
1291 /* u/v must be calculated using the offset of the even column */
1292 gint even_y = (y & ~1);
1294 u = s[(sh - 1 - x) * src_stride + even_y * bpp + u_offset];
1296 u = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + u_offset]
1298 v = s[(sh - 1 - x) * src_stride + even_y * bpp + v_offset];
1300 v = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + v_offset]
1303 d[y * dest_stride + x * bpp + u_offset] = u;
1304 d[y * dest_stride + x * bpp + v_offset] = v;
1305 d[y * dest_stride + x * bpp + y_offset] =
1306 s[(sh - 1 - x) * src_stride + y * bpp + y_offset];
1308 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1309 s[(sh - 1 - (x + 1)) * src_stride + y * bpp + y_offset];
1313 case GST_VIDEO_ORIENTATION_90L:
1314 for (y = 0; y < dh; y++) {
1315 for (x = 0; x < dw; x += 2) {
1318 /* u/v must be calculated using the offset of the even column */
1319 gint even_y = ((sw - 1 - y) & ~1);
1321 u = s[x * src_stride + even_y * bpp + u_offset];
1323 u = (s[(x + 1) * src_stride + even_y * bpp + u_offset] + u) >> 1;
1324 v = s[x * src_stride + even_y * bpp + v_offset];
1326 v = (s[(x + 1) * src_stride + even_y * bpp + v_offset] + v) >> 1;
1328 d[y * dest_stride + x * bpp + u_offset] = u;
1329 d[y * dest_stride + x * bpp + v_offset] = v;
1330 d[y * dest_stride + x * bpp + y_offset] =
1331 s[x * src_stride + (sw - 1 - y) * bpp + y_offset];
1333 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1334 s[(x + 1) * src_stride + (sw - 1 - y) * bpp + y_offset];
1338 case GST_VIDEO_ORIENTATION_180:
1339 for (y = 0; y < dh; y++) {
1340 for (x = 0; x < dw; x += 2) {
1343 /* u/v must be calculated using the offset of the even column */
1344 gint even_x = ((sw - 1 - x) & ~1);
1346 u = (s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset] +
1347 s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset]) / 2;
1348 v = (s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset] +
1349 s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset]) / 2;
1351 d[y * dest_stride + x * bpp + u_offset] = u;
1352 d[y * dest_stride + x * bpp + v_offset] = v;
1353 d[y * dest_stride + x * bpp + y_offset] =
1354 s[(sh - 1 - y) * src_stride + (sw - 1 - x) * bpp + y_offset];
1356 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1357 s[(sh - 1 - y) * src_stride + (sw - 1 - (x + 1)) * bpp +
1362 case GST_VIDEO_ORIENTATION_HORIZ:
1363 for (y = 0; y < dh; y++) {
1364 for (x = 0; x < dw; x += 2) {
1367 /* u/v must be calculated using the offset of the even column */
1368 gint even_x = ((sw - 1 - x) & ~1);
1370 u = (s[y * src_stride + even_x * bpp + u_offset] +
1371 s[y * src_stride + even_x * bpp + u_offset]) / 2;
1372 v = (s[y * src_stride + even_x * bpp + v_offset] +
1373 s[y * src_stride + even_x * bpp + v_offset]) / 2;
1375 d[y * dest_stride + x * bpp + u_offset] = u;
1376 d[y * dest_stride + x * bpp + v_offset] = v;
1377 d[y * dest_stride + x * bpp + y_offset] =
1378 s[y * src_stride + (sw - 1 - x) * bpp + y_offset];
1380 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1381 s[y * src_stride + (sw - 1 - (x + 1)) * bpp + y_offset];
1385 case GST_VIDEO_ORIENTATION_VERT:
1386 for (y = 0; y < dh; y++) {
1387 for (x = 0; x < dw; x += 2) {
1390 /* u/v must be calculated using the offset of the even column */
1391 gint even_x = (x & ~1);
1393 u = (s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset] +
1394 s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset]) / 2;
1395 v = (s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset] +
1396 s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset]) / 2;
1398 d[y * dest_stride + x * bpp + u_offset] = u;
1399 d[y * dest_stride + x * bpp + v_offset] = v;
1400 d[y * dest_stride + x * bpp + y_offset] =
1401 s[(sh - 1 - y) * src_stride + x * bpp + y_offset];
1403 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1404 s[(sh - 1 - y) * src_stride + (x + 1) * bpp + y_offset];
1408 case GST_VIDEO_ORIENTATION_UL_LR:
1409 for (y = 0; y < dh; y++) {
1410 for (x = 0; x < dw; x += 2) {
1413 /* u/v must be calculated using the offset of the even column */
1414 gint even_y = (y & ~1);
1416 u = s[x * src_stride + even_y * bpp + u_offset];
1418 u = (s[(x + 1) * src_stride + even_y * bpp + u_offset] + u) >> 1;
1419 v = s[x * src_stride + even_y * bpp + v_offset];
1421 v = (s[(x + 1) * src_stride + even_y * bpp + v_offset] + v) >> 1;
1423 d[y * dest_stride + x * bpp + u_offset] = u;
1424 d[y * dest_stride + x * bpp + v_offset] = v;
1425 d[y * dest_stride + x * bpp + y_offset] =
1426 s[x * src_stride + y * bpp + y_offset];
1428 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1429 s[(x + 1) * src_stride + y * bpp + y_offset];
1433 case GST_VIDEO_ORIENTATION_UR_LL:
1434 for (y = 0; y < dh; y++) {
1435 for (x = 0; x < dw; x += 2) {
1438 /* u/v must be calculated using the offset of the even column */
1439 gint even_y = ((sw - 1 - y) & ~1);
1441 u = s[(sh - 1 - x) * src_stride + even_y * bpp + u_offset];
1443 u = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + u_offset]
1445 v = s[(sh - 1 - x) * src_stride + even_y * bpp + v_offset];
1447 v = (s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + v_offset]
1450 d[y * dest_stride + x * bpp + u_offset] = u;
1451 d[y * dest_stride + x * bpp + v_offset] = v;
1452 d[y * dest_stride + x * bpp + y_offset] =
1453 s[(sh - 1 - x) * src_stride + (sw - 1 - y) * bpp + y_offset];
1455 d[y * dest_stride + (x + 1) * bpp + y_offset] =
1456 s[(sh - 1 - (x + 1)) * src_stride + (sw - 1 - y) * bpp +
1461 case GST_VIDEO_ORIENTATION_IDENTITY:
1462 gst_video_frame_copy (dest, src);
1465 g_assert_not_reached ();
1471 gst_video_flip_configure_process (GstVideoFlip * vf)
1473 switch (vf->v_format) {
1474 case GST_VIDEO_FORMAT_I420:
1475 case GST_VIDEO_FORMAT_YV12:
1476 case GST_VIDEO_FORMAT_Y444:
1477 vf->process = gst_video_flip_planar_yuv;
1479 case GST_VIDEO_FORMAT_I420_10LE:
1480 case GST_VIDEO_FORMAT_I420_10BE:
1481 case GST_VIDEO_FORMAT_I420_12LE:
1482 case GST_VIDEO_FORMAT_I420_12BE:
1483 case GST_VIDEO_FORMAT_Y444_10LE:
1484 case GST_VIDEO_FORMAT_Y444_10BE:
1485 case GST_VIDEO_FORMAT_Y444_12LE:
1486 case GST_VIDEO_FORMAT_Y444_12BE:
1487 vf->process = gst_video_flip_planar_yuv_16bit;
1489 case GST_VIDEO_FORMAT_I422_10LE:
1490 case GST_VIDEO_FORMAT_I422_10BE:
1491 case GST_VIDEO_FORMAT_I422_12LE:
1492 case GST_VIDEO_FORMAT_I422_12BE:
1493 vf->process = gst_video_flip_planar_yuv_422_16bit;
1495 case GST_VIDEO_FORMAT_YUY2:
1496 case GST_VIDEO_FORMAT_UYVY:
1497 case GST_VIDEO_FORMAT_YVYU:
1498 vf->process = gst_video_flip_y422;
1500 case GST_VIDEO_FORMAT_AYUV:
1501 case GST_VIDEO_FORMAT_ARGB:
1502 case GST_VIDEO_FORMAT_ABGR:
1503 case GST_VIDEO_FORMAT_RGBA:
1504 case GST_VIDEO_FORMAT_BGRA:
1505 case GST_VIDEO_FORMAT_xRGB:
1506 case GST_VIDEO_FORMAT_xBGR:
1507 case GST_VIDEO_FORMAT_RGBx:
1508 case GST_VIDEO_FORMAT_BGRx:
1509 case GST_VIDEO_FORMAT_RGB:
1510 case GST_VIDEO_FORMAT_BGR:
1511 case GST_VIDEO_FORMAT_GRAY8:
1512 case GST_VIDEO_FORMAT_GRAY16_BE:
1513 case GST_VIDEO_FORMAT_GRAY16_LE:
1514 vf->process = gst_video_flip_packed_simple;
1516 case GST_VIDEO_FORMAT_NV12:
1517 case GST_VIDEO_FORMAT_NV21:
1518 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
1519 case GST_VIDEO_FORMAT_SN12:
1521 vf->process = gst_video_flip_semi_planar_yuv;
1529 gst_video_flip_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
1530 GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
1532 GstVideoFlip *vf = GST_VIDEO_FLIP (vfilter);
1533 gboolean ret = FALSE, need_reconfigure = FALSE;
1537 if (GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_INFO_FORMAT (out_info))
1540 /* Check that they are correct */
1541 GST_OBJECT_LOCK (vf);
1542 switch (vf->configuring_method) {
1543 case GST_VIDEO_ORIENTATION_90R:
1544 case GST_VIDEO_ORIENTATION_90L:
1545 case GST_VIDEO_ORIENTATION_UL_LR:
1546 case GST_VIDEO_ORIENTATION_UR_LL:
1547 if ((in_info->width != out_info->height) ||
1548 (in_info->height != out_info->width)) {
1549 GST_ERROR_OBJECT (vf, "we are inverting width and height but caps "
1550 "are not correct : %dx%d to %dx%d", in_info->width,
1551 in_info->height, out_info->width, out_info->height);
1555 case GST_VIDEO_ORIENTATION_IDENTITY:
1556 case GST_VIDEO_ORIENTATION_180:
1557 case GST_VIDEO_ORIENTATION_HORIZ:
1558 case GST_VIDEO_ORIENTATION_VERT:
1559 if ((in_info->width != out_info->width) ||
1560 (in_info->height != out_info->height)) {
1561 GST_ERROR_OBJECT (vf, "we are keeping width and height but caps "
1562 "are not correct : %dx%d to %dx%d", in_info->width,
1563 in_info->height, out_info->width, out_info->height);
1568 g_assert_not_reached ();
1575 GEnumValue *active_method_enum, *method_enum;
1576 GEnumClass *enum_class =
1577 g_type_class_ref (GST_TYPE_VIDEO_ORIENTATION_METHOD);
1579 active_method_enum = g_enum_get_value (enum_class, vf->active_method);
1580 method_enum = g_enum_get_value (enum_class, vf->configuring_method);
1581 GST_LOG_OBJECT (vf, "Changing active method from %s to configuring %s",
1582 active_method_enum ? active_method_enum->value_nick : "(nil)",
1583 method_enum ? method_enum->value_nick : "(nil)");
1584 g_type_class_unref (enum_class);
1586 vf->active_method = vf->configuring_method;
1587 vf->change_configuring_method = TRUE;
1588 if (vf->active_method != vf->proposed_method)
1589 need_reconfigure = TRUE;
1591 vf->v_format = GST_VIDEO_INFO_FORMAT (in_info);
1592 gst_video_flip_configure_process (vf);
1595 GST_OBJECT_UNLOCK (vf);
1596 if (need_reconfigure) {
1597 gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (vf));
1600 return ret && (vf->process != NULL);
1603 GST_ERROR_OBJECT (vf, "Invalid caps: %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT,
1609 gst_video_flip_set_method (GstVideoFlip * videoflip,
1610 GstVideoOrientationMethod method, gboolean from_tag)
1612 GST_OBJECT_LOCK (videoflip);
1614 if (method == GST_VIDEO_ORIENTATION_CUSTOM) {
1615 GST_WARNING_OBJECT (videoflip, "unsupported custom orientation");
1616 GST_OBJECT_UNLOCK (videoflip);
1620 /* Store updated method */
1622 videoflip->tag_method = method;
1624 videoflip->method = method;
1626 /* Get the new method */
1627 if (videoflip->method == GST_VIDEO_ORIENTATION_AUTO)
1628 method = videoflip->tag_method;
1630 method = videoflip->method;
1632 if (method != videoflip->proposed_method) {
1633 GEnumValue *active_method_enum, *method_enum;
1634 GstBaseTransform *btrans = GST_BASE_TRANSFORM (videoflip);
1635 GEnumClass *enum_class =
1636 g_type_class_ref (GST_TYPE_VIDEO_ORIENTATION_METHOD);
1638 active_method_enum =
1639 g_enum_get_value (enum_class, videoflip->active_method);
1640 method_enum = g_enum_get_value (enum_class, method);
1641 GST_LOG_OBJECT (videoflip, "Changing method from %s to %s",
1642 active_method_enum ? active_method_enum->value_nick : "(nil)",
1643 method_enum ? method_enum->value_nick : "(nil)");
1644 g_type_class_unref (enum_class);
1646 videoflip->proposed_method = method;
1647 videoflip->change_configuring_method = TRUE;
1649 GST_OBJECT_UNLOCK (videoflip);
1651 gst_base_transform_set_passthrough (btrans,
1652 method == GST_VIDEO_ORIENTATION_IDENTITY);
1653 gst_base_transform_reconfigure_src (btrans);
1655 GST_OBJECT_UNLOCK (videoflip);
1660 gst_video_flip_before_transform (GstBaseTransform * trans, GstBuffer * in)
1662 GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
1663 GstClockTime timestamp, stream_time;
1665 timestamp = GST_BUFFER_TIMESTAMP (in);
1667 gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
1669 GST_DEBUG_OBJECT (videoflip, "sync to %" GST_TIME_FORMAT,
1670 GST_TIME_ARGS (timestamp));
1672 if (GST_CLOCK_TIME_IS_VALID (stream_time))
1673 gst_object_sync_values (GST_OBJECT (videoflip), stream_time);
1676 static GstFlowReturn
1677 gst_video_flip_transform_frame (GstVideoFilter * vfilter,
1678 GstVideoFrame * in_frame, GstVideoFrame * out_frame)
1680 GEnumClass *enum_class;
1681 GstVideoOrientationMethod active, proposed;
1682 GEnumValue *active_method_enum;
1683 GstVideoFlip *videoflip = GST_VIDEO_FLIP (vfilter);
1685 GST_OBJECT_LOCK (videoflip);
1686 if (G_UNLIKELY (videoflip->process == NULL))
1687 goto not_negotiated;
1689 if (videoflip->configuring_method != videoflip->active_method) {
1690 videoflip->active_method = videoflip->configuring_method;
1691 gst_video_flip_configure_process (videoflip);
1694 enum_class = g_type_class_ref (GST_TYPE_VIDEO_ORIENTATION_METHOD);
1695 active_method_enum = g_enum_get_value (enum_class, videoflip->active_method);
1696 GST_LOG_OBJECT (videoflip,
1697 "videoflip: flipping (%s), input %ux%u output %ux%u",
1698 active_method_enum ? active_method_enum->value_nick : "(nil)",
1699 GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame),
1700 GST_VIDEO_FRAME_WIDTH (out_frame), GST_VIDEO_FRAME_HEIGHT (out_frame));
1701 g_type_class_unref (enum_class);
1703 videoflip->process (videoflip, out_frame, in_frame);
1705 proposed = videoflip->proposed_method;
1706 active = videoflip->active_method;
1707 videoflip->change_configuring_method = TRUE;
1708 GST_OBJECT_UNLOCK (videoflip);
1710 if (proposed != active) {
1711 gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (videoflip),
1712 proposed == GST_VIDEO_ORIENTATION_IDENTITY);
1713 gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (videoflip));
1720 GST_OBJECT_UNLOCK (videoflip);
1721 GST_ERROR_OBJECT (videoflip, "Not negotiated yet");
1722 return GST_FLOW_NOT_NEGOTIATED;
1727 gst_video_flip_src_event (GstBaseTransform * trans, GstEvent * event)
1729 GstVideoFlip *vf = GST_VIDEO_FLIP (trans);
1730 gdouble new_x, new_y, x, y;
1732 GstVideoInfo *out_info = &GST_VIDEO_FILTER (trans)->out_info;
1734 GST_DEBUG_OBJECT (vf, "handling %s event", GST_EVENT_TYPE_NAME (event));
1736 switch (GST_EVENT_TYPE (event)) {
1737 case GST_EVENT_NAVIGATION:
1738 event = gst_event_make_writable (event);
1740 if (gst_navigation_event_get_coordinates (event, &x, &y)) {
1741 GST_DEBUG_OBJECT (vf, "converting %fx%f", x, y);
1742 GST_OBJECT_LOCK (vf);
1743 switch (vf->active_method) {
1744 case GST_VIDEO_ORIENTATION_90R:
1746 new_y = out_info->width - x;
1748 case GST_VIDEO_ORIENTATION_90L:
1749 new_x = out_info->height - y;
1752 case GST_VIDEO_ORIENTATION_UR_LL:
1753 new_x = out_info->height - y;
1754 new_y = out_info->width - x;
1756 case GST_VIDEO_ORIENTATION_UL_LR:
1760 case GST_VIDEO_ORIENTATION_180:
1761 new_x = out_info->width - x;
1762 new_y = out_info->height - y;
1764 case GST_VIDEO_ORIENTATION_HORIZ:
1765 new_x = out_info->width - x;
1768 case GST_VIDEO_ORIENTATION_VERT:
1770 new_y = out_info->height - y;
1777 GST_OBJECT_UNLOCK (vf);
1778 GST_DEBUG_OBJECT (vf, "to %fx%f", new_x, new_y);
1779 gst_navigation_event_set_coordinates (event, new_x, new_y);
1786 ret = GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans, event);
1792 gst_video_flip_sink_event (GstBaseTransform * trans, GstEvent * event)
1794 GstVideoFlip *vf = GST_VIDEO_FLIP (trans);
1795 GstTagList *taglist;
1796 GstVideoOrientationMethod method;
1799 GST_DEBUG_OBJECT (vf, "handling %s event", GST_EVENT_TYPE_NAME (event));
1801 switch (GST_EVENT_TYPE (event)) {
1803 gst_event_parse_tag (event, &taglist);
1805 if (gst_video_orientation_from_tag (taglist, &method)) {
1806 gst_video_flip_set_method (vf, method, TRUE);
1813 ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
1819 gst_video_flip_set_property (GObject * object, guint prop_id,
1820 const GValue * value, GParamSpec * pspec)
1822 GstVideoFlip *videoflip = GST_VIDEO_FLIP (object);
1826 case PROP_VIDEO_DIRECTION:
1827 gst_video_flip_set_method (videoflip, g_value_get_enum (value), FALSE);
1830 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1836 gst_video_flip_get_property (GObject * object, guint prop_id, GValue * value,
1839 GstVideoFlip *videoflip = GST_VIDEO_FLIP (object);
1843 case PROP_VIDEO_DIRECTION:
1844 g_value_set_enum (value, videoflip->method);
1847 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1852 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
1854 gst_video_flip_decide_allocation (GstBaseTransform * trans,
1857 GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
1858 GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
1860 GST_WARNING_OBJECT (videoflip, "format[%s]", filter->out_info.finfo->name);
1862 if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12) {
1864 GstStructure *config;
1865 GstCaps *caps = NULL;
1868 gst_query_parse_allocation (query, &caps, NULL);
1870 GST_WARNING_OBJECT (videoflip, "caps failed");
1874 gst_video_info_init (&vinfo);
1875 gst_video_info_from_caps (&vinfo, caps);
1879 videoflip->pool = gst_tizen_buffer_pool_new ();
1880 config = gst_buffer_pool_get_config (videoflip->pool);
1882 gst_buffer_pool_config_set_params (config, caps, size,
1883 TIZEN_BUFFER_POOL_MIN_BUFFERS, TIZEN_BUFFER_POOL_MAX_BUFFERS);
1884 gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
1885 gst_buffer_pool_set_config (videoflip->pool, config);
1887 if (!gst_buffer_pool_set_active (videoflip->pool, TRUE)) {
1888 gst_object_unref (videoflip->pool);
1889 videoflip->pool = NULL;
1890 GST_WARNING_OBJECT (videoflip, "Failed to activate pool");
1894 GST_WARNING_OBJECT (videoflip, "new buffer pool[%p]", videoflip->pool);
1897 return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query);
1900 static GstFlowReturn
1901 gst_video_flip_prepare_output_buffer (GstBaseTransform * trans,
1902 GstBuffer *input, GstBuffer **outbuf)
1904 GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
1905 GstBuffer *buf = NULL;
1907 if (!videoflip->pool)
1908 return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer (trans, input, outbuf);
1910 if (gst_buffer_pool_acquire_buffer (videoflip->pool, &buf, 0) != GST_FLOW_OK) {
1911 GST_ERROR_OBJECT (trans, "Buffer acquire failed");
1912 return GST_FLOW_ERROR;
1915 GST_DEBUG_OBJECT (videoflip, "acquired buffer[%p]", buf);
1918 GST_BASE_TRANSFORM_CLASS (parent_class)->copy_metadata (trans, input, buf);
1926 gst_video_flip_finalize (GstVideoFlip * videoflip)
1928 if (videoflip->pool) {
1929 GST_WARNING_OBJECT (videoflip, "free buffer pool[%p]", videoflip->pool);
1930 gst_buffer_pool_set_active (videoflip->pool, FALSE);
1931 gst_object_unref (videoflip->pool);
1932 videoflip->pool = NULL;
1935 G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (videoflip));
1940 gst_video_flip_class_init (GstVideoFlipClass * klass)
1942 GObjectClass *gobject_class = (GObjectClass *) klass;
1943 GstElementClass *gstelement_class = (GstElementClass *) klass;
1944 GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
1945 GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;
1948 GST_DEBUG_CATEGORY_INIT (video_flip_debug, "videoflip", 0, "videoflip");
1950 gobject_class->set_property = gst_video_flip_set_property;
1951 gobject_class->get_property = gst_video_flip_get_property;
1953 g_object_class_install_property (gobject_class, PROP_METHOD,
1954 g_param_spec_enum ("method", "method",
1955 "method (deprecated, use video-direction instead)",
1956 GST_TYPE_VIDEO_FLIP_METHOD, PROP_METHOD_DEFAULT,
1957 GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING |
1958 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
1959 g_object_class_override_property (gobject_class, PROP_VIDEO_DIRECTION,
1961 /* override the overriden property's flags to include the mutable in playing
1963 pspec = g_object_class_find_property (gobject_class, "video-direction");
1964 pspec->flags |= GST_PARAM_MUTABLE_PLAYING;
1966 gst_element_class_set_static_metadata (gstelement_class, "Video flipper",
1967 "Filter/Effect/Video",
1968 "Flips and rotates video", "David Schleef <ds@schleef.org>");
1970 gst_element_class_add_static_pad_template (gstelement_class,
1971 &gst_video_flip_sink_template);
1972 gst_element_class_add_static_pad_template (gstelement_class,
1973 &gst_video_flip_src_template);
1975 trans_class->transform_caps =
1976 GST_DEBUG_FUNCPTR (gst_video_flip_transform_caps);
1977 trans_class->before_transform =
1978 GST_DEBUG_FUNCPTR (gst_video_flip_before_transform);
1979 trans_class->src_event = GST_DEBUG_FUNCPTR (gst_video_flip_src_event);
1980 trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_video_flip_sink_event);
1982 vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_flip_set_info);
1983 vfilter_class->transform_frame =
1984 GST_DEBUG_FUNCPTR (gst_video_flip_transform_frame);
1985 #ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
1986 trans_class->decide_allocation = gst_video_flip_decide_allocation;
1987 trans_class->prepare_output_buffer = gst_video_flip_prepare_output_buffer;
1988 gobject_class->finalize = gst_video_flip_finalize;
1991 gst_type_mark_as_plugin_api (GST_TYPE_VIDEO_FLIP_METHOD, 0);
1995 gst_video_flip_init (GstVideoFlip * videoflip)
1997 /* AUTO is not valid for active method, this is just to ensure we setup the
1998 * method in gst_video_flip_set_method() */
1999 videoflip->active_method = GST_VIDEO_ORIENTATION_AUTO;
2000 videoflip->proposed_method = GST_VIDEO_ORIENTATION_IDENTITY;
2001 videoflip->configuring_method = GST_VIDEO_ORIENTATION_IDENTITY;