summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-12-01 01:01:35 +0000
committerDave Chapman <dave@dchapman.com>2007-12-01 01:01:35 +0000
commitaaacb7010fc247cfc9f16b2e3aee568f29089a22 (patch)
tree5270f80f3dbad56eba3a408bdc8b36ac7394722d
parent95c117cdb8b2db2e3b5520e9181443a7915463e7 (diff)
downloadrockbox-aaacb7010fc247cfc9f16b2e3aee568f29089a22.tar.gz
rockbox-aaacb7010fc247cfc9f16b2e3aee568f29089a22.zip
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
-rw-r--r--apps/codecs/libalac/alac.c66
-rw-r--r--apps/codecs/libm4a/demux.c23
-rw-r--r--apps/codecs/libm4a/m4a.h15
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 @@
38#include "../codec.h" 38#include "../codec.h"
39#include "decomp.h" 39#include "decomp.h"
40 40
41#define _Swap32(v) do { \
42 v = (((v) & 0x000000FF) << 0x18) | \
43 (((v) & 0x0000FF00) << 0x08) | \
44 (((v) & 0x00FF0000) >> 0x08) | \
45 (((v) & 0xFF000000) >> 0x18); } while(0)
46
47#define _Swap16(v) do { \
48 v = (((v) & 0x00FF) << 0x08) | \
49 (((v) & 0xFF00) >> 0x08); } while (0)
50
51int16_t predictor_coef_table[32] IBSS_ATTR; 41int16_t predictor_coef_table[32] IBSS_ATTR;
52int16_t predictor_coef_table_a[32] IBSS_ATTR; 42int16_t predictor_coef_table_a[32] IBSS_ATTR;
53int16_t predictor_coef_table_b[32] IBSS_ATTR; 43int16_t predictor_coef_table_b[32] IBSS_ATTR;
54 44
45
46/* Endian/aligment safe functions - only used in alac_set_info() */
47static uint32_t get_uint32be(unsigned char* p)
48{
49 return((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]);
50}
51
52static uint16_t get_uint16be(unsigned char* p)
53{
54 return((p[0]<<8) | p[1]);
55}
56
55void alac_set_info(alac_file *alac, char *inputbuffer) 57void alac_set_info(alac_file *alac, char *inputbuffer)
56{ 58{
57 char *ptr = inputbuffer; 59 unsigned char* ptr = (unsigned char*)inputbuffer;
58 ptr += 4; /* size */ 60 ptr += 4; /* size */
59 ptr += 4; /* frma */ 61 ptr += 4; /* frma */
60 ptr += 4; /* alac */ 62 ptr += 4; /* alac */
@@ -63,42 +65,22 @@ void alac_set_info(alac_file *alac, char *inputbuffer)
63 65
64 ptr += 4; /* 0 ? */ 66 ptr += 4; /* 0 ? */
65 67
66 alac->setinfo_max_samples_per_frame = *(uint32_t*)ptr; /* buffer size / 2 ? */ 68 alac->setinfo_max_samples_per_frame = get_uint32be(ptr); /* buffer size / 2 ? */
67#ifdef ROCKBOX_LITTLE_ENDIAN
68 _Swap32(alac->setinfo_max_samples_per_frame);
69#endif
70 ptr += 4; 69 ptr += 4;
71 alac->setinfo_7a = *(uint8_t*)ptr; 70 alac->setinfo_7a = *ptr++;
71 alac->setinfo_sample_size = *ptr++;
72 alac->setinfo_rice_historymult = *ptr++;
73 alac->setinfo_rice_initialhistory = *ptr++;
74 alac->setinfo_rice_kmodifier = *ptr++;
75 alac->setinfo_7f = *ptr++;
72 ptr += 1; 76 ptr += 1;
73 alac->setinfo_sample_size = *(uint8_t*)ptr; 77 alac->setinfo_80 = get_uint16be(ptr);
74 ptr += 1;
75 alac->setinfo_rice_historymult = *(uint8_t*)ptr;
76 ptr += 1;
77 alac->setinfo_rice_initialhistory = *(uint8_t*)ptr;
78 ptr += 1;
79 alac->setinfo_rice_kmodifier = *(uint8_t*)ptr;
80 ptr += 1;
81 alac->setinfo_7f = *(uint8_t*)ptr;
82 ptr += 1;
83 alac->setinfo_80 = *(uint16_t*)ptr;
84#ifdef ROCKBOX_LITTLE_ENDIAN
85 _Swap16(alac->setinfo_80);
86#endif
87 ptr += 2; 78 ptr += 2;
88 alac->setinfo_82 = *(uint32_t*)ptr; 79 alac->setinfo_82 = get_uint32be(ptr);
89#ifdef ROCKBOX_LITTLE_ENDIAN
90 _Swap32(alac->setinfo_82);
91#endif
92 ptr += 4; 80 ptr += 4;
93 alac->setinfo_86 = *(uint32_t*)ptr; 81 alac->setinfo_86 = get_uint32be(ptr);
94#ifdef ROCKBOX_LITTLE_ENDIAN
95 _Swap32(alac->setinfo_86);
96#endif
97 ptr += 4; 82 ptr += 4;
98 alac->setinfo_8a_rate = *(uint32_t*)ptr; 83 alac->setinfo_8a_rate = get_uint32be(ptr);
99#ifdef ROCKBOX_LITTLE_ENDIAN
100 _Swap32(alac->setinfo_8a_rate);
101#endif
102 ptr += 4; 84 ptr += 4;
103} 85}
104 86
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)
150 150
151 /* read length */ 151 /* read length */
152 qtmovie->res->codecdata_len = mp4ff_read_mp4_descr_length(qtmovie->stream); 152 qtmovie->res->codecdata_len = mp4ff_read_mp4_descr_length(qtmovie->stream);
153 qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len); 153 if (qtmovie->res->codecdata_len > MAX_CODECDATA_SIZE)
154 if (qtmovie->res->codecdata)
155 { 154 {
156 stream_read(qtmovie->stream, qtmovie->res->codecdata_len, qtmovie->res->codecdata); 155 DEBUGF("codecdata too large (%d) in esds\n",
157 } else { 156 (int)qtmovie->res->codecdata_len);
158 qtmovie->res->codecdata_len = 0; 157 return false;
159 } 158 }
160 159
160 stream_read(qtmovie->stream, qtmovie->res->codecdata_len, qtmovie->res->codecdata);
161
161 /* will skip the remainder of the atom */ 162 /* will skip the remainder of the atom */
162 return true; 163 return true;
163} 164}
@@ -225,19 +226,21 @@ static bool read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len)
225 226
226 /* 12 = audio format atom, 8 = padding */ 227 /* 12 = audio format atom, 8 = padding */
227 qtmovie->res->codecdata_len = entry_remaining + 12 + 8; 228 qtmovie->res->codecdata_len = entry_remaining + 12 + 8;
228 qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len); 229 if (qtmovie->res->codecdata_len > MAX_CODECDATA_SIZE)
229
230 if (!qtmovie->res->codecdata)
231 { 230 {
232 DEBUGF("stsd too large\n"); 231 DEBUGF("codecdata too large (%d) in stsd\n",
233 return false; 232 (int)qtmovie->res->codecdata_len);
234 } 233 }
235 234
236 memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len); 235 memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len);
237 /* audio format atom */ 236 /* audio format atom */
237#if 0
238 /* The ALAC decoder skips these bytes, so there is no need to store them,
239 and this code isn't endian/alignment safe */
238 ((unsigned int*)qtmovie->res->codecdata)[0] = 0x0c000000; 240 ((unsigned int*)qtmovie->res->codecdata)[0] = 0x0c000000;
239 ((unsigned int*)qtmovie->res->codecdata)[1] = MAKEFOURCC('a','m','r','f'); 241 ((unsigned int*)qtmovie->res->codecdata)[1] = MAKEFOURCC('a','m','r','f');
240 ((unsigned int*)qtmovie->res->codecdata)[2] = MAKEFOURCC('c','a','l','a'); 242 ((unsigned int*)qtmovie->res->codecdata)[2] = MAKEFOURCC('c','a','l','a');
243#endif
241 244
242 stream_read(qtmovie->stream, 245 stream_read(qtmovie->stream,
243 entry_remaining, 246 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 @@
23#include <codecs.h> 23#include <codecs.h>
24#include <inttypes.h> 24#include <inttypes.h>
25 25
26/* AAC codecdata appears to always be less than 8 bytes - see
27 AudioSpecificConfig2 in libfaad/mp4.c
28
29 ALAC codecdata appears to always be 44 bytes (see alac_set_info in
30 libalac/alac.c) but my test file contains 56 bytes.
31
32 So we go safe and round up to 64 bytes - if we find more than this,
33 we give an error (even though we could possibly continue), so we
34 can increase this buffer.
35*/
36
37#define MAX_CODECDATA_SIZE 64
38
26typedef struct { 39typedef struct {
27 struct codec_api* ci; 40 struct codec_api* ci;
28 int eof; 41 int eof;
@@ -57,7 +70,7 @@ typedef struct
57 uint32_t num_sample_byte_sizes; 70 uint32_t num_sample_byte_sizes;
58 71
59 uint32_t codecdata_len; 72 uint32_t codecdata_len;
60 void *codecdata; 73 uint8_t codecdata[MAX_CODECDATA_SIZE];
61 74
62 int mdat_offset; 75 int mdat_offset;
63 uint32_t mdat_len; 76 uint32_t mdat_len;