mirror of https://github.com/nu774/fdkaac.git
Use our SBR signaling implementation on old libfdkaac
This commit is contained in:
parent
fd2a1e77b3
commit
cf200f9563
71
src/aacenc.c
71
src/aacenc.c
|
@ -13,6 +13,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "aacenc.h"
|
#include "aacenc.h"
|
||||||
|
|
||||||
|
int aacenc_is_explicit_bw_compatible_sbr_signaling_available()
|
||||||
|
{
|
||||||
|
LIB_INFO lib_info;
|
||||||
|
aacenc_get_lib_info(&lib_info);
|
||||||
|
return lib_info.version > 0x03040900;
|
||||||
|
}
|
||||||
|
|
||||||
int aacenc_is_sbr_ratio_available()
|
int aacenc_is_sbr_ratio_available()
|
||||||
{
|
{
|
||||||
#if AACENCODER_LIB_VL0 < 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1<4)
|
#if AACENCODER_LIB_VL0 < 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1<4)
|
||||||
|
@ -64,6 +71,70 @@ void aacenc_get_lib_info(LIB_INFO *info)
|
||||||
free(lib_info);
|
free(lib_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
unsigned shift = aacenc_is_dual_rate_sbr(params);
|
||||||
|
|
||||||
|
switch (params->profile) {
|
||||||
|
case AOT_SBR:
|
||||||
|
case AOT_PS:
|
||||||
|
if (!shift)
|
||||||
|
break;
|
||||||
|
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 << shift) << 3;
|
||||||
|
if (params->profile == AOT_SBR) {
|
||||||
|
*outsize = ascsize + 3;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (*outsize < ascsize)
|
||||||
|
return -1;
|
||||||
|
memcpy(outasc, asc, ascsize);
|
||||||
|
*outsize = ascsize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int aacenc_channel_mode(const pcm_sample_description_t *format)
|
int aacenc_channel_mode(const pcm_sample_description_t *format)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,8 @@ typedef struct aacenc_frame_t {
|
||||||
uint32_t size, capacity;
|
uint32_t size, capacity;
|
||||||
} aacenc_frame_t;
|
} aacenc_frame_t;
|
||||||
|
|
||||||
|
int aacenc_is_explicit_bw_compatible_sbr_signaling_available();
|
||||||
|
|
||||||
int aacenc_is_sbr_ratio_available();
|
int aacenc_is_sbr_ratio_available();
|
||||||
|
|
||||||
int aacenc_is_sbr_active(const aacenc_param_t *params);
|
int aacenc_is_sbr_active(const aacenc_param_t *params);
|
||||||
|
@ -38,6 +40,10 @@ int aacenc_is_dual_rate_sbr(const aacenc_param_t *params);
|
||||||
|
|
||||||
void aacenc_get_lib_info(LIB_INFO *info);
|
void aacenc_get_lib_info(LIB_INFO *info);
|
||||||
|
|
||||||
|
int aacenc_mp4asc(const aacenc_param_t *params,
|
||||||
|
const uint8_t *asc, uint32_t ascsize,
|
||||||
|
uint8_t *outasc, uint32_t *outsize);
|
||||||
|
|
||||||
int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params,
|
int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params,
|
||||||
const pcm_sample_description_t *format,
|
const pcm_sample_description_t *format,
|
||||||
AACENC_InfoStruct *info);
|
AACENC_InfoStruct *info);
|
||||||
|
|
26
src/main.c
26
src/main.c
|
@ -801,12 +801,14 @@ int main(int argc, char **argv)
|
||||||
params.sbr_ratio = 2;
|
params.sbr_ratio = 2;
|
||||||
}
|
}
|
||||||
scale_shift = aacenc_is_dual_rate_sbr((aacenc_param_t*)¶ms);
|
scale_shift = aacenc_is_dual_rate_sbr((aacenc_param_t*)¶ms);
|
||||||
params.sbr_signaling =
|
params.sbr_signaling = 0;
|
||||||
(params.transport_format == TT_MP4_LOAS) ? 2 :
|
if (sbr_mode) {
|
||||||
(params.transport_format == TT_MP4_RAW) ? 1 : 0;
|
if (params.transport_format == TT_MP4_LOAS || !scale_shift)
|
||||||
if (sbr_mode && !scale_shift)
|
params.sbr_signaling = 2;
|
||||||
params.sbr_signaling = 2;
|
if (params.transport_format == TT_MP4_RAW &&
|
||||||
|
aacenc_is_explicit_bw_compatible_sbr_signaling_available())
|
||||||
|
params.sbr_signaling = 1;
|
||||||
|
}
|
||||||
if (aacenc_init(&encoder, (aacenc_param_t*)¶ms, sample_format,
|
if (aacenc_init(&encoder, (aacenc_param_t*)¶ms, sample_format,
|
||||||
&aacinfo) < 0)
|
&aacinfo) < 0)
|
||||||
goto END;
|
goto END;
|
||||||
|
@ -832,9 +834,17 @@ int main(int argc, char **argv)
|
||||||
params.output_fp)) < 0)
|
params.output_fp)) < 0)
|
||||||
goto END;
|
goto END;
|
||||||
m4af_set_num_channels(m4af, 0, sample_format->channels_per_frame);
|
m4af_set_num_channels(m4af, 0, sample_format->channels_per_frame);
|
||||||
m4af_set_decoder_specific_info(m4af, 0,
|
|
||||||
aacinfo.confBuf, aacinfo.confSize);
|
|
||||||
m4af_set_fixed_frame_duration(m4af, 0, framelen >> scale_shift);
|
m4af_set_fixed_frame_duration(m4af, 0, framelen >> scale_shift);
|
||||||
|
if (aacenc_is_explicit_bw_compatible_sbr_signaling_available())
|
||||||
|
m4af_set_decoder_specific_info(m4af, 0,
|
||||||
|
aacinfo.confBuf, aacinfo.confSize);
|
||||||
|
else {
|
||||||
|
uint8_t mp4asc[32];
|
||||||
|
uint32_t ascsize = sizeof(mp4asc);
|
||||||
|
aacenc_mp4asc((aacenc_param_t*)¶ms, aacinfo.confBuf,
|
||||||
|
aacinfo.confSize, mp4asc, &ascsize);
|
||||||
|
m4af_set_decoder_specific_info(m4af, 0, mp4asc, ascsize);
|
||||||
|
}
|
||||||
m4af_set_vbr_mode(m4af, 0, params.bitrate_mode);
|
m4af_set_vbr_mode(m4af, 0, params.bitrate_mode);
|
||||||
m4af_set_priming_mode(m4af, params.gapless_mode + 1);
|
m4af_set_priming_mode(m4af, params.gapless_mode + 1);
|
||||||
m4af_begin_write(m4af);
|
m4af_begin_write(m4af);
|
||||||
|
|
Loading…
Reference in New Issue