From aaacb7010fc247cfc9f16b2e3aee568f29089a22 Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Sat, 1 Dec 2007 01:01:35 +0000 Subject: Remove the mallocs for the codecdata in the m4a parser and assume a maximum size of 64 bytes (see comments in source). Also clean up the alac_set_info() function a little and make it alignment-safe. We still need to remove the seektable related mallocs. Please report if any AAC or ALAC files stop playing in Rockbox after this commit - but it is not expected to cause problems. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15861 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libalac/alac.c | 66 +++++++++++++++++----------------------------- apps/codecs/libm4a/demux.c | 23 +++++++++------- apps/codecs/libm4a/m4a.h | 15 ++++++++++- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/apps/codecs/libalac/alac.c b/apps/codecs/libalac/alac.c index f8e4df8b1d..d5d9be17f7 100644 --- a/apps/codecs/libalac/alac.c +++ b/apps/codecs/libalac/alac.c @@ -38,23 +38,25 @@ #include "../codec.h" #include "decomp.h" -#define _Swap32(v) do { \ - v = (((v) & 0x000000FF) << 0x18) | \ - (((v) & 0x0000FF00) << 0x08) | \ - (((v) & 0x00FF0000) >> 0x08) | \ - (((v) & 0xFF000000) >> 0x18); } while(0) - -#define _Swap16(v) do { \ - v = (((v) & 0x00FF) << 0x08) | \ - (((v) & 0xFF00) >> 0x08); } while (0) - int16_t predictor_coef_table[32] IBSS_ATTR; int16_t predictor_coef_table_a[32] IBSS_ATTR; int16_t predictor_coef_table_b[32] IBSS_ATTR; + +/* Endian/aligment safe functions - only used in alac_set_info() */ +static uint32_t get_uint32be(unsigned char* p) +{ + return((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]); +} + +static uint16_t get_uint16be(unsigned char* p) +{ + return((p[0]<<8) | p[1]); +} + void alac_set_info(alac_file *alac, char *inputbuffer) { - char *ptr = inputbuffer; + unsigned char* ptr = (unsigned char*)inputbuffer; ptr += 4; /* size */ ptr += 4; /* frma */ ptr += 4; /* alac */ @@ -63,42 +65,22 @@ void alac_set_info(alac_file *alac, char *inputbuffer) ptr += 4; /* 0 ? */ - alac->setinfo_max_samples_per_frame = *(uint32_t*)ptr; /* buffer size / 2 ? */ -#ifdef ROCKBOX_LITTLE_ENDIAN - _Swap32(alac->setinfo_max_samples_per_frame); -#endif + alac->setinfo_max_samples_per_frame = get_uint32be(ptr); /* buffer size / 2 ? */ ptr += 4; - alac->setinfo_7a = *(uint8_t*)ptr; + alac->setinfo_7a = *ptr++; + alac->setinfo_sample_size = *ptr++; + alac->setinfo_rice_historymult = *ptr++; + alac->setinfo_rice_initialhistory = *ptr++; + alac->setinfo_rice_kmodifier = *ptr++; + alac->setinfo_7f = *ptr++; ptr += 1; - alac->setinfo_sample_size = *(uint8_t*)ptr; - ptr += 1; - alac->setinfo_rice_historymult = *(uint8_t*)ptr; - ptr += 1; - alac->setinfo_rice_initialhistory = *(uint8_t*)ptr; - ptr += 1; - alac->setinfo_rice_kmodifier = *(uint8_t*)ptr; - ptr += 1; - alac->setinfo_7f = *(uint8_t*)ptr; - ptr += 1; - alac->setinfo_80 = *(uint16_t*)ptr; -#ifdef ROCKBOX_LITTLE_ENDIAN - _Swap16(alac->setinfo_80); -#endif + alac->setinfo_80 = get_uint16be(ptr); ptr += 2; - alac->setinfo_82 = *(uint32_t*)ptr; -#ifdef ROCKBOX_LITTLE_ENDIAN - _Swap32(alac->setinfo_82); -#endif + alac->setinfo_82 = get_uint32be(ptr); ptr += 4; - alac->setinfo_86 = *(uint32_t*)ptr; -#ifdef ROCKBOX_LITTLE_ENDIAN - _Swap32(alac->setinfo_86); -#endif + alac->setinfo_86 = get_uint32be(ptr); ptr += 4; - alac->setinfo_8a_rate = *(uint32_t*)ptr; -#ifdef ROCKBOX_LITTLE_ENDIAN - _Swap32(alac->setinfo_8a_rate); -#endif + alac->setinfo_8a_rate = get_uint32be(ptr); ptr += 4; } diff --git a/apps/codecs/libm4a/demux.c b/apps/codecs/libm4a/demux.c index 634bb4ffca..912e7327e7 100644 --- a/apps/codecs/libm4a/demux.c +++ b/apps/codecs/libm4a/demux.c @@ -150,14 +150,15 @@ static bool read_chunk_esds(qtmovie_t *qtmovie, size_t chunk_len) /* read length */ qtmovie->res->codecdata_len = mp4ff_read_mp4_descr_length(qtmovie->stream); - qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len); - if (qtmovie->res->codecdata) + if (qtmovie->res->codecdata_len > MAX_CODECDATA_SIZE) { - stream_read(qtmovie->stream, qtmovie->res->codecdata_len, qtmovie->res->codecdata); - } else { - qtmovie->res->codecdata_len = 0; + DEBUGF("codecdata too large (%d) in esds\n", + (int)qtmovie->res->codecdata_len); + return false; } + stream_read(qtmovie->stream, qtmovie->res->codecdata_len, qtmovie->res->codecdata); + /* will skip the remainder of the atom */ return true; } @@ -225,19 +226,21 @@ static bool read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len) /* 12 = audio format atom, 8 = padding */ qtmovie->res->codecdata_len = entry_remaining + 12 + 8; - qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len); - - if (!qtmovie->res->codecdata) + if (qtmovie->res->codecdata_len > MAX_CODECDATA_SIZE) { - DEBUGF("stsd too large\n"); - return false; + DEBUGF("codecdata too large (%d) in stsd\n", + (int)qtmovie->res->codecdata_len); } memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len); /* audio format atom */ +#if 0 + /* The ALAC decoder skips these bytes, so there is no need to store them, + and this code isn't endian/alignment safe */ ((unsigned int*)qtmovie->res->codecdata)[0] = 0x0c000000; ((unsigned int*)qtmovie->res->codecdata)[1] = MAKEFOURCC('a','m','r','f'); ((unsigned int*)qtmovie->res->codecdata)[2] = MAKEFOURCC('c','a','l','a'); +#endif stream_read(qtmovie->stream, entry_remaining, diff --git a/apps/codecs/libm4a/m4a.h b/apps/codecs/libm4a/m4a.h index 401cff3b7a..a4d4dc0f79 100644 --- a/apps/codecs/libm4a/m4a.h +++ b/apps/codecs/libm4a/m4a.h @@ -23,6 +23,19 @@ #include #include +/* AAC codecdata appears to always be less than 8 bytes - see + AudioSpecificConfig2 in libfaad/mp4.c + + ALAC codecdata appears to always be 44 bytes (see alac_set_info in + libalac/alac.c) but my test file contains 56 bytes. + + So we go safe and round up to 64 bytes - if we find more than this, + we give an error (even though we could possibly continue), so we + can increase this buffer. +*/ + +#define MAX_CODECDATA_SIZE 64 + typedef struct { struct codec_api* ci; int eof; @@ -57,7 +70,7 @@ typedef struct uint32_t num_sample_byte_sizes; uint32_t codecdata_len; - void *codecdata; + uint8_t codecdata[MAX_CODECDATA_SIZE]; int mdat_offset; uint32_t mdat_len; -- cgit v1.2.3