diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/export/export_pcm.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/export/export_pcm.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/export/export_pcm.c b/debian/transcode/transcode-1.1.7/export/export_pcm.c new file mode 100644 index 00000000..2ed96fd1 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/export/export_pcm.c @@ -0,0 +1,293 @@ +/* + * export_pcm.c + * + * Copyright (C) Thomas Oestreich - May 2001 + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "transcode.h" +#include "avilib/avilib.h" +#include "libtc/libtc.h" + +#define MOD_NAME "export_pcm.so" +#define MOD_VERSION "v0.1.0 (2007-08-25)" +#define MOD_CODEC "(audio) PCM (non-interleaved)" + + +static int verbose_flag=TC_QUIET; +static int capability_flag=TC_CAP_PCM|TC_CAP_RGB|TC_CAP_YUV|TC_CAP_VID; + +#define MOD_PRE tc_pcm +#include "export_def.h" + +static struct wave_header rtf; +static int fd_r = -1, fd_l = -1, fd_c = -1; +static int fd_ls = -1, fd_rs = -1, fd_lfe = -1; + +typedef enum { + CHANNEL_CENTER = 1, + CHANNEL_STEREO = 2, + CHANNEL_FRONT = 4, + CHANNEL_LFE = 8 +} PCMChannels; + +static PCMChannels chan_settings[8] = { + 0, /* 0: nothing */ + CHANNEL_CENTER, /* 1: mono */ + CHANNEL_STEREO, /* 2: stereo */ + CHANNEL_STEREO|CHANNEL_CENTER, /* 3: 2.1 */ + CHANNEL_STEREO|CHANNEL_FRONT, /* 4: 2+2 */ + CHANNEL_STEREO|CHANNEL_FRONT|CHANNEL_CENTER, /* 5: 2+2+1 */ + CHANNEL_STEREO|CHANNEL_FRONT|CHANNEL_CENTER|CHANNEL_LFE, /* 6: 5.1 */ + 0, /* nothing */ +}; + +/* ------------------------------------------------------------ + * + * init codec + * + * ------------------------------------------------------------*/ + +MOD_init +{ + int rate; + + if (param->flag == TC_VIDEO) { + return TC_EXPORT_OK; + } + if (param->flag == TC_AUDIO) { + memset(&rtf, 0, sizeof(rtf)); + + strlcpy(rtf.riff.id, "RIFF", 4); + strlcpy(rtf.riff.wave_id, "WAVE", 4); + strlcpy(rtf.format.id, "fmt ", 4); + + rtf.format.len = sizeof(struct common_struct); + rtf.common.wFormatTag = CODEC_PCM; + + rate = (vob->mp3frequency != 0) ?vob->mp3frequency :vob->a_rate; + + rtf.common.dwSamplesPerSec = rate; + rtf.common.dwAvgBytesPerSec = vob->dm_chan * rate * vob->dm_bits/8; + rtf.common.wBitsPerSample = vob->dm_bits; + rtf.common.wBlockAlign = vob->dm_chan*vob->dm_bits/8; + + if(vob->dm_chan >= 1 && vob->dm_chan <= 6) { /* sanity check */ + rtf.common.wChannels=vob->dm_chan; + } else { + tc_log_error(MOD_NAME, "bad PCM channel number: %i", + vob->dm_chan); + return TC_EXPORT_ERROR; + } + if (!vob->a_codec_flag + || !rtf.common.dwSamplesPerSec + || !rtf.common.wBitsPerSample + || !rtf.common.wBlockAlign) { + tc_log_error(MOD_NAME, "cannot export PCM, invalid format " + "(no audio track at all?)"); + return TC_EXPORT_ERROR; + } + + rtf.riff.len = 0x7FFFFFFF; + rtf.data.len = 0x7FFFFFFF; + + strlcpy(rtf.data.id, "data",4); + + return TC_EXPORT_OK; + } + // invalid flag + return TC_EXPORT_ERROR; +} + +/* ------------------------------------------------------------ + * + * open outputfile + * + * ------------------------------------------------------------*/ + +/* XXX */ +#define FD_OPEN(fd) do { \ + fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, \ + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); \ + if (fd < 0) { \ + tc_log_error(MOD_NAME, "opening file: %s", strerror(errno)); \ + return TC_EXPORT_ERROR; \ + } \ +} while (0) + +MOD_open +{ + char fname[TC_BUF_LINE]; + int chan_flags = chan_settings[rtf.common.wChannels]; + + if (param->flag == TC_AUDIO) { + if (chan_flags & CHANNEL_LFE) { + tc_snprintf(fname, sizeof(fname), "%s_lfe.pcm", + vob->audio_out_file); + FD_OPEN(fd_lfe); + } + + if (chan_flags & CHANNEL_FRONT) { + tc_snprintf(fname, sizeof(fname), "%s_ls.pcm", + vob->audio_out_file); + FD_OPEN(fd_ls); + + tc_snprintf(fname, sizeof(fname), "%s_rs.pcm", + vob->audio_out_file); + FD_OPEN(fd_rs); + } + + if (chan_flags & CHANNEL_STEREO) { + tc_snprintf(fname, sizeof(fname), "%s_l.pcm", + vob->audio_out_file); + FD_OPEN(fd_l); + + tc_snprintf(fname, sizeof(fname), "%s_r.pcm", + vob->audio_out_file); + FD_OPEN(fd_r); + } + + if (chan_flags & CHANNEL_CENTER) { + tc_snprintf(fname, sizeof(fname), "%s_c.pcm", + vob->audio_out_file); + FD_OPEN(fd_c); + } + + return TC_EXPORT_OK; + } + + if (param->flag == TC_VIDEO) { + return TC_EXPORT_OK; + } + + // invalid flag + return TC_EXPORT_ERROR; +} + +/* ------------------------------------------------------------ + * + * encode and export + * + * ------------------------------------------------------------*/ + +#define FD_WRITE(fd, buf, size) do { \ + if(fd != -1 && tc_pwrite(fd, buf, size) != size) { \ + tc_log_error(MOD_NAME, "writing audio frame: %s", \ + strerror(errno)); \ + return TC_EXPORT_ERROR; \ + } \ +} while (0) + +MOD_encode +{ + if (param->flag == TC_VIDEO) { + return TC_EXPORT_OK; + } + if (param->flag == TC_AUDIO) { + int size = (int)(param->size/rtf.common.wChannels); + + switch (rtf.common.wChannels) { + case 6: + FD_WRITE(fd_rs, param->buffer + 5 * size, size); + FD_WRITE(fd_ls, param->buffer + 4 * size, size); + FD_WRITE(fd_r, param->buffer + 3 * size, size); + FD_WRITE(fd_c, param->buffer + 2 * size, size); + FD_WRITE(fd_l, param->buffer + size, size); + FD_WRITE(fd_lfe, param->buffer, size); + break; + + case 2: + FD_WRITE(fd_r, param->buffer + size, size); + FD_WRITE(fd_l, param->buffer, size); + break; + + case 1: + FD_WRITE(fd_c, param->buffer, size); + break; + } + + return TC_EXPORT_OK; + } + + // invalid flag + return TC_EXPORT_ERROR; +} + +/* ------------------------------------------------------------ + * + * close outputfiles + * + * ------------------------------------------------------------*/ + +#define FD_CLOSE(fd) do { \ + if (fd != -1) { \ + close(fd);\ + } \ +} while (0) + +MOD_close +{ + if (param->flag == TC_VIDEO) { + return TC_EXPORT_OK; + } + if (param->flag == TC_AUDIO) { + FD_CLOSE(fd_l); + FD_CLOSE(fd_c); + FD_CLOSE(fd_r); + FD_CLOSE(fd_ls); + FD_CLOSE(fd_rs); + FD_CLOSE(fd_lfe); + return TC_EXPORT_OK; + } + return TC_EXPORT_ERROR; +} + +/* ------------------------------------------------------------ + * + * stop encoder + * + * ------------------------------------------------------------*/ + +MOD_stop +{ + if (param->flag == TC_VIDEO) { + return TC_EXPORT_OK; + } + if (param->flag == TC_AUDIO) { + return TC_EXPORT_OK; + } + return TC_EXPORT_ERROR; +} + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ |
