remove --sbr-signaling

Instead, we always use explicit/backward compatible SBR signaling by
ASC extension in case of m4a, which is not supported by FDK library
(so we do it on our side).
For LOAS, we use explicit hierarchical signaling.
This commit is contained in:
nu774 2013-10-27 19:27:18 +09:00
parent 5ccbfaa710
commit 9b8f9915c2
3 changed files with 86 additions and 17 deletions

View File

@ -10,6 +10,7 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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)
{

View File

@ -26,6 +26,10 @@ typedef struct aacenc_param_t {
int aacenc_is_sbr_active(const aacenc_param_t *params);
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,
const pcm_sample_description_t *format,
AACENC_InfoStruct *info);

View File

@ -133,10 +133,6 @@ PROGNAME " %s\n"
" 0: Off\n"
" 1: On(default)\n"
" -L, --lowdelay-sbr Enable ELD-SBR (AAC ELD only)\n"
" -s, --sbr-signaling <n> SBR signaling mode\n"
" 0: Implicit, backward compatible(default)\n"
" 1: Explicit SBR and implicit PS\n"
" 2: Explicit hierarchical signaling\n"
" -f, --transport-format <n> Transport format\n"
" 0: RAW (default, muxed into M4A)\n"
" 1: ADIF\n"
@ -247,7 +243,6 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
{ "bandwidth", required_argument, 0, 'w' },
{ "afterburner", required_argument, 0, 'a' },
{ "lowdelay-sbr", no_argument, 0, 'L' },
{ "sbr-signaling", required_argument, 0, 's' },
{ "transport-format", required_argument, 0, 'f' },
{ "adts-crc-check", no_argument, 0, 'C' },
{ "header-period", required_argument, 0, 'P' },
@ -326,13 +321,6 @@ int parse_options(int argc, char **argv, aacenc_param_ex_t *params)
case 'L':
params->lowdelay_sbr = 1;
break;
case 's':
if (sscanf(optarg, "%u", &n) != 1 || n > 2) {
fprintf(stderr, "invalid arg for sbr-signaling\n");
return -1;
}
params->sbr_signaling = n;
break;
case 'f':
if (sscanf(optarg, "%u", &n) != 1) {
fprintf(stderr, "invalid arg for transport-format\n");
@ -736,6 +724,7 @@ int main(int argc, char **argv)
const pcm_sample_description_t *sample_format;
int downsampled_timescale = 0;
int frame_count = 0;
int sbr_mode = 0;
setlocale(LC_CTYPE, "");
setbuf(stderr, 0);
@ -748,6 +737,17 @@ int main(int argc, char **argv)
sample_format = pcm_get_format(reader);
/*
* We use explicit/hierarchical signaling for LOAS.
* Other than that, we request implicit signaling to FDK library, then
* append explicit/backward-compatible signaling to ASC in case of MP4FF.
*
* Explicit/backward-compatible signaling of SBR is the most recommended
* way in MPEG4 part3 spec, and seems the only way supported by iTunes.
* Since FDK library does not support it, we have to do it on our side.
*/
params.sbr_signaling = (params.transport_format == TT_MP4_LOAS) ? 2 : 0;
if (aacenc_init(&encoder, (aacenc_param_t*)&params, sample_format,
&aacinfo) < 0)
goto END;
@ -764,19 +764,21 @@ int main(int argc, char **argv)
goto END;
}
handle_signals();
sbr_mode = aacenc_is_sbr_active((aacenc_param_t*)&params);
if (!params.transport_format) {
uint32_t scale;
uint8_t mp4asc[32];
uint32_t ascsize = sizeof(mp4asc);
unsigned framelen = aacinfo.frameLength;
int sbr_mode = aacenc_is_sbr_active((aacenc_param_t*)&params);
int sig_mode = aacEncoder_GetParam(encoder, AACENC_SIGNALING_MODE);
if (sbr_mode && !sig_mode)
if (sbr_mode)
downsampled_timescale = 1;
scale = sample_format->sample_rate >> downsampled_timescale;
if ((m4af = m4af_create(M4AF_CODEC_MP4A, scale, &m4af_io,
params.output_fp)) < 0)
goto END;
m4af_set_decoder_specific_info(m4af, 0, aacinfo.confBuf,
aacinfo.confSize);
aacenc_mp4asc((aacenc_param_t*)&params, aacinfo.confBuf,
aacinfo.confSize, mp4asc, &ascsize);
m4af_set_decoder_specific_info(m4af, 0, mp4asc, ascsize);
m4af_set_fixed_frame_duration(m4af, 0,
framelen >> downsampled_timescale);
m4af_set_vbr_mode(m4af, 0, params.bitrate_mode);