mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
95c117cdb8
commit
aaacb7010f
3 changed files with 51 additions and 53 deletions
|
@ -38,23 +38,25 @@
|
||||||
#include "../codec.h"
|
#include "../codec.h"
|
||||||
#include "decomp.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[32] IBSS_ATTR;
|
||||||
int16_t predictor_coef_table_a[32] IBSS_ATTR;
|
int16_t predictor_coef_table_a[32] IBSS_ATTR;
|
||||||
int16_t predictor_coef_table_b[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)
|
void alac_set_info(alac_file *alac, char *inputbuffer)
|
||||||
{
|
{
|
||||||
char *ptr = inputbuffer;
|
unsigned char* ptr = (unsigned char*)inputbuffer;
|
||||||
ptr += 4; /* size */
|
ptr += 4; /* size */
|
||||||
ptr += 4; /* frma */
|
ptr += 4; /* frma */
|
||||||
ptr += 4; /* alac */
|
ptr += 4; /* alac */
|
||||||
|
@ -63,42 +65,22 @@ void alac_set_info(alac_file *alac, char *inputbuffer)
|
||||||
|
|
||||||
ptr += 4; /* 0 ? */
|
ptr += 4; /* 0 ? */
|
||||||
|
|
||||||
alac->setinfo_max_samples_per_frame = *(uint32_t*)ptr; /* buffer size / 2 ? */
|
alac->setinfo_max_samples_per_frame = get_uint32be(ptr); /* buffer size / 2 ? */
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
_Swap32(alac->setinfo_max_samples_per_frame);
|
|
||||||
#endif
|
|
||||||
ptr += 4;
|
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;
|
ptr += 1;
|
||||||
alac->setinfo_sample_size = *(uint8_t*)ptr;
|
alac->setinfo_80 = get_uint16be(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
|
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
alac->setinfo_82 = *(uint32_t*)ptr;
|
alac->setinfo_82 = get_uint32be(ptr);
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
_Swap32(alac->setinfo_82);
|
|
||||||
#endif
|
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
alac->setinfo_86 = *(uint32_t*)ptr;
|
alac->setinfo_86 = get_uint32be(ptr);
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
_Swap32(alac->setinfo_86);
|
|
||||||
#endif
|
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
alac->setinfo_8a_rate = *(uint32_t*)ptr;
|
alac->setinfo_8a_rate = get_uint32be(ptr);
|
||||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
|
||||||
_Swap32(alac->setinfo_8a_rate);
|
|
||||||
#endif
|
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,14 +150,15 @@ static bool read_chunk_esds(qtmovie_t *qtmovie, size_t chunk_len)
|
||||||
|
|
||||||
/* read length */
|
/* read length */
|
||||||
qtmovie->res->codecdata_len = mp4ff_read_mp4_descr_length(qtmovie->stream);
|
qtmovie->res->codecdata_len = mp4ff_read_mp4_descr_length(qtmovie->stream);
|
||||||
qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len);
|
if (qtmovie->res->codecdata_len > MAX_CODECDATA_SIZE)
|
||||||
if (qtmovie->res->codecdata)
|
|
||||||
{
|
{
|
||||||
stream_read(qtmovie->stream, qtmovie->res->codecdata_len, qtmovie->res->codecdata);
|
DEBUGF("codecdata too large (%d) in esds\n",
|
||||||
} else {
|
(int)qtmovie->res->codecdata_len);
|
||||||
qtmovie->res->codecdata_len = 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream_read(qtmovie->stream, qtmovie->res->codecdata_len, qtmovie->res->codecdata);
|
||||||
|
|
||||||
/* will skip the remainder of the atom */
|
/* will skip the remainder of the atom */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -225,19 +226,21 @@ static bool read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len)
|
||||||
|
|
||||||
/* 12 = audio format atom, 8 = padding */
|
/* 12 = audio format atom, 8 = padding */
|
||||||
qtmovie->res->codecdata_len = entry_remaining + 12 + 8;
|
qtmovie->res->codecdata_len = entry_remaining + 12 + 8;
|
||||||
qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len);
|
if (qtmovie->res->codecdata_len > MAX_CODECDATA_SIZE)
|
||||||
|
|
||||||
if (!qtmovie->res->codecdata)
|
|
||||||
{
|
{
|
||||||
DEBUGF("stsd too large\n");
|
DEBUGF("codecdata too large (%d) in stsd\n",
|
||||||
return false;
|
(int)qtmovie->res->codecdata_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len);
|
memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len);
|
||||||
/* audio format atom */
|
/* 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)[0] = 0x0c000000;
|
||||||
((unsigned int*)qtmovie->res->codecdata)[1] = MAKEFOURCC('a','m','r','f');
|
((unsigned int*)qtmovie->res->codecdata)[1] = MAKEFOURCC('a','m','r','f');
|
||||||
((unsigned int*)qtmovie->res->codecdata)[2] = MAKEFOURCC('c','a','l','a');
|
((unsigned int*)qtmovie->res->codecdata)[2] = MAKEFOURCC('c','a','l','a');
|
||||||
|
#endif
|
||||||
|
|
||||||
stream_read(qtmovie->stream,
|
stream_read(qtmovie->stream,
|
||||||
entry_remaining,
|
entry_remaining,
|
||||||
|
|
|
@ -23,6 +23,19 @@
|
||||||
#include <codecs.h>
|
#include <codecs.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/* 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 {
|
typedef struct {
|
||||||
struct codec_api* ci;
|
struct codec_api* ci;
|
||||||
int eof;
|
int eof;
|
||||||
|
@ -57,7 +70,7 @@ typedef struct
|
||||||
uint32_t num_sample_byte_sizes;
|
uint32_t num_sample_byte_sizes;
|
||||||
|
|
||||||
uint32_t codecdata_len;
|
uint32_t codecdata_len;
|
||||||
void *codecdata;
|
uint8_t codecdata[MAX_CODECDATA_SIZE];
|
||||||
|
|
||||||
int mdat_offset;
|
int mdat_offset;
|
||||||
uint32_t mdat_len;
|
uint32_t mdat_len;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue