X-Git-Url: http://git.ieval.ro/?p=fdkaac.git;a=blobdiff_plain;f=src%2Faacenc.c;h=d25be8a3570a0eb019d1355f14731fc12f3c268c;hp=af9107d32e82630440952d9dbfcd0f8da2757cf7;hb=9b8f9915c2cac2887e52bb38d263f171b5f7d69d;hpb=5ccbfaa710c8d86a59e5d07f10e2667ea3619ab0 diff --git a/src/aacenc.c b/src/aacenc.c index af9107d..d25be8a 100644 --- a/src/aacenc.c +++ b/src/aacenc.c @@ -10,6 +10,7 @@ #endif #include #include +#include #include "aacenc.h" int aacenc_is_sbr_active(const aacenc_param_t *params) @@ -25,6 +26,68 @@ int aacenc_is_sbr_active(const aacenc_param_t *params) return 0; } +static const unsigned aacenc_sampling_freq_tab[] = { + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, + 16000, 12000, 11025, 8000, 7350, 0, 0, 0 +}; + +static +unsigned sampling_freq_index(unsigned rate) +{ + unsigned i; + for (i = 0; aacenc_sampling_freq_tab[i]; ++i) + if (aacenc_sampling_freq_tab[i] == rate) + return i; + return 0xf; +} + +/* + * Append backward compatible SBR/PS signaling to implicit signaling ASC, + * if SBR/PS is present. + */ +int aacenc_mp4asc(const aacenc_param_t *params, + const uint8_t *asc, uint32_t ascsize, + uint8_t *outasc, uint32_t *outsize) +{ + unsigned asc_sfreq = aacenc_sampling_freq_tab[(asc[0]&0x7)<<1 |asc[1]>>7]; + + switch (params->profile) { + case AOT_SBR: + case AOT_PS: + if (*outsize < ascsize + 3) + return -1; + memcpy(outasc, asc, ascsize); + /* syncExtensionType:11 (value:0x2b7) */ + outasc[ascsize+0] = 0x2b << 1; + outasc[ascsize+1] = 0x7 << 5; + /* extensionAudioObjectType:5 (value:5)*/ + outasc[ascsize+1] |= 5; + /* sbrPresentFlag:1 (value:1) */ + outasc[ascsize+2] = 0x80; + /* extensionSamplingFrequencyIndex:4 */ + outasc[ascsize+2] |= sampling_freq_index(asc_sfreq << 1) << 3; + if (params->profile == AOT_SBR) { + *outsize = ascsize + 3; + break; + } + if (*outsize < ascsize + 5) + return -1; + /* syncExtensionType:11 (value:0x548) */ + outasc[ascsize+2] |= 0x5; + outasc[ascsize+3] = 0x48; + /* psPresentFlag:1 (value:1) */ + outasc[ascsize+4] = 0x80; + *outsize = ascsize + 5; + break; + default: + if (*outsize < ascsize) + return -1; + memcpy(outasc, asc, ascsize); + *outsize = ascsize; + } + return 0; +} + static int aacenc_channel_mode(const pcm_sample_description_t *format) {