ref: facf1c46148257b9fc33c4b5552e187bd7e5f461
parent: 2ed7cad8bfd9b8bec0ac6856e92963cfe8ee36bf
author: menno <menno>
date: Sun Mar 23 19:03:30 EDT 2008
Applied some patches received
--- a/common/mp4ff/mp4ff_int_types.h
+++ b/common/mp4ff/mp4ff_int_types.h
@@ -3,6 +3,10 @@
#if defined (_WIN32)
+#ifdef __MINGW32__
+#include <stdlib.h>
+#endif /* #ifdef __MINGW32__ */
+
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: main.c,v 1.81 2007/11/01 12:33:29 menno Exp $
+** $Id: main.c,v 1.82 2008/03/23 23:03:27 menno Exp $
**/
#ifdef _WIN32
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include <getopt.h>
#include <neaacdec.h>
@@ -640,8 +641,9 @@
if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (!adts_out))
{
- write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
- }
+ if (write_audio_file(aufile, sample_buffer, frameInfo.samples, 0) == 0)
+ break;
+ }
/* fill buffer */
fill_buffer(&b);
@@ -976,7 +978,8 @@
if ((frameInfo.error == 0) && (sample_count > 0) && (!adts_out))
{
- write_audio_file(aufile, sample_buffer, sample_count, delay);
+ if (write_audio_file(aufile, sample_buffer, sample_count, delay) == 0)
+ break;
}
if (frameInfo.error > 0)
--- a/include/neaacdec.h
+++ b/include/neaacdec.h
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: neaacdec.h,v 1.11 2007/11/01 12:33:29 menno Exp $
+** $Id: neaacdec.h,v 1.12 2008/03/23 23:03:27 menno Exp $
**/
#ifndef __NEAACDEC_H__
@@ -69,7 +69,7 @@
#endif
#endif
-#define FAAD2_VERSION "2.6"
+#define FAAD2_VERSION "2.7"
/* object types for AAC */
#define MAIN 1
@@ -86,6 +86,7 @@
#define RAW 0
#define ADIF 1
#define ADTS 2
+#define LATM 3
/* SBR signalling */
#define NO_SBR 0
--- a/libfaad/common.c
+++ b/libfaad/common.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: common.c,v 1.26 2007/11/01 12:33:30 menno Exp $
+** $Id: common.c,v 1.27 2008/03/23 23:03:28 menno Exp $
**/
/* just some common functions that could be used anywhere */
@@ -244,7 +244,7 @@
return (*__r1 = (t3 >> 1) | t1 ) ^ (*__r2 = (t4 + t4) | t2 );
}
-uint32_t ones32(uint32_t x)
+static uint32_t ones32(uint32_t x)
{
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
@@ -255,7 +255,7 @@
return (x & 0x0000003f);
}
-uint32_t floor_log2(uint32_t x)
+static uint32_t floor_log2(uint32_t x)
{
#if 1
x |= (x >> 1);
--- a/libfaad/common.h
+++ b/libfaad/common.h
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: common.h,v 1.72 2007/11/01 12:33:30 menno Exp $
+** $Id: common.h,v 1.73 2008/03/23 23:03:28 menno Exp $
**/
#ifndef __COMMON_H__
@@ -405,8 +405,6 @@
/* common functions */
uint8_t cpu_has_sse(void);
uint32_t ne_rng(uint32_t *__r1, uint32_t *__r2);
-uint32_t ones32(uint32_t x);
-uint32_t floor_log2(uint32_t x);
uint32_t wl_min_lzc(uint32_t x);
#ifdef FIXED_POINT
#define LOG2_MIN_INF REAL_CONST(-10000)
--- a/libfaad/decoder.c
+++ b/libfaad/decoder.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: decoder.c,v 1.111 2007/11/01 12:33:30 menno Exp $
+** $Id: decoder.c,v 1.112 2008/03/23 23:03:28 menno Exp $
**/
#include "common.h"
@@ -32,6 +32,7 @@
#include "structs.h"
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include "decoder.h"
@@ -111,6 +112,7 @@
hDecoder->config.downMatrix = 0;
hDecoder->adts_header_present = 0;
hDecoder->adif_header_present = 0;
+ hDecoder->latm_header_present = 0;
#ifdef ERROR_RESILIENCE
hDecoder->aacSectionDataResilienceFlag = 0;
hDecoder->aacScalefactorDataResilienceFlag = 0;
@@ -203,6 +205,31 @@
}
+static int latmCheck(latm_header *latm, bitfile *ld)
+{
+ uint32_t good=0, bad=0, bits, m;
+
+ while(!ld->error)
+ {
+ bits = faad_latm_frame(latm, ld);
+ if(bits==-1U)
+ bad++;
+ else
+ {
+ good++;
+ while(bits>0)
+ {
+ m = min(bits, 8);
+ faad_getbits(ld, m);
+ bits -= m;
+ }
+ }
+ }
+
+ return (good>0);
+}
+
+
int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
uint32_t buffer_size,
uint32_t *samplerate, uint8_t *channels)
@@ -223,12 +250,29 @@
if (buffer != NULL)
{
- faad_initbits(&ld, buffer, buffer_size);
+ int is_latm;
+ latm_header *l = &hDecoder->latm_config;
- /* Check if an ADIF header is present */
- if ((buffer[0] == 'A') && (buffer[1] == 'D') &&
- (buffer[2] == 'I') && (buffer[3] == 'F'))
+ faad_initbits(&ld, buffer, buffer_size);
+
+ memset(l, 0, sizeof(latm_header));
+ is_latm = latmCheck(l, &ld);
+ l->inited = 0;
+ l->frameLength = 0;
+ faad_rewindbits(&ld);
+ if(is_latm && l->ASCbits>0)
{
+ int32_t x;
+ hDecoder->latm_header_present = 1;
+ x = NeAACDecInit2(hDecoder, l->ASC, (l->ASCbits+7)/8, samplerate, channels);
+ if(x!=0)
+ hDecoder->latm_header_present = 0;
+ return x;
+ }
+ /* Check if an ADIF header is present */
+ else if ((buffer[0] == 'A') && (buffer[1] == 'D') &&
+ (buffer[2] == 'I') && (buffer[3] == 'F'))
+ {
hDecoder->adif_header_present = 1;
get_adif_header(&adif, &ld);
@@ -331,7 +375,7 @@
/* decode the audio specific config */
rc = AudioSpecificConfig2(pBuffer, SizeOfDecoderSpecificInfo, &mp4ASC,
- &(hDecoder->pce));
+ &(hDecoder->pce), hDecoder->latm_header_present);
/* copy the relevant info to the decoder handle */
*samplerate = mp4ASC.samplingFrequency;
@@ -768,6 +812,7 @@
uint32_t bitsconsumed;
uint16_t frame_len;
void *sample_buffer;
+ uint32_t startbit=0, endbit=0, payload_bits=0;
#ifdef PROFILE
int64_t count = faad_get_ts();
@@ -837,6 +882,17 @@
}
#endif
+ if(hDecoder->latm_header_present)
+ {
+ payload_bits = faad_latm_frame(&hDecoder->latm_config, &ld);
+ startbit = faad_get_processed_bits(&ld);
+ if(payload_bits == -1U)
+ {
+ hInfo->error = 1;
+ goto error;
+ }
+ }
+
#ifdef DRM
if (hDecoder->object_type == DRM_ER_LC)
{
@@ -882,6 +938,17 @@
}
#endif
+ if(hDecoder->latm_header_present)
+ {
+ endbit = faad_get_processed_bits(&ld);
+ if(endbit-startbit > payload_bits)
+ fprintf(stderr, "\r\nERROR, too many payload bits read: %u > %d. Please. report with a link to a sample\n",
+ endbit-startbit, payload_bits);
+ if(hDecoder->latm_config.otherDataLenBits > 0)
+ faad_getbits(&ld, hDecoder->latm_config.otherDataLenBits);
+ faad_byte_align(&ld);
+ }
+
channels = hDecoder->fr_channels;
if (hInfo->error > 0)
@@ -906,7 +973,7 @@
faad_endbits(&ld);
- if (!hDecoder->adts_header_present && !hDecoder->adif_header_present)
+ if (!hDecoder->adts_header_present && !hDecoder->adif_header_present && !hDecoder->latm_header_present)
{
if (hDecoder->channelConfiguration == 0)
hDecoder->channelConfiguration = channels;
@@ -955,6 +1022,8 @@
hInfo->header_type = ADIF;
if (hDecoder->adts_header_present)
hInfo->header_type = ADTS;
+ if (hDecoder->latm_header_present)
+ hInfo->header_type = LATM;
#if (defined(PS_DEC) || defined(DRM_PS))
hInfo->ps = hDecoder->ps_used_global;
#endif
--- a/libfaad/hcr.c
+++ b/libfaad/hcr.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcr.c,v 1.24 2007/11/01 12:33:30 menno Exp $
+** $Id: hcr.c,v 1.25 2008/03/23 23:03:28 menno Exp $
**/
#include "common.h"
@@ -173,7 +173,7 @@
b->len += a->len;
}
-uint8_t is_good_cb(uint8_t this_CB, uint8_t this_sec_CB)
+static uint8_t is_good_cb(uint8_t this_CB, uint8_t this_sec_CB)
{
/* only want spectral data CB's */
if ((this_sec_CB > ZERO_HCB && this_sec_CB <= ESC_HCB) || (this_sec_CB >= VCB11_FIRST && this_sec_CB <= VCB11_LAST))
@@ -191,7 +191,7 @@
return 0;
}
-void read_segment(bits_t *segment, uint8_t segwidth, bitfile *ld)
+static void read_segment(bits_t *segment, uint8_t segwidth, bitfile *ld)
{
segment->len = segwidth;
@@ -206,7 +206,7 @@
}
}
-void fill_in_codeword(codeword_t *codeword, uint16_t index, uint16_t sp, uint8_t cb)
+static void fill_in_codeword(codeword_t *codeword, uint16_t index, uint16_t sp, uint8_t cb)
{
codeword[index].sp_offset = sp;
codeword[index].cb = cb;
--- a/libfaad/mp4.c
+++ b/libfaad/mp4.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4.c,v 1.38 2007/11/01 12:33:32 menno Exp $
+** $Id: mp4.c,v 1.39 2008/03/23 23:03:29 menno Exp $
**/
#include "common.h"
@@ -118,37 +118,33 @@
uint32_t buffer_size,
mp4AudioSpecificConfig *mp4ASC)
{
- return AudioSpecificConfig2(pBuffer, buffer_size, mp4ASC, NULL);
+ return AudioSpecificConfig2(pBuffer, buffer_size, mp4ASC, NULL, 0);
}
-int8_t AudioSpecificConfig2(uint8_t *pBuffer,
- uint32_t buffer_size,
+int8_t AudioSpecificConfigFromBitfile(bitfile *ld,
mp4AudioSpecificConfig *mp4ASC,
- program_config *pce)
+ program_config *pce, uint32_t buffer_size, uint8_t short_form)
{
- bitfile ld;
int8_t result = 0;
+ uint32_t startpos = faad_get_processed_bits(ld);
#ifdef SBR_DEC
int8_t bits_to_decode = 0;
#endif
- if (pBuffer == NULL)
- return -7;
if (mp4ASC == NULL)
return -8;
memset(mp4ASC, 0, sizeof(mp4AudioSpecificConfig));
- faad_initbits(&ld, pBuffer, buffer_size);
- faad_byte_align(&ld);
-
- mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(&ld, 5
+ mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(ld, 5
DEBUGVAR(1,1,"parse_audio_decoder_specific_info(): ObjectTypeIndex"));
- mp4ASC->samplingFrequencyIndex = (uint8_t)faad_getbits(&ld, 4
+ mp4ASC->samplingFrequencyIndex = (uint8_t)faad_getbits(ld, 4
DEBUGVAR(1,2,"parse_audio_decoder_specific_info(): SamplingFrequencyIndex"));
+ if(mp4ASC->samplingFrequencyIndex==0x0f)
+ faad_getbits(ld, 24);
- mp4ASC->channelsConfiguration = (uint8_t)faad_getbits(&ld, 4
+ mp4ASC->channelsConfiguration = (uint8_t)faad_getbits(ld, 4
DEBUGVAR(1,3,"parse_audio_decoder_specific_info(): ChannelsConfiguration"));
mp4ASC->samplingFrequency = get_sample_rate(mp4ASC->samplingFrequencyIndex);
@@ -155,19 +151,16 @@
if (ObjectTypesTable[mp4ASC->objectTypeIndex] != 1)
{
- faad_endbits(&ld);
return -1;
}
if (mp4ASC->samplingFrequency == 0)
{
- faad_endbits(&ld);
return -2;
}
if (mp4ASC->channelsConfiguration > 7)
{
- faad_endbits(&ld);
return -3;
}
@@ -187,7 +180,7 @@
uint8_t tmp;
mp4ASC->sbr_present_flag = 1;
- tmp = (uint8_t)faad_getbits(&ld, 4
+ tmp = (uint8_t)faad_getbits(ld, 4
DEBUGVAR(1,5,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
/* check for downsampled SBR */
if (tmp == mp4ASC->samplingFrequencyIndex)
@@ -195,12 +188,12 @@
mp4ASC->samplingFrequencyIndex = tmp;
if (mp4ASC->samplingFrequencyIndex == 15)
{
- mp4ASC->samplingFrequency = (uint32_t)faad_getbits(&ld, 24
+ mp4ASC->samplingFrequency = (uint32_t)faad_getbits(ld, 24
DEBUGVAR(1,6,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
} else {
mp4ASC->samplingFrequency = get_sample_rate(mp4ASC->samplingFrequencyIndex);
}
- mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(&ld, 5
+ mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(ld, 5
DEBUGVAR(1,7,"parse_audio_decoder_specific_info(): ObjectTypeIndex"));
}
#endif
@@ -210,12 +203,12 @@
mp4ASC->objectTypeIndex == 3 || mp4ASC->objectTypeIndex == 4 ||
mp4ASC->objectTypeIndex == 6 || mp4ASC->objectTypeIndex == 7)
{
- result = GASpecificConfig(&ld, mp4ASC, pce);
+ result = GASpecificConfig(ld, mp4ASC, pce);
#ifdef ERROR_RESILIENCE
} else if (mp4ASC->objectTypeIndex >= ER_OBJECT_START) { /* ER */
- result = GASpecificConfig(&ld, mp4ASC, pce);
- mp4ASC->epConfig = (uint8_t)faad_getbits(&ld, 2
+ result = GASpecificConfig(ld, mp4ASC, pce);
+ mp4ASC->epConfig = (uint8_t)faad_getbits(ld, 2
DEBUGVAR(1,143,"parse_audio_decoder_specific_info(): epConfig"));
if (mp4ASC->epConfig != 0)
@@ -234,21 +227,24 @@
#ifdef SBR_DEC
- bits_to_decode = (int8_t)(buffer_size*8 - faad_get_processed_bits(&ld));
+ if(short_form)
+ bits_to_decode = 0;
+ else
+ bits_to_decode = (int8_t)(buffer_size*8 - (startpos-faad_get_processed_bits(ld)));
if ((mp4ASC->objectTypeIndex != 5) && (bits_to_decode >= 16))
{
- int16_t syncExtensionType = (int16_t)faad_getbits(&ld, 11
+ int16_t syncExtensionType = (int16_t)faad_getbits(ld, 11
DEBUGVAR(1,9,"parse_audio_decoder_specific_info(): syncExtensionType"));
if (syncExtensionType == 0x2b7)
{
- uint8_t tmp_OTi = (uint8_t)faad_getbits(&ld, 5
+ uint8_t tmp_OTi = (uint8_t)faad_getbits(ld, 5
DEBUGVAR(1,10,"parse_audio_decoder_specific_info(): extensionAudioObjectType"));
if (tmp_OTi == 5)
{
- mp4ASC->sbr_present_flag = (uint8_t)faad_get1bit(&ld
+ mp4ASC->sbr_present_flag = (uint8_t)faad_get1bit(ld
DEBUGVAR(1,11,"parse_audio_decoder_specific_info(): sbr_present_flag"));
if (mp4ASC->sbr_present_flag)
@@ -258,7 +254,7 @@
/* Don't set OT to SBR until checked that it is actually there */
mp4ASC->objectTypeIndex = tmp_OTi;
- tmp = (uint8_t)faad_getbits(&ld, 4
+ tmp = (uint8_t)faad_getbits(ld, 4
DEBUGVAR(1,12,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
/* check for downsampled SBR */
@@ -268,7 +264,7 @@
if (mp4ASC->samplingFrequencyIndex == 15)
{
- mp4ASC->samplingFrequency = (uint32_t)faad_getbits(&ld, 24
+ mp4ASC->samplingFrequency = (uint32_t)faad_getbits(ld, 24
DEBUGVAR(1,13,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
} else {
mp4ASC->samplingFrequency = get_sample_rate(mp4ASC->samplingFrequencyIndex);
@@ -292,7 +288,22 @@
}
#endif
- faad_endbits(&ld);
+ faad_endbits(ld);
return result;
+}
+
+int8_t AudioSpecificConfig2(uint8_t *pBuffer,
+ uint32_t buffer_size,
+ mp4AudioSpecificConfig *mp4ASC,
+ program_config *pce,
+ uint8_t short_form)
+{
+ uint8_t ret = 0;
+ bitfile ld;
+ faad_initbits(&ld, pBuffer, buffer_size);
+ faad_byte_align(&ld);
+ ret = AudioSpecificConfigFromBitfile(&ld, mp4ASC, pce, buffer_size, short_form);
+ faad_endbits(&ld);
+ return ret;
}
--- a/libfaad/mp4.h
+++ b/libfaad/mp4.h
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4.h,v 1.25 2007/11/01 12:33:32 menno Exp $
+** $Id: mp4.h,v 1.26 2008/03/23 23:03:29 menno Exp $
**/
#ifndef __MP4_H__
@@ -44,7 +44,11 @@
int8_t AudioSpecificConfig2(uint8_t *pBuffer,
uint32_t buffer_size,
mp4AudioSpecificConfig *mp4ASC,
- program_config *pce);
+ program_config *pce, uint8_t short_form);
+
+int8_t AudioSpecificConfigFromBitfile(bitfile *ld,
+ mp4AudioSpecificConfig *mp4ASC,
+ program_config *pce, uint32_t bsize, uint8_t short_form);
#ifdef __cplusplus
}
--- a/libfaad/sbr_e_nf.c
+++ b/libfaad/sbr_e_nf.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_e_nf.c,v 1.21 2007/11/01 12:33:35 menno Exp $
+** $Id: sbr_e_nf.c,v 1.22 2008/03/23 23:03:29 menno Exp $
**/
#include "common.h"
@@ -234,7 +234,7 @@
/* calculates 1/(1+Q) */
/* [0..1] */
-real_t calc_Q_div(sbr_info *sbr, uint8_t ch, uint8_t m, uint8_t l)
+static real_t calc_Q_div(sbr_info *sbr, uint8_t ch, uint8_t m, uint8_t l)
{
if (sbr->bs_coupling)
{
@@ -353,7 +353,7 @@
/* calculates Q/(1+Q) */
/* [0..1] */
-real_t calc_Q_div2(sbr_info *sbr, uint8_t ch, uint8_t m, uint8_t l)
+static real_t calc_Q_div2(sbr_info *sbr, uint8_t ch, uint8_t m, uint8_t l)
{
if (sbr->bs_coupling)
{
--- a/libfaad/structs.h
+++ b/libfaad/structs.h
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: structs.h,v 1.46 2007/11/01 12:33:40 menno Exp $
+** $Id: structs.h,v 1.47 2008/03/23 23:03:29 menno Exp $
**/
#ifndef __STRUCTS_H__
@@ -335,6 +335,23 @@
/*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;
@@ -377,6 +394,7 @@
{
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;
@@ -476,6 +494,7 @@
int64_t scalefac_cycles;
int64_t requant_cycles;
#endif
+ latm_header latm_config;
const unsigned char *cmes;
} NeAACDecStruct, *NeAACDecHandle;
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.c
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: syntax.c,v 1.89 2007/11/01 12:33:40 menno Exp $
+** $Id: syntax.c,v 1.90 2008/03/23 23:03:29 menno Exp $
**/
/*
@@ -36,6 +36,7 @@
#include "structs.h"
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include "decoder.h"
@@ -52,6 +53,7 @@
#ifdef SBR_DEC
#include "sbr_syntax.h"
#endif
+#include "mp4.h"
/* static function declarations */
@@ -154,10 +156,10 @@
DEBUGVAR(1,145,"GASpecificConfig(): aacScalefactorDataResilienceFlag"));
mp4ASC->aacSpectralDataResilienceFlag = faad_get1bit(ld
DEBUGVAR(1,146,"GASpecificConfig(): aacSpectralDataResilienceFlag"));
-
- /* 1 bit: extensionFlag3 */
}
- }
+ /* 1 bit: extensionFlag3 */
+ faad_getbits(ld, 1);
+ }
#endif
return 0;
@@ -573,7 +575,7 @@
/* new in corrigendum 14496-3:2002 */
#ifdef DRM
- if (hDecoder->object_type != DRM_ER_LC)
+ if (hDecoder->object_type != DRM_ER_LC && !hDecoder->latm_header_present)
#endif
{
faad_byte_align(ld);
@@ -2441,4 +2443,189 @@
adts->crc_check = (uint16_t)faad_getbits(ld, 16
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)
+ {
+ 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;
}
--- a/libfaad/syntax.h
+++ b/libfaad/syntax.h
@@ -25,7 +25,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: syntax.h,v 1.58 2007/11/01 12:33:40 menno Exp $
+** $Id: syntax.h,v 1.59 2008/03/23 23:03:30 menno Exp $
**/
#ifndef __SYNTAX_H__
@@ -52,6 +52,7 @@
#define RAW 0
#define ADIF 1
#define ADTS 2
+#define LATM 3
/* SBR signalling */
#define NO_SBR 0
@@ -121,6 +122,7 @@
void DRM_aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
bitfile *ld, program_config *pce, drc_info *drc);
#endif
+uint32_t faad_latm_frame(latm_header *latm, bitfile *ld);
#ifdef __cplusplus
}