diff options
Diffstat (limited to 'lib/transcoder.cc')
-rw-r--r-- | lib/transcoder.cc | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/transcoder.cc b/lib/transcoder.cc new file mode 100644 index 0000000..edb4449 --- /dev/null +++ b/lib/transcoder.cc @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * transcoder.cc + * + * Wed Jul 19 22:11:02 CEST 2006 + * Copyright 2006 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of MIaV. + * + * MIaV is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MIaV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MIaV; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "transcoder.h" + +/* + R = Y + 1.4075 * (V - 128) + G = Y - (0.3455 * (U - 128) - (0.7169 * (V - 128)) + B = Y + 1.7790 * (U - 128) +*/ +#define RED(y, u, v) (y + 1.4075 * (v - 128)) +#define GREEN(y, u, v) (y - (0.3455 * (u - 128)) - (0.7169 * (v - 128))) +#define BLUE(y, u, v) (y + 1.7790 * (u - 128)) + +/* + R = 1.164(Y - 16) + 1.596(V - 128) + G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) + B = 1.164(Y - 16) + 2.018(U - 128) +*/ +//#define RED(y, u, v) (1.164 * (y - 16) + 1.596 * (v - 128)) +//#define GREEN(y, u, v) (1.164 * (y - 16) - 0.813 * (v - 128) - 0.391 * (u - 128)) +//#define BLUE(y, u, v) (1.164 * (y - 16) + 2.018 * (u - 128)) +static Frame *transcode_yuv2brg0(Frame *input, char* rgb, int bufsz) +{ + if(!rgb) { // No buffer supplied, creating one. + rgb = new char[720 * 576 * 4]; + bufsz = 720 * 576 * 4; + } + if(bufsz < 720 * 576 * 4) return NULL; // Buffer is too small. + + unsigned char Y0, Y1, U, V; + + unsigned int byte = 0; + unsigned int pos = 0; + + char *pframe = input->vframe; + + while(pos < 720*576*4) { + // YUV 4:2:2 packing + // Y0 U0 Y1 V1 Y2 U2 Y3 V3 + // [Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3] + + Y0 = pframe[byte]; byte++; + U = pframe[byte]; byte++; + Y1 = pframe[byte]; byte++; + V = pframe[byte]; byte++; + + rgb[pos+3] = 0; // Alpha + rgb[pos+2] = (unsigned char)RED(Y0, U, V); // Red + rgb[pos+1] = (unsigned char)GREEN(Y0, U, V); // Green + rgb[pos+0] = (unsigned char)BLUE(Y0, U, V); // Blue + pos+=4; + + rgb[pos+3] = 0; // Alpha + rgb[pos+2] = (unsigned char)RED(Y1, U, V); // Red + rgb[pos+1] = (unsigned char)GREEN(Y1, U, V); // Green + rgb[pos+0] = (unsigned char)BLUE(Y1, U, V); // Blue + pos+=4; + } + + return new Frame(rgb, bufsz, VF_BRG0, NULL, 0, AF_NONE); +} + + +Frame *transcode(Frame *input, + video_format_t vformat, char *vbuffer, int vbuffer_size, + audio_format_t aformat, char *abuffer, int abuffer_size) +{ + + // YUV422 => BRG0 + if(vformat == VF_BRG0 && input->vformat == VF_YUV422 && + aformat == AF_NONE && abuffer == NULL) + return transcode_yuv2brg0(input, vbuffer, vbuffer_size); + + // Unknown transcoding! + return NULL; +} |