[vlc-commits] packetizer: mpeg4audio: add support for AAC-ELD over LATM
Francois Cartegnie
git at videolan.org
Thu Feb 21 20:27:15 CET 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Feb 21 18:24:43 2019 +0100| [c2e79d39840df30364eeb21d93b02bb5f2dd70d5] | committer: Francois Cartegnie
packetizer: mpeg4audio: add support for AAC-ELD over LATM
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c2e79d39840df30364eeb21d93b02bb5f2dd70d5
---
modules/packetizer/mpeg4audio.c | 96 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 1 deletion(-)
diff --git a/modules/packetizer/mpeg4audio.c b/modules/packetizer/mpeg4audio.c
index f81587f5cd..eaf9b545d5 100644
--- a/modules/packetizer/mpeg4audio.c
+++ b/modules/packetizer/mpeg4audio.c
@@ -134,6 +134,7 @@ typedef struct
int i_frame_size;
unsigned int i_channels;
unsigned int i_rate, i_frame_length, i_header_size;
+ int i_aac_profile;
int i_input_rate;
@@ -182,6 +183,29 @@ static int ChannelConfigurationToVLC(uint8_t i_channel)
return i_channel;
}
+static int AOTtoAACProfile(uint8_t i_object_type)
+{
+ switch(i_object_type)
+ {
+ case AOT_AAC_MAIN:
+ case AOT_AAC_LC:
+ case AOT_AAC_SSR:
+ case AOT_AAC_LTP:
+ case AOT_AAC_SBR:
+ case AOT_AAC_SC:
+ case AOT_ER_AAC_LD:
+ case AOT_AAC_PS:
+ case AOT_ER_AAC_ELD:
+ {
+ static_assert(AOT_AAC_MAIN == AAC_PROFILE_MAIN + 1,
+ "invalid profile to object mapping");
+ return i_object_type - 1;
+ }
+ default:
+ return -1;
+ }
+}
+
#define ADTS_HEADER_SIZE 9
#define LOAS_HEADER_SIZE 3
@@ -284,6 +308,8 @@ static int OpenPacketizer(vlc_object_t *p_this)
p_dec->fmt_out.audio.i_frame_length = asc.i_frame_length;
p_dec->fmt_out.audio.i_channels =
ChannelConfigurationToVLC(asc.i_channel_configuration);
+ if(p_dec->fmt_out.i_profile != -1)
+ p_dec->fmt_out.i_profile = AOTtoAACProfile(asc.i_object_type);
msg_Dbg(p_dec, "%sAAC%s %dHz %d samples/frame",
(asc.i_sbr) ? "HE-" : "",
@@ -532,6 +558,70 @@ static int Mpeg4GASpecificConfig(mpeg4_asc_t *p_cfg, bs_t *s)
return 0;
}
+static int Mpeg4ELDSpecificConfig(mpeg4_asc_t *p_cfg, bs_t *s)
+{
+ p_cfg->i_frame_length = bs_read1(s) ? 960 : 480;
+
+ /* ELDSpecificConfig Table 4.180 */
+
+ bs_skip(s, 3);
+ if(bs_read1(s)) /* ldSbrPresentFlag */
+ {
+ bs_skip(s, 2);
+ /* ld_sbr_header(channelConfiguration) Table 4.181 */
+ unsigned numSbrHeader;
+ switch(p_cfg->i_channel_configuration)
+ {
+ case 1: case 2:
+ numSbrHeader = 1;
+ break;
+ case 3:
+ numSbrHeader = 2;
+ break;
+ case 4: case 5: case 6:
+ numSbrHeader = 3;
+ break;
+ case 7:
+ numSbrHeader = 4;
+ break;
+ default:
+ numSbrHeader = 0;
+ break;
+ }
+ for( ; numSbrHeader; numSbrHeader-- )
+ {
+ /* sbr_header() Table 4.63 */
+ bs_read(s, 14);
+ bool header_extra_1 = bs_read1(s);
+ bool header_extra_2 = bs_read1(s);
+ if(header_extra_1)
+ bs_read(s, 5);
+ if(header_extra_2)
+ bs_read(s, 6);
+ }
+ }
+
+ for(unsigned eldExtType = bs_read(s, 4);
+ eldExtType != 0x0 /* ELDEXT_TERM */;
+ eldExtType = bs_read(s, 4))
+ {
+ unsigned eldExtLen = bs_read(s, 4);
+ unsigned eldExtLenAdd = 0;
+ if(eldExtLen == 15)
+ {
+ eldExtLenAdd = bs_read(s, 8);
+ eldExtLen += eldExtLenAdd;
+ }
+ if(eldExtLenAdd == 255)
+ eldExtLen += bs_read(s, 16);
+ /* reserved extensions */
+ for(; eldExtLen; eldExtLen--)
+ bs_skip(s, 8);
+ }
+
+ return 0;
+}
+
static enum mpeg4_audioObjectType Mpeg4ReadAudioObjectType(bs_t *s)
{
int i_type = bs_read(s, 5);
@@ -622,7 +712,8 @@ static int Mpeg4ReadAudioSpecificConfig(bs_t *s, mpeg4_asc_t *p_cfg, bool b_with
case AOT_SLS_NON_CORE:
// SLSSpecificConfig();
case AOT_ER_AAC_ELD:
- // ELDSpecificConfig();
+ Mpeg4ELDSpecificConfig(p_cfg, s);
+ break;
case AOT_SMR_SIMPLE:
case AOT_SMR_MAIN:
// SymbolicMusicSpecificConfig();
@@ -851,6 +942,7 @@ static int LOASParse(decoder_t *p_dec, uint8_t *p_buffer, int i_buffer)
p_sys->i_channels = ChannelConfigurationToVLC(st->cfg.i_channel_configuration);
p_sys->i_rate = st->cfg.i_samplerate;
p_sys->i_frame_length = st->cfg.i_frame_length;
+ p_sys->i_aac_profile = AOTtoAACProfile(st->cfg.i_object_type);
if (p_sys->i_channels && p_sys->i_rate && p_sys->i_frame_length > 0)
{
@@ -1015,6 +1107,8 @@ static void SetupOutput(decoder_t *p_dec, block_t *p_block)
p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
+ /* Will reload extradata on change */
+ p_dec->fmt_out.i_profile = p_sys->i_aac_profile;
#if 0
p_dec->fmt_out.audio.i_physical_channels = p_sys->i_channels_conf;
More information about the vlc-commits
mailing list