2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
28 #include <videoflip.h>
31 #include "gstvideoflip.h"
33 static void gst_videoflip_planar411 (GstVideoflip * scale, unsigned char *dest,
36 static void gst_videoflip_flip (GstVideoflip * videoflip, unsigned char *dest,
37 unsigned char *src, int sw, int sh, int dw, int dh);
39 struct videoflip_format_struct videoflip_formats[] = {
41 {"YV12", 12, gst_videoflip_planar411,},
42 {"I420", 12, gst_videoflip_planar411,},
45 int videoflip_n_formats =
46 sizeof (videoflip_formats) / sizeof (videoflip_formats[0]);
49 videoflip_get_cap (struct videoflip_format_struct *format)
52 GstStructure *structure;
54 if (format->scale == NULL)
58 GST_MAKE_FOURCC (format->fourcc[0], format->fourcc[1], format->fourcc[2],
62 structure = gst_structure_new ("video/x-raw-rgb",
63 "depth", G_TYPE_INT, format->bpp,
64 "bpp", G_TYPE_INT, format->depth,
65 "endianness", G_TYPE_INT, format->endianness,
66 "red_mask", G_TYPE_INT, format->red_mask,
67 "green_mask", G_TYPE_INT, format->green_mask,
68 "blue_mask", G_TYPE_INT, format->blue_mask, NULL);
70 structure = gst_structure_new ("video/x-raw-yuv",
71 "format", GST_TYPE_FOURCC, fourcc, NULL);
77 struct videoflip_format_struct *
78 videoflip_find_by_caps (const GstCaps * caps)
82 GST_DEBUG ("finding %p", caps);
84 g_return_val_if_fail (caps != NULL, NULL);
86 for (i = 0; i < videoflip_n_formats; i++) {
89 c = gst_caps_new_full (videoflip_get_cap (videoflip_formats + i), NULL);
91 if (gst_caps_is_always_compatible (caps, c)) {
93 return videoflip_formats + i;
103 gst_videoflip_setup (GstVideoflip * videoflip)
105 if (videoflip->from_width == 0 || videoflip->from_height == 0) {
109 switch (videoflip->method) {
110 case GST_VIDEOFLIP_METHOD_90R:
111 case GST_VIDEOFLIP_METHOD_90L:
112 case GST_VIDEOFLIP_METHOD_TRANS:
113 case GST_VIDEOFLIP_METHOD_OTHER:
114 videoflip->to_height = videoflip->from_width;
115 videoflip->to_width = videoflip->from_height;
117 case GST_VIDEOFLIP_METHOD_IDENTITY:
118 case GST_VIDEOFLIP_METHOD_180:
119 case GST_VIDEOFLIP_METHOD_HORIZ:
120 case GST_VIDEOFLIP_METHOD_VERT:
121 videoflip->to_height = videoflip->from_height;
122 videoflip->to_width = videoflip->from_width;
129 GST_DEBUG ("format=%p \"%s\" from %dx%d to %dx%d",
130 videoflip->format, videoflip->format->fourcc,
131 videoflip->from_width, videoflip->from_height,
132 videoflip->to_width, videoflip->to_height);
134 if (videoflip->method == GST_VIDEOFLIP_METHOD_IDENTITY) {
135 GST_DEBUG ("videoflip: using passthru");
136 videoflip->passthru = TRUE;
137 videoflip->inited = TRUE;
141 videoflip->from_buf_size = (videoflip->from_width * videoflip->from_height
142 * videoflip->format->depth) / 8;
143 videoflip->to_buf_size = (videoflip->to_width * videoflip->to_height
144 * videoflip->format->depth) / 8;
146 videoflip->inited = TRUE;
150 gst_videoflip_planar411 (GstVideoflip * scale, unsigned char *dest,
153 int sw = scale->from_width;
154 int sh = scale->from_height;
155 int dw = scale->to_width;
156 int dh = scale->to_height;
158 GST_DEBUG ("videoflip: scaling planar 4:1:1 %dx%d to %dx%d", sw, sh, dw, dh);
160 gst_videoflip_flip (scale, dest, src, sw, sh, dw, dh);
170 gst_videoflip_flip (scale, dest, src, sw, sh, dw, dh);
175 gst_videoflip_flip (scale, dest, src, sw, sh, dw, dh);
179 gst_videoflip_flip (GstVideoflip * videoflip, unsigned char *dest,
180 unsigned char *src, int sw, int sh, int dw, int dh)
184 switch (videoflip->method) {
185 case GST_VIDEOFLIP_METHOD_90R:
186 for (y = 0; y < dh; y++) {
187 for (x = 0; x < dw; x++) {
188 dest[y * dw + x] = src[(sh - 1 - x) * sw + y];
192 case GST_VIDEOFLIP_METHOD_90L:
193 for (y = 0; y < dh; y++) {
194 for (x = 0; x < dw; x++) {
195 dest[y * dw + x] = src[x * sw + (sw - 1 - y)];
199 case GST_VIDEOFLIP_METHOD_180:
200 for (y = 0; y < dh; y++) {
201 for (x = 0; x < dw; x++) {
202 dest[y * dw + x] = src[(sh - 1 - y) * sw + (sw - 1 - x)];
206 case GST_VIDEOFLIP_METHOD_HORIZ:
207 for (y = 0; y < dh; y++) {
208 for (x = 0; x < dw; x++) {
209 dest[y * dw + x] = src[y * sw + (sw - 1 - x)];
213 case GST_VIDEOFLIP_METHOD_VERT:
214 for (y = 0; y < dh; y++) {
215 for (x = 0; x < dw; x++) {
216 dest[y * dw + x] = src[(sh - 1 - y) * sw + x];
220 case GST_VIDEOFLIP_METHOD_TRANS:
221 for (y = 0; y < dh; y++) {
222 for (x = 0; x < dw; x++) {
223 dest[y * dw + x] = src[x * sw + y];
227 case GST_VIDEOFLIP_METHOD_OTHER:
228 for (y = 0; y < dh; y++) {
229 for (x = 0; x < dw; x++) {
230 dest[y * dw + x] = src[(sh - 1 - x) * sw + (sw - 1 - y)];