From fac1d658b59ee97cf5ea7e91df37b46e57aee59e Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 12 Mar 2007 22:33:34 +0100 Subject: [PATCH] aac_afh: use the file mapping rather than read() This simplifies this audio format handler quite a bit. Also fix a bug in error.h: E_AAC_OVERRUN is an error of the aac decoder, so move the corresponding define to where it belongs. --- aac_afh.c | 89 ++++++++++++++++--------------------------------------- error.h | 4 +-- 2 files changed, 27 insertions(+), 66 deletions(-) diff --git a/aac_afh.c b/aac_afh.c index f6b86981..17b72250 100644 --- a/aac_afh.c +++ b/aac_afh.c @@ -30,10 +30,7 @@ #include "aac.h" #include "fd.h" -/** size of the input buffer, must be big enough to hold header */ -#define AAC_INBUF_SIZE 65536 - -static int aac_find_stsz(unsigned char *buf, unsigned buflen, size_t *skip) +static int aac_find_stsz(unsigned char *buf, off_t buflen, off_t *skip) { int i; @@ -54,48 +51,32 @@ static int aac_find_stsz(unsigned char *buf, unsigned buflen, size_t *skip) *skip = i; return sample_count; } - PARA_WARNING_LOG("stsz not found, buflen: %d\n", buflen); return -E_STSZ; } -static int read_chunk_table(FILE *file, struct audio_format_info *afi, - unsigned char *inbuf, size_t inbuf_len, size_t skip) +static ssize_t aac_compute_chunk_table(struct audio_format_info *afi, + unsigned char *map, off_t numbytes) { int ret, i; size_t sum = 0; + off_t skip; - for (;;) { - ret = aac_find_stsz(inbuf, inbuf_len, &skip); - if (ret >= 0) - break; - ret = read(fileno(file), inbuf, AAC_INBUF_SIZE); - if (ret <= 0) - return -E_AAC_READ; - inbuf_len = ret; - PARA_INFO_LOG("next buffer: %d bytes\n", ret); - } + ret = aac_find_stsz(map, numbytes, &skip); + if (ret < 0) + return ret; afi->chunks_total = ret; PARA_INFO_LOG("sz table has %lu entries\n", afi->chunks_total); afi->chunk_table = para_malloc((afi->chunks_total + 1) * sizeof(size_t)); for (i = 1; i <= afi->chunks_total; i++) { - if (skip + 4 > inbuf_len) { - skip = inbuf_len - skip; - memmove(inbuf, inbuf + inbuf_len - skip, skip); - ret = read(fileno(file), inbuf + skip, - AAC_INBUF_SIZE - skip); - if (ret <= 0) - return -E_AAC_READ; - inbuf_len = ret + skip; - skip = 0; - PARA_INFO_LOG("next buffer: %zu bytes\n", inbuf_len); - } - sum += aac_read_int32(inbuf + skip); + if (skip + 4 > numbytes) + break; + sum += aac_read_int32(map + skip); afi->chunk_table[i] = sum; skip += 4; // if (i < 10 || i + 10 > afi->chunks_total) // PARA_DEBUG_LOG("offset #%d: %zu\n", i, afi->chunk_table[i]); } - return 1; + return skip; } static long unsigned aac_set_chunk_tv(struct audio_format_info *afi, @@ -116,54 +97,37 @@ static long unsigned aac_set_chunk_tv(struct audio_format_info *afi, /* * Init m4a file and write some tech data to given pointers. */ -static int aac_get_file_info(FILE *file, char *map, off_t numbytes, +static int aac_get_file_info(__a_unused FILE *file, char *map, off_t numbytes, struct audio_format_info *afi) { - int i, ret, decoder_len; - size_t inbuf_len, skip; - unsigned long rate = 0; - unsigned char channels = 0, *inbuf = para_malloc(AAC_INBUF_SIZE); + int i; + size_t skip; + ssize_t ret; + unsigned long rate = 0, decoder_len; + unsigned char channels = 0; mp4AudioSpecificConfig mp4ASC; NeAACDecHandle handle; - ret = read(fileno(file), inbuf, AAC_INBUF_SIZE); - if (ret <= 0) { - ret = -E_AAC_READ; - goto out; - } - inbuf_len = ret; - ret = aac_find_esds(inbuf, inbuf_len, &skip); + ret = aac_find_esds(map, numbytes, &skip); if (ret < 0) goto out; decoder_len = ret; handle = aac_open(); - ret = NeAACDecInit(handle, inbuf + skip, decoder_len, &rate, &channels); - if (ret < 0) { - ret = -E_AACDEC_INIT; + ret = -E_AACDEC_INIT; + if (NeAACDecInit(handle, map + skip, decoder_len, &rate, &channels)) goto out; - } - skip += ret; PARA_INFO_LOG("rate: %lu, channels: %d\n", rate, channels); ret = -E_MP4ASC; - if (NeAACDecAudioSpecificConfig(inbuf + skip, inbuf_len - skip, - &mp4ASC) < 0) + if (NeAACDecAudioSpecificConfig(map + skip, numbytes - skip, &mp4ASC)) goto out; - ret = read_chunk_table(file, afi, inbuf, inbuf_len, skip); + ret = aac_compute_chunk_table(afi, map, numbytes); if (ret < 0) goto out; + skip = ret; afi->seconds_total = aac_set_chunk_tv(afi, &mp4ASC); - for (;;) { - ret = aac_find_entry_point(inbuf, inbuf_len, &skip); - if (ret >= 0) - break; - ret = read(fileno(file), inbuf, AAC_INBUF_SIZE); - if (ret <= 0) { - ret = -E_AAC_READ; - goto out; - } - inbuf_len = ret; - PARA_INFO_LOG("next buffer: %d bytes\n", ret); - } + ret = aac_find_entry_point(map + skip, numbytes - skip, &skip); + if (ret < 0) + goto out; afi->chunk_table[0] = ret; for (i = 1; i<= afi->chunks_total; i++) afi->chunk_table[i] += ret; @@ -175,7 +139,6 @@ static int aac_get_file_info(FILE *file, char *map, off_t numbytes, tv_scale(20, &afi->chunk_tv, &afi->eof_tv); ret = 1; out: - free(inbuf); return ret; } diff --git a/error.h b/error.h index 45485e1d..d8c92293 100644 --- a/error.h +++ b/error.h @@ -274,11 +274,8 @@ extern const char **para_errlist[]; #define AAC_AFH_ERRORS \ - PARA_ERROR(AAC_REPOS, "aac repositioning error"), \ - PARA_ERROR(AAC_READ, "aac read error"), \ PARA_ERROR(STSZ, "did not find stcz atom"), \ PARA_ERROR(MP4ASC, "audio spec config error"), \ - PARA_ERROR(AAC_OVERRUN, "aac output buffer overrun"), \ #define AAC_COMMON_ERRORS \ @@ -447,6 +444,7 @@ extern const char **para_errlist[]; #define AACDEC_ERRORS \ PARA_ERROR(AACDEC_INIT, "failed to init aac decoder"), \ PARA_ERROR(AAC_DECODE, "aac decode error"), \ + PARA_ERROR(AAC_OVERRUN, "aac output buffer overrun"), \ /** -- 2.39.5