X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=aacdec_filter.c;h=95c13305519e39a86eff3cbe5cdf06b280ef8d04;hp=602df63ef7bd91520f426cbe35ea85cc7ae91fe0;hb=7e37a7cf49df279b9ab467fa4f62dd376c791a26;hpb=aa234b7afe223879a7bd7274ce05a3a315a2ec49 diff --git a/aacdec_filter.c b/aacdec_filter.c index 602df63e..95c13305 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Andre Noll + * Copyright (C) 2006-2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -23,10 +23,7 @@ #include "string.h" #include "aac.h" -/** the output buffer size */ -#define AAC_OUTBUF_SIZE (32 * 1024) - -/** give up decoding after that many errors */ +/** Give up decoding after that many errors. */ #define MAX_ERRORS 20 /** @@ -55,135 +52,15 @@ struct private_aacdec_data { /** The number of channels of the current stream. */ unsigned int channels; /** Current sample rate in Hz. */ - unsigned int samplerate; + unsigned int sample_rate; }; -static ssize_t aacdec(char *input_buffer, size_t len, struct filter_node *fn) -{ - struct private_aacdec_data *padd = fn->private_data; - struct filter_chain *fc = fn->fc; - int i, ret; - unsigned char *p, *outbuffer; - unsigned char *inbuf = (unsigned char*)input_buffer; - size_t skip, consumed = 0; - - if (fn->loaded > fn->bufsize * 3 / 5) - return 0; - ret = *fc->input_error; - if (ret < 0) - return ret; - if (len < 2048) - return 0; - - if (!padd->initialized) { - unsigned long rate = 0; - unsigned char channels = 0; - ret = aac_find_esds(inbuf, len, &skip, &padd->decoder_length); - if (ret < 0) { - PARA_INFO_LOG("%s\n", para_strerror(-ret)); - ret = NeAACDecInit(padd->handle, inbuf, - len, &rate, &channels); - PARA_INFO_LOG("decoder init: %d\n", ret); - if (ret < 0) { - ret = -E_AACDEC_INIT; - goto out; - } - consumed = ret; - } else { - PARA_INFO_LOG("decoder len: %lu\n", - padd->decoder_length); - consumed += skip; - p = inbuf + consumed; - ret = -E_AACDEC_INIT; - if (NeAACDecInit2(padd->handle, p, - padd->decoder_length, &rate, - &channels) < 0) - goto out; - } - fc->samplerate = rate; - fc->channels = channels; - PARA_INFO_LOG("rate: %u, channels: %d\n", - fc->samplerate, fc->channels); - padd->initialized = 1; - } - if (padd->decoder_length > 0) { - consumed = 0; - if (!padd->entry) { - ret = aac_find_entry_point(inbuf + consumed, - len - consumed, &skip); - if (ret < 0) { - ret = len; - goto out; - } - consumed += skip; - padd->entry = ret; - PARA_INFO_LOG("entry: %zu\n", padd->entry); - } - ret = len; - if (padd->consumed_total + len < padd->entry) - goto out; - if (padd->consumed_total < padd->entry) - consumed = padd->entry - padd->consumed_total; - } - for (; consumed < len; consumed++) - if ((inbuf[consumed] & 0xfe) == 0x20) - break; - if (consumed >= len) - goto success; - p = inbuf + consumed; - outbuffer = NeAACDecDecode(padd->handle, &padd->frame_info, p, - len - consumed); - if (padd->frame_info.error) { - ret = -E_AAC_DECODE; - if (padd->error_count++ > MAX_ERRORS) - goto out; - PARA_ERROR_LOG("frame_error: %d, consumed: %zu + %zd + %lu\n", - padd->frame_info.error, padd->consumed_total, - consumed, padd->frame_info.bytesconsumed); - PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage( - padd->frame_info.error)); - consumed++; /* catch 21 */ - goto success; - } - padd->error_count = 0; - consumed += padd->frame_info.bytesconsumed; - ret = consumed; - if (!padd->frame_info.samples) - goto out; - ret = -E_AAC_OVERRUN; - if (padd->frame_info.samples * 2 + fn->loaded > fn->bufsize) - goto out; - for (i = 0; i < padd->frame_info.samples; i++) { - short *s = (short *)outbuffer; - write_int16_host_endian(fn->buf + fn->loaded, s[i]); - fn->loaded += 2; - } -success: - ret = consumed; -out: - if (ret > 0) - padd->consumed_total += ret; - return ret; -} - static int aacdec_execute(struct btr_node *btrn, const char *cmd, char **result) { struct filter_node *fn = btr_context(btrn); struct private_aacdec_data *padd = fn->private_data; - if (!strcmp(cmd, "samplerate")) { - if (padd->samplerate == 0) - return -ERRNO_TO_PARA_ERROR(ENAVAIL); - *result = make_message("%u", padd->samplerate); - return 1; - } - if (!strcmp(cmd, "channels")) { - if (padd->channels == 0) - return -ERRNO_TO_PARA_ERROR(ENAVAIL); - *result = make_message("%u", padd->channels); - return 1; - } - return -ERRNO_TO_PARA_ERROR(ENOTSUP); + return decoder_execute(cmd, padd->sample_rate, padd->channels, result); } static void aacdec_open(struct filter_node *fn) @@ -191,8 +68,6 @@ static void aacdec_open(struct filter_node *fn) struct private_aacdec_data *padd = para_calloc(sizeof(*padd)); fn->private_data = padd; - fn->bufsize = AAC_OUTBUF_SIZE; - fn->buf = para_calloc(fn->bufsize); fn->min_iqs = 2048; padd->handle = aac_open(); } @@ -202,8 +77,6 @@ static void aacdec_close(struct filter_node *fn) struct private_aacdec_data *padd = fn->private_data; NeAACDecClose(padd->handle); - free(fn->buf); - fn->buf = NULL; free(padd); fn->private_data = NULL; } @@ -216,18 +89,19 @@ static void aacdec_post_select(__a_unused struct sched *s, struct task *t) int i, ret; unsigned char *p, *inbuf, *outbuffer; char *btr_buf; - size_t len, skip, consumed = 0, loaded, iqs; + size_t len, skip, consumed, loaded; next_buffer: t->error = 0; - ret = btr_node_status(btrn, fn->min_iqs); + ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL); if (ret < 0) goto err; if (ret == 0) return; btr_merge(btrn, fn->min_iqs); len = btr_next_buffer(btrn, (char **)&inbuf); - iqs = btr_get_input_queue_size(btrn); + len = PARA_MIN(len, (size_t)8192); + consumed = 0; if (!padd->initialized) { unsigned long rate = 0; unsigned char channels = 0; @@ -253,10 +127,10 @@ next_buffer: &channels) < 0) goto out; } - padd->samplerate = rate; + padd->sample_rate = rate; padd->channels = channels; PARA_INFO_LOG("rate: %u, channels: %d\n", - padd->samplerate, padd->channels); + padd->sample_rate, padd->channels); padd->initialized = 1; } if (padd->decoder_length > 0) { @@ -293,13 +167,17 @@ next_buffer: ret = -E_AAC_DECODE; if (padd->error_count++ > MAX_ERRORS) goto err; - PARA_ERROR_LOG("frame_error: %d (%s), consumed: %zu + %zd + %lu\n", - err, NeAACDecGetErrorMessage(padd->frame_info.error), + /* Suppress non-fatal bitstream error message at BOF/EOF */ + if (len < fn->min_iqs || padd->consumed_total == 0) { + consumed = len; + goto success; + } + PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage(err)); + PARA_ERROR_LOG("consumed: %zu + %zd + %lu\n", padd->consumed_total, consumed, padd->frame_info.bytesconsumed); - PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage( - padd->frame_info.error)); - consumed++; /* catch 21 */ + if (consumed < len) + consumed++; /* catch 21 */ goto success; } padd->error_count = 0; @@ -331,16 +209,15 @@ err: } /** - * the init function of the aacdec filter + * The init function of the aacdec filter. * - * \param f pointer to the filter struct to initialize + * \param f Pointer to the filter struct to initialize. * * \sa filter::init */ void aacdec_filter_init(struct filter *f) { f->open = aacdec_open; - f->convert = aacdec; f->close = aacdec_close; f->pre_select = generic_filter_pre_select; f->post_select = aacdec_post_select;