/* -*- 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; }