2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
16 int aacenc_is_sbr_ratio_available()
18 #if AACENCODER_LIB_VL0 < 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1<4)
22 aacenc_get_lib_info(&lib_info
);
23 return lib_info
.version
> 0x03040000;
27 int aacenc_is_sbr_active(const aacenc_param_t
*params
)
29 switch (params
->profile
) {
30 case AOT_SBR
: case AOT_PS
: case AOT_MP2_SBR
: case AOT_MP2_PS
:
31 case AOT_DABPLUS_SBR
: case AOT_DABPLUS_PS
:
32 case AOT_DRM_SBR
: case AOT_DRM_MPEG_PS
:
35 if (params
->profile
== AOT_ER_AAC_ELD
&& params
->lowdelay_sbr
)
40 int aacenc_is_dual_rate_sbr(const aacenc_param_t
*params
)
42 if (params
->profile
== AOT_PS
|| params
->profile
== AOT_MP2_PS
)
44 else if (params
->profile
== AOT_SBR
|| params
->profile
== AOT_MP2_SBR
)
45 return params
->sbr_ratio
== 0 || params
->sbr_ratio
== 2;
46 else if (params
->profile
== AOT_ER_AAC_ELD
&& params
->lowdelay_sbr
)
47 return params
->sbr_ratio
== 2;
51 void aacenc_get_lib_info(LIB_INFO
*info
)
53 LIB_INFO
*lib_info
= 0;
54 lib_info
= calloc(FDK_MODULE_LAST
, sizeof(LIB_INFO
));
55 if (aacEncGetLibInfo(lib_info
) == AACENC_OK
) {
57 for (i
= 0; i
< FDK_MODULE_LAST
; ++i
) {
58 if (lib_info
[i
].module_id
== FDK_AACENC
) {
59 memcpy(info
, &lib_info
[i
], sizeof(LIB_INFO
));
68 int aacenc_channel_mode(const pcm_sample_description_t
*format
)
70 uint32_t chanmask
= format
->channel_mask
;
72 if (format
->channels_per_frame
> 8)
75 static uint32_t defaults
[] = { 0x4, 0x3, 0x7, 0, 0x37, 0x3f, 0, 0x63f };
76 chanmask
= defaults
[format
->channels_per_frame
- 1];
79 case 0x3: return MODE_2
;
80 case 0x4: return MODE_1
;
81 case 0x7: return MODE_1_2
;
82 case 0x37: return MODE_1_2_2
;
83 case 0x3f: return MODE_1_2_2_1
;
84 case 0x107: return MODE_1_2_1
;
85 case 0x607: return MODE_1_2_2
;
86 case 0x60f: return MODE_1_2_2_1
;
87 #if AACENCODER_LIB_VL0 > 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1>=4)
88 case 0xff: return MODE_1_2_2_2_1
;
89 case 0x63f: return MODE_7_1_REAR_SURROUND
;
95 int aacenc_init(HANDLE_AACENCODER
*encoder
, const aacenc_param_t
*params
,
96 const pcm_sample_description_t
*format
,
97 AACENC_InfoStruct
*info
)
104 aacenc_get_lib_info(&lib_info
);
106 if ((channel_mode
= aacenc_channel_mode(format
)) == 0) {
107 fprintf(stderr
, "ERROR: unsupported channel layout\n");
110 if (aacEncOpen(encoder
, 0, 0) != AACENC_OK
) {
111 fprintf(stderr
, "ERROR: aacEncOpen() failed\n");
114 aot
= (params
->profile
? params
->profile
: AOT_AAC_LC
);
115 if (aacEncoder_SetParam(*encoder
, AACENC_AOT
, aot
) != AACENC_OK
) {
116 fprintf(stderr
, "ERROR: unsupported profile\n");
119 if (params
->bitrate_mode
== 0)
120 aacEncoder_SetParam(*encoder
, AACENC_BITRATE
, params
->bitrate
);
121 else if (aacEncoder_SetParam(*encoder
, AACENC_BITRATEMODE
,
122 params
->bitrate_mode
) != AACENC_OK
) {
123 fprintf(stderr
, "ERROR: unsupported bitrate mode\n");
126 if (aacEncoder_SetParam(*encoder
, AACENC_SAMPLERATE
,
127 format
->sample_rate
) != AACENC_OK
) {
128 fprintf(stderr
, "ERROR: unsupported sample rate\n");
131 if (aacEncoder_SetParam(*encoder
, AACENC_CHANNELMODE
,
132 channel_mode
) != AACENC_OK
) {
133 fprintf(stderr
, "ERROR: unsupported channel mode\n");
136 aacEncoder_SetParam(*encoder
, AACENC_BANDWIDTH
, params
->bandwidth
);
137 aacEncoder_SetParam(*encoder
, AACENC_CHANNELORDER
, 1);
138 aacEncoder_SetParam(*encoder
, AACENC_AFTERBURNER
, !!params
->afterburner
);
140 aacEncoder_SetParam(*encoder
, AACENC_SBR_MODE
, params
->lowdelay_sbr
);
142 #if AACENCODER_LIB_VL0 > 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1>=4)
143 if (lib_info
.version
> 0x03040000)
144 aacEncoder_SetParam(*encoder
, AACENC_SBR_RATIO
, params
->sbr_ratio
);
147 if (aacEncoder_SetParam(*encoder
, AACENC_TRANSMUX
,
148 params
->transport_format
) != AACENC_OK
) {
149 fprintf(stderr
, "ERROR: unsupported transport format\n");
152 if (aacEncoder_SetParam(*encoder
, AACENC_SIGNALING_MODE
,
153 params
->sbr_signaling
) != AACENC_OK
) {
154 fprintf(stderr
, "ERROR: failed to set SBR signaling mode\n");
157 if (params
->adts_crc_check
)
158 aacEncoder_SetParam(*encoder
, AACENC_PROTECTION
, 1);
159 if (params
->header_period
)
160 aacEncoder_SetParam(*encoder
, AACENC_HEADER_PERIOD
,
161 params
->header_period
);
163 if (aacEncEncode(*encoder
, 0, 0, 0, 0) != AACENC_OK
) {
164 fprintf(stderr
, "ERROR: encoder initialization failed\n");
167 if (aacEncInfo(*encoder
, info
) != AACENC_OK
) {
168 fprintf(stderr
, "ERROR: cannot retrieve encoder info\n");
174 aacEncClose(encoder
);
178 int aac_encode_frame(HANDLE_AACENCODER encoder
,
179 const pcm_sample_description_t
*format
,
180 const int16_t *input
, unsigned iframes
,
181 aacenc_frame_t
*output
)
183 uint32_t ilen
= iframes
* format
->channels_per_frame
;
184 AACENC_BufDesc ibdesc
= { 0 }, obdesc
= { 0 };
185 AACENC_InArgs iargs
= { 0 };
186 AACENC_OutArgs oargs
= { 0 };
187 void *ibufs
[] = { (void*)input
};
189 INT ibuf_ids
[] = { IN_AUDIO_DATA
};
190 INT obuf_ids
[] = { OUT_BITSTREAM_DATA
};
191 INT ibuf_sizes
[] = { ilen
* sizeof(int16_t) };
193 INT ibuf_el_sizes
[] = { sizeof(int16_t) };
194 INT obuf_el_sizes
[] = { 1 };
196 unsigned channel_mode
, obytes
;
198 channel_mode
= aacEncoder_GetParam(encoder
, AACENC_CHANNELMODE
);
199 obytes
= 6144 / 8 * channel_mode
;
200 if (!output
->data
|| output
->capacity
< obytes
) {
201 uint8_t *p
= realloc(output
->data
, obytes
);
203 output
->capacity
= obytes
;
206 obufs
[0] = output
->data
;
207 obuf_sizes
[0] = obytes
;
209 iargs
.numInSamples
= ilen
? ilen
: -1; /* -1 for signaling EOF */
212 ibdesc
.bufferIdentifiers
= ibuf_ids
;
213 ibdesc
.bufSizes
= ibuf_sizes
;
214 ibdesc
.bufElSizes
= ibuf_el_sizes
;
217 obdesc
.bufferIdentifiers
= obuf_ids
;
218 obdesc
.bufSizes
= obuf_sizes
;
219 obdesc
.bufElSizes
= obuf_el_sizes
;
221 err
= aacEncEncode(encoder
, &ibdesc
, &obdesc
, &iargs
, &oargs
);
222 if (err
!= AACENC_ENCODE_EOF
&& err
!= AACENC_OK
) {
223 fprintf(stderr
, "ERROR: aacEncEncode() failed\n");
226 output
->size
= oargs
.numOutBytes
;
227 return oargs
.numInSamples
/ format
->channels_per_frame
;