summaryrefslogtreecommitdiffstats
path: root/libfaad2
diff options
context:
space:
mode:
authornicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2>2008-01-26 18:31:48 +0000
committernicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2>2008-01-26 18:31:48 +0000
commit46cfd2988bb1fe6cd26aced8ab8af4c7a7c5ca2a (patch)
tree715f13eef678048014cff9bdc3a120fc368a32a7 /libfaad2
parent715cd43c17efa6368d5a5755919a78d5ab193e37 (diff)
downloadmpv-46cfd2988bb1fe6cd26aced8ab8af4c7a7c5ca2a.tar.bz2
mpv-46cfd2988bb1fe6cd26aced8ab8af4c7a7c5ca2a.tar.xz
generic functions and structures to parse and statekeep LATM streams
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@25862 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libfaad2')
-rw-r--r--libfaad2/neaacdec.h1
-rw-r--r--libfaad2/structs.h19
-rw-r--r--libfaad2/syntax.c185
-rw-r--r--libfaad2/syntax.h2
4 files changed, 207 insertions, 0 deletions
diff --git a/libfaad2/neaacdec.h b/libfaad2/neaacdec.h
index 347732d7d4..e0c10b66c5 100644
--- a/libfaad2/neaacdec.h
+++ b/libfaad2/neaacdec.h
@@ -83,6 +83,7 @@ extern "C" {
#define RAW 0
#define ADIF 1
#define ADTS 2
+#define LATM 3
/* SBR signalling */
#define NO_SBR 0
diff --git a/libfaad2/structs.h b/libfaad2/structs.h
index a624b5f03a..8f25298e70 100644
--- a/libfaad2/structs.h
+++ b/libfaad2/structs.h
@@ -330,6 +330,23 @@ typedef struct mp4AudioSpecificConfig
/*uint8_t*/ char downSampledSBR;
} mp4AudioSpecificConfig;
+#define MAX_ASC_BYTES 64
+typedef struct {
+ int inited;
+ int version, versionA;
+ int framelen_type;
+ int useSameStreamMux;
+ int allStreamsSameTimeFraming;
+ int numSubFrames;
+ int numPrograms;
+ int numLayers;
+ int otherDataPresent;
+ uint32_t otherDataLenBits;
+ uint32_t frameLength;
+ uint8_t ASC[MAX_ASC_BYTES];
+ uint32_t ASCbits;
+} latm_header;
+
typedef struct NeAACDecConfiguration
{
/*uint8_t*/ unsigned char defObjectType;
@@ -372,6 +389,7 @@ typedef struct
{
uint8_t adts_header_present;
uint8_t adif_header_present;
+ uint8_t latm_header_present;
uint8_t sf_index;
uint8_t object_type;
uint8_t channelConfiguration;
@@ -463,6 +481,7 @@ typedef struct
int64_t scalefac_cycles;
int64_t requant_cycles;
#endif
+ latm_header latm_config;
} NeAACDecStruct, *NeAACDecHandle;
diff --git a/libfaad2/syntax.c b/libfaad2/syntax.c
index 70efafd424..52a08f25b7 100644
--- a/libfaad2/syntax.c
+++ b/libfaad2/syntax.c
@@ -2329,3 +2329,188 @@ static void adts_error_check(adts_header *adts, bitfile *ld)
DEBUGVAR(1,134,"adts_error_check(): crc_check"));
}
}
+
+/* LATM parsing functions */
+
+static uint32_t latm_get_value(bitfile *ld)
+{
+ uint32_t l, value;
+ uint8_t bytesForValue;
+
+ bytesForValue = (uint8_t)faad_getbits(ld, 2);
+ value = 0;
+ for(l=0; l<bytesForValue; l++)
+ value = (value << 8) | (uint8_t)faad_getbits(ld, 8);
+
+ return value;
+}
+
+
+static uint32_t latmParsePayload(latm_header *latm, bitfile *ld)
+{
+ //assuming there's only one program with a single layer and 1 subFrame,
+ //allStreamsSametimeframing is set,
+ uint32_t framelen;
+ uint8_t tmp;
+
+ //this should be the payload length field for the current configuration
+ framelen = 0;
+ if(latm->framelen_type==0)
+ {
+ do
+ {
+ tmp = (uint8_t)faad_getbits(ld, 8);
+ framelen += tmp;
+ } while(tmp==0xff);
+ }
+ else if(latm->framelen_type==1)
+ framelen=latm->frameLength;
+
+ return framelen;
+}
+
+
+static uint32_t latmAudioMuxElement(latm_header *latm, bitfile *ld)
+{
+ uint32_t ascLen, asc_bits=0;
+ uint32_t x1, y1, m, n, i;
+ program_config pce;
+ mp4AudioSpecificConfig mp4ASC;
+
+ latm->useSameStreamMux = (uint8_t)faad_getbits(ld, 1);
+ if(!latm->useSameStreamMux)
+ {
+ //parseSameStreamMuxConfig
+ latm->version = (uint8_t) faad_getbits(ld, 1);
+ if(latm->version)
+ latm->versionA = (uint8_t) faad_getbits(ld, 1);
+ if(latm->versionA)
+ {
+ //dunno the payload format for versionA
+ fprintf(stderr, "versionA not supported\n");
+ return 0;
+ }
+ if(latm->version) //read taraBufferFullness
+ latm_get_value(ld);
+ latm->allStreamsSameTimeFraming = (uint8_t)faad_getbits(ld, 1);
+ latm->numSubFrames = (uint8_t)faad_getbits(ld, 6) + 1;
+ latm->numPrograms = (uint8_t)faad_getbits(ld, 4) + 1;
+ latm->numLayers = faad_getbits(ld, 3) + 1;
+ if(latm->numPrograms>1 || !latm->allStreamsSameTimeFraming || latm->numSubFrames>1 || latm->numLayers>1)
+ {
+ fprintf(stderr, "\r\nUnsupported LATM configuration: %d programs/ %d subframes, %d layers, allstreams: %d\n",
+ latm->numPrograms, latm->numSubFrames, latm->numLayers, latm->allStreamsSameTimeFraming);
+ return 0;
+ }
+ ascLen = 0;
+ if(latm->version)
+ ascLen = latm_get_value(ld);
+
+ x1 = faad_get_processed_bits(ld);
+ if(AudioSpecificConfigFromBitfile(ld, &mp4ASC, &pce, 0, 1) < 0)
+ return 0;
+
+ //horrid hack to unread the ASC bits and store them in latm->ASC
+ //the correct code would rely on an ideal faad_ungetbits()
+ y1 = faad_get_processed_bits(ld);
+ if((y1-x1) <= MAX_ASC_BYTES*8)
+ {
+ faad_rewindbits(ld);
+ m = x1;
+ while(m>0)
+ {
+ n = min(m, 32);
+ faad_getbits(ld, n);
+ m -= n;
+ }
+
+ i = 0;
+ m = latm->ASCbits = y1 - x1;
+ while(m > 0)
+ {
+ n = min(m, 8);
+ latm->ASC[i++] = (uint8_t) faad_getbits(ld, n);
+ m -= n;
+ }
+ }
+
+ asc_bits = y1-x1;
+
+ if(ascLen>asc_bits)
+ faad_getbits(ld, ascLen-asc_bits);
+
+ latm->framelen_type = (uint8_t) faad_getbits(ld, 3);
+ if(latm->framelen_type == 0)
+ {
+ latm->frameLength = 0;
+ faad_getbits(ld, 8); //buffer fullness for frame_len_type==0, useless
+ }
+ else if(latm->framelen_type == 1)
+ {
+ latm->frameLength = faad_getbits(ld, 9);
+ if(latm->frameLength==0)
+ {
+ fprintf(stderr, "Invalid frameLength: 0\r\n");
+ return 0;
+ }
+ latm->frameLength = (latm->frameLength+20)*8;
+ }
+ else
+ { //hellish CELP or HCVX stuff, discard
+ fprintf(stderr, "Unsupported CELP/HCVX framelentype: %d\n", latm->framelen_type);
+ return 0;
+ }
+
+ latm->otherDataLenBits = 0;
+ if(faad_getbits(ld, 1))
+ { //other data present
+ int esc, tmp;
+ if(latm->version)
+ latm->otherDataLenBits = latm_get_value(ld);
+ else do
+ {
+ esc = faad_getbits(ld, 1);
+ tmp = faad_getbits(ld, 8);
+ latm->otherDataLenBits = (latm->otherDataLenBits << 8) + tmp;
+ } while(esc);
+ }
+ if(faad_getbits(ld, 1)) //crc
+ faad_getbits(ld, 8);
+ latm->inited = 1;
+ }
+
+ //read payload
+ if(latm->inited)
+ return latmParsePayload(latm, ld);
+ else
+ return 0;
+}
+
+
+uint32_t faad_latm_frame(latm_header *latm, bitfile *ld)
+{
+ uint16_t len;
+ uint32_t initpos, endpos, firstpos, ret;
+
+ firstpos = faad_get_processed_bits(ld);
+ while(!ld->error && !ld->no_more_reading)
+ {
+ faad_byte_align(ld);
+ if(faad_showbits(ld, 11) != 0x2B7)
+ {
+ faad_getbits(ld, 8);
+ continue;
+ }
+ faad_getbits(ld, 11);
+ len = faad_getbits(ld, 13);
+ if(!len)
+ continue;
+ initpos = faad_get_processed_bits(ld);
+ ret = latmAudioMuxElement(latm, ld);
+ endpos = faad_get_processed_bits(ld);
+ if(ret>0)
+ return (len*8)-(endpos-initpos);
+ //faad_getbits(ld, initpos-endpos); //go back to initpos, but is valid a getbits(-N) ?
+ }
+ return -1U;
+}
diff --git a/libfaad2/syntax.h b/libfaad2/syntax.h
index ba7503c766..ba08b00a89 100644
--- a/libfaad2/syntax.h
+++ b/libfaad2/syntax.h
@@ -49,6 +49,7 @@ extern "C" {
#define RAW 0
#define ADIF 1
#define ADTS 2
+#define LATM 3
/* SBR signalling */
#define NO_SBR 0
@@ -116,6 +117,7 @@ uint8_t reordered_spectral_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile
int16_t *spectral_data);
void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
bitfile *ld, program_config *pce, drc_info *drc);
+uint32_t faad_latm_frame(latm_header *latm, bitfile *ld);
#ifdef __cplusplus