summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/import/decode_mpeg2.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/decode_mpeg2.c')
-rw-r--r--debian/transcode/transcode-1.1.7/import/decode_mpeg2.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/decode_mpeg2.c b/debian/transcode/transcode-1.1.7/import/decode_mpeg2.c
new file mode 100644
index 00000000..4147ae9c
--- /dev/null
+++ b/debian/transcode/transcode-1.1.7/import/decode_mpeg2.c
@@ -0,0 +1,177 @@
+/*
+ * decode_mpeg2.c
+ *
+ * Copyright (C) Thomas Oestreich - June 2001
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of transcode, a video stream processing tool
+ *
+ * transcode 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, or (at your option)
+ * any later version.
+ *
+ * transcode 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 GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "transcode.h"
+#include "tcinfo.h"
+
+#include "ioaux.h"
+#include "tc.h"
+
+#include "libtc/libtc.h"
+
+#if defined(HAVE_LIBMPEG2) && defined(HAVE_LIBMPEG2CONVERT)
+
+#include <mpeg2dec/mpeg2.h>
+#include <mpeg2dec/mpeg2convert.h>
+
+#define BUFFER_SIZE 262144
+static uint8_t buffer[BUFFER_SIZE];
+
+/* ------------------------------------------------------------
+ * helper functions
+ * ------------------------------------------------------------*/
+
+typedef void (*WriteDataFn)(decode_t *decode, const mpeg2_info_t *info,
+ const mpeg2_sequence_t *sequence);
+
+static void show_accel(uint32_t mp_ac)
+{
+ tc_log_info(__FILE__, "libmpeg2 acceleration: %s",
+ (mp_ac & MPEG2_ACCEL_X86_3DNOW) ? "3dnow" :
+ (mp_ac & MPEG2_ACCEL_X86_MMXEXT) ? "mmxext" :
+ (mp_ac & MPEG2_ACCEL_X86_MMX) ? "mmx" :
+ "none (plain C)");
+}
+
+#define WRITE_DATA(PBUF, LEN, TAG) do { \
+ int ret = tc_pwrite(decode->fd_out, PBUF, LEN); \
+ if(LEN != ret) { \
+ tc_log_error(__FILE__, "failed to write %s data" \
+ " of frame (len=%i)", \
+ TAG, ret); \
+ import_exit(1); \
+ } \
+} while (0)
+
+
+static void write_rgb24(decode_t *decode, const mpeg2_info_t *info,
+ const mpeg2_sequence_t *sequence)
+{
+ int len = 0;
+ /* FIXME: move to libtc/tcframes routines? */
+
+ len = 3 * info->sequence->width * info->sequence->height;
+ WRITE_DATA(info->display_fbuf->buf[0], len, "RGB");
+}
+
+static void write_yuv420p(decode_t *decode, const mpeg2_info_t *info,
+ const mpeg2_sequence_t *sequence)
+{
+ static const char *plane_id[] = { "Y", "U", "V" };
+ int len = 0;
+ /* FIXME: move to libtc/tcframes routines? */
+
+ len = sequence->width * sequence->height;
+ WRITE_DATA(info->display_fbuf->buf[0], len, plane_id[0]);
+
+ len = sequence->chroma_width * sequence->chroma_height;
+ WRITE_DATA(info->display_fbuf->buf[1], len, plane_id[1]);
+ WRITE_DATA(info->display_fbuf->buf[2], len, plane_id[2]);
+}
+
+
+/* ------------------------------------------------------------
+ * decoder entry point
+ * ------------------------------------------------------------*/
+
+void decode_mpeg2(decode_t *decode)
+{
+ mpeg2dec_t *decoder = NULL;
+ const mpeg2_info_t *info = NULL;
+ const mpeg2_sequence_t *sequence = NULL;
+ mpeg2_state_t state;
+ size_t size;
+ uint32_t ac = 0;
+
+ WriteDataFn writer = write_yuv420p;
+ if (decode->format == TC_CODEC_RGB) {
+ tc_log_info(__FILE__, "using libmpeg2convert"
+ " RGB24 conversion");
+ writer = write_rgb24;
+ }
+
+ ac = mpeg2_accel(MPEG2_ACCEL_DETECT);
+ show_accel(ac);
+
+ decoder = mpeg2_init();
+ if (decoder == NULL) {
+ tc_log_error(__FILE__, "Could not allocate a decoder object.");
+ import_exit(1);
+ }
+ info = mpeg2_info(decoder);
+
+ size = (size_t)-1;
+ do {
+ state = mpeg2_parse(decoder);
+ sequence = info->sequence;
+ switch (state) {
+ case STATE_BUFFER:
+ size = tc_pread(decode->fd_in, buffer, BUFFER_SIZE);
+ mpeg2_buffer(decoder, buffer, buffer + size);
+ break;
+ case STATE_SEQUENCE:
+ if (decode->format == TC_CODEC_RGB) {
+ mpeg2_convert(decoder, mpeg2convert_rgb24, NULL);
+ }
+ break;
+ case STATE_SLICE:
+ case STATE_END:
+ case STATE_INVALID_END:
+ if (info->display_fbuf) {
+ writer(decode, info, sequence);
+ }
+ break;
+ default:
+ /* can't happen */
+ break;
+ }
+ } while (size);
+
+ mpeg2_close(decoder);
+ import_exit(0);
+}
+
+#else /* defined(HAVE_LIBMPEG2) && defined(HAVE_LIBMPEG2CONVERT) */
+
+void decode_mpeg2(decode_t *decode)
+{
+ tc_log_error(__FILE__, "No support for MPEG2 configured -- exiting");
+ import_exit(1);
+}
+
+
+#endif /* defined(HAVE_LIBMPEG2) && defined(HAVE_LIBMPEG2CONVERT) */
+
+
+/*************************************************************************/
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * c-file-offsets: ((case-label . *) (statement-case-intro . *))
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */