diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/encode/encode_faac.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/encode/encode_faac.c | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/encode/encode_faac.c b/debian/transcode/transcode-1.1.7/encode/encode_faac.c new file mode 100644 index 00000000..121175c1 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/encode/encode_faac.c @@ -0,0 +1,312 @@ +/* + * encode_faac.c - encode audio frames using FAAC + * Written by Andrew Church <achurch@achurch.org> + * + * This file is part of transcode, a video stream processing tool. + * transcode is free software, distributable under the terms of the GNU + * General Public License (version 2 or later). See the file COPYING + * for details. + */ + +#include "transcode.h" +#include "libtc/libtc.h" +#include "libtc/optstr.h" +#include "libtc/tcmodule-plugin.h" + +#include <faac.h> + +#define MOD_NAME "encode_faac.so" +#define MOD_VERSION "v0.1 (2006-10-11)" +#define MOD_CAP "Encodes audio to AAC using FAAC (currently BROKEN)" +#define MOD_AUTHOR "Andrew Church" + +#define MOD_FEATURES \ + TC_MODULE_FEATURE_ENCODE|TC_MODULE_FEATURE_AUDIO + +#define MOD_FLAGS \ + TC_MODULE_FLAG_RECONFIGURABLE + +/*************************************************************************/ + +/* Local data structure: */ + +typedef struct { + faacEncHandle handle; + unsigned long framesize; // samples per AAC frame + int bps; // bytes per sample + /* FAAC only takes complete frames as input, so we buffer as needed. */ + uint8_t *audiobuf; + int audiobuf_len; // in samples +} PrivateData; + +/*************************************************************************/ +/*************************************************************************/ + +/* Module interface routines and data. */ + +/*************************************************************************/ + +/** + * faacmod_init: Initialize this instance of the module. See + * tcmodule-data.h for function details. + */ + +static int faac_init(TCModuleInstance *self, uint32_t features) +{ + PrivateData *pd; + + TC_MODULE_SELF_CHECK(self, "init"); + TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features); + + self->userdata = pd = tc_malloc(sizeof(PrivateData)); + if (!pd) { + tc_log_error(MOD_NAME, "init: out of memory!"); + return TC_ERROR; + } + pd->handle = 0; + pd->audiobuf = NULL; + + /* FIXME: shouldn't this test a specific flag? */ + if (verbose) { + tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); + if (verbose & TC_INFO) { + char *id, *copyright; + faacEncGetVersion(&id, ©right); + tc_log_info(MOD_NAME, "Using FAAC %s", id); + } + } + return TC_OK; +} + +/*************************************************************************/ + +/** + * faac_configure: Configure this instance of the module. See + * tcmodule-data.h for function details. + */ + +static int faac_configure(TCModuleInstance *self, + const char *options, vob_t *vob) +{ + PrivateData *pd; + int samplerate = vob->mp3frequency ? vob->mp3frequency : vob->a_rate; + int ret; + unsigned long dummy; + faacEncConfiguration conf; + + TC_MODULE_SELF_CHECK(self, "configure"); + + pd = self->userdata; + + /* Save bytes per sample */ + pd->bps = (vob->dm_chan * vob->dm_bits) / 8; + + /* Create FAAC handle (freeing any old one that might be left over) */ + if (pd->handle) + faacEncClose(pd->handle); + pd->handle = faacEncOpen(samplerate, vob->dm_chan, &pd->framesize, &dummy); + if (!pd->handle) { + tc_log_error(MOD_NAME, "FAAC initialization failed"); + return TC_ERROR; + } + + /* Set up our default audio parameters */ + /* why can't just use a pointer here? -- FR */ + /* Because the function returns a pointer to an internal buffer --AC */ + conf = *faacEncGetCurrentConfiguration(pd->handle); + conf.mpegVersion = MPEG4; + conf.aacObjectType = MAIN; + conf.allowMidside = 1; + conf.useLfe = 0; + conf.useTns = 1; + conf.bitRate = vob->mp3bitrate / vob->dm_chan; + conf.bandWidth = 0; // automatic configuration + conf.quantqual = 100; // FIXME: quality should be a per-module setting + conf.outputFormat = 1; + if (vob->dm_bits != 16) { + tc_log_error(MOD_NAME, "Only 16-bit samples supported"); + return TC_ERROR; + } + conf.inputFormat = FAAC_INPUT_16BIT; + conf.shortctl = SHORTCTL_NORMAL; + + ret = optstr_get(options, "quality", "%li", &conf.quantqual); + if (ret >= 0) { + if (verbose >= TC_INFO) { + tc_log_info(MOD_NAME, "using quality=%li", conf.quantqual); + } + } + + if (!faacEncSetConfiguration(pd->handle, &conf)) { + tc_log_error(MOD_NAME, "Failed to set FAAC configuration"); + faacEncClose(pd->handle); + pd->handle = 0; + return TC_ERROR; + } + + /* Allocate local audio buffer */ + if (pd->audiobuf) + free(pd->audiobuf); + pd->audiobuf = tc_malloc(pd->framesize * pd->bps); + if (!pd->audiobuf) { + tc_log_error(MOD_NAME, "Unable to allocate audio buffer"); + faacEncClose(pd->handle); + pd->handle = 0; + return TC_ERROR; + } + + return TC_OK; +} + +/*************************************************************************/ + +/** + * faac_inspect: Return the value of an option in this instance of the + * module. See tcmodule-data.h for function details. + */ + +static int faac_inspect(TCModuleInstance *self, + const char *param, const char **value) +{ + static char buf[TC_BUF_MAX]; + + TC_MODULE_SELF_CHECK(self, "inspect"); + TC_MODULE_SELF_CHECK(param, "inspect"); + + if (optstr_lookup(param, "help")) { + tc_snprintf(buf, sizeof(buf), + "Overview:\n" + " Encodes audio to AAC using the FAAC library.\n" + "Options:\n" + " quality: set encoder quality [0-100]\n"); + *value = buf; + } + return TC_OK; +} + +/*************************************************************************/ + +/** + * faac_stop: Reset this instance of the module. See tcmodule-data.h for + * function details. + */ + +static int faac_stop(TCModuleInstance *self) +{ + PrivateData *pd; + + TC_MODULE_SELF_CHECK(self, "stop"); + + pd = self->userdata; + + if (pd->handle) { + faacEncClose(pd->handle); + pd->handle = NULL; + } + + return TC_OK; +} + +/*************************************************************************/ + +/** + * faac_fini: Clean up after this instance of the module. See + * tcmodule-data.h for function details. + */ + +static int faac_fini(TCModuleInstance *self) +{ + TC_MODULE_SELF_CHECK(self, "fini"); + + faac_stop(self); + tc_free(self->userdata); + self->userdata = NULL; + return TC_OK; +} + +/*************************************************************************/ + +/** + * faac_encode: Encode a frame of data. See tcmodule-data.h for + * function details. + */ + +static int faac_encode(TCModuleInstance *self, + aframe_list_t *in, aframe_list_t *out) +{ + PrivateData *pd; + uint8_t *inptr; + int nsamples; + + TC_MODULE_SELF_CHECK(self, "encode"); + + pd = self->userdata; + + if (in) { + inptr = in->audio_buf; + nsamples = in->audio_size / pd->bps; + } else { + inptr = NULL; + nsamples = 0; + } + out->audio_len = 0; + + while (pd->audiobuf_len + nsamples >= pd->framesize) { + int res; + const int tocopy = (pd->framesize - pd->audiobuf_len) * pd->bps; + ac_memcpy(pd->audiobuf + pd->audiobuf_len*pd->bps, inptr, tocopy); + inptr += tocopy; + nsamples -= tocopy / pd->bps; + pd->audiobuf_len = 0; + res = faacEncEncode(pd->handle, (int32_t *)pd->audiobuf, pd->framesize, + out->audio_buf + out->audio_len, + out->audio_size - out->audio_len); + if (res > out->audio_size - out->audio_len) { + tc_log_error(MOD_NAME, + "Output buffer overflow! Try a lower bitrate."); + return TC_ERROR; + } + out->audio_len += res; + } + + if (nsamples > 0) { + ac_memcpy(pd->audiobuf + pd->audiobuf_len*pd->bps, inptr, + nsamples*pd->bps); + pd->audiobuf_len += nsamples; + } + return TC_OK; +} + +/*************************************************************************/ + +static const TCCodecID faac_codecs_in[] = { TC_CODEC_PCM, TC_CODEC_ERROR }; +static const TCCodecID faac_codecs_out[] = { TC_CODEC_AAC, TC_CODEC_ERROR }; +TC_MODULE_CODEC_FORMATS(faac); + +TC_MODULE_INFO(faac); + +static const TCModuleClass faac_class = { + TC_MODULE_CLASS_HEAD(faac), + + .init = faac_init, + .fini = faac_fini, + .configure = faac_configure, + .stop = faac_stop, + .inspect = faac_inspect, + + .encode_audio = faac_encode, +}; + +TC_MODULE_ENTRY_POINT(faac); + +/*************************************************************************/ + +/* + * Local variables: + * c-file-style: "stroustrup" + * c-file-offsets: ((case-label . *) (statement-case-intro . *)) + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: + */ |
