summaryrefslogtreecommitdiff
path: root/lib/transcoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/transcoder.cc')
-rw-r--r--lib/transcoder.cc100
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;
+}