support 7.1 channel mode added on FDK 3.4.12
[fdkaac.git] / src / aacenc.c
1 /*
2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
4 */
5 #if HAVE_CONFIG_H
6 # include "config.h"
7 #endif
8 #if HAVE_STDINT_H
9 # include <stdint.h>
10 #endif
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include "aacenc.h"
15
16 int aacenc_is_sbr_active(const aacenc_param_t *params)
17 {
18 switch (params->profile) {
19 case AOT_SBR: case AOT_PS: case AOT_MP2_SBR: case AOT_MP2_PS:
20 case AOT_DABPLUS_SBR: case AOT_DABPLUS_PS:
21 case AOT_DRM_SBR: case AOT_DRM_MPEG_PS:
22 return 1;
23 }
24 if (params->profile == AOT_ER_AAC_ELD && params->lowdelay_sbr)
25 return 1;
26 return 0;
27 }
28
29 static const unsigned aacenc_sampling_freq_tab[] = {
30 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
31 16000, 12000, 11025, 8000, 7350, 0, 0, 0
32 };
33
34 static
35 unsigned sampling_freq_index(unsigned rate)
36 {
37 unsigned i;
38 for (i = 0; aacenc_sampling_freq_tab[i]; ++i)
39 if (aacenc_sampling_freq_tab[i] == rate)
40 return i;
41 return 0xf;
42 }
43
44 /*
45 * Append backward compatible SBR/PS signaling to implicit signaling ASC,
46 * if SBR/PS is present.
47 */
48 int aacenc_mp4asc(const aacenc_param_t *params,
49 const uint8_t *asc, uint32_t ascsize,
50 uint8_t *outasc, uint32_t *outsize)
51 {
52 unsigned asc_sfreq = aacenc_sampling_freq_tab[(asc[0]&0x7)<<1 |asc[1]>>7];
53
54 switch (params->profile) {
55 case AOT_SBR:
56 case AOT_PS:
57 if (*outsize < ascsize + 3)
58 return -1;
59 memcpy(outasc, asc, ascsize);
60 /* syncExtensionType:11 (value:0x2b7) */
61 outasc[ascsize+0] = 0x2b << 1;
62 outasc[ascsize+1] = 0x7 << 5;
63 /* extensionAudioObjectType:5 (value:5)*/
64 outasc[ascsize+1] |= 5;
65 /* sbrPresentFlag:1 (value:1) */
66 outasc[ascsize+2] = 0x80;
67 /* extensionSamplingFrequencyIndex:4 */
68 outasc[ascsize+2] |= sampling_freq_index(asc_sfreq << 1) << 3;
69 if (params->profile == AOT_SBR) {
70 *outsize = ascsize + 3;
71 break;
72 }
73 if (*outsize < ascsize + 5)
74 return -1;
75 /* syncExtensionType:11 (value:0x548) */
76 outasc[ascsize+2] |= 0x5;
77 outasc[ascsize+3] = 0x48;
78 /* psPresentFlag:1 (value:1) */
79 outasc[ascsize+4] = 0x80;
80 *outsize = ascsize + 5;
81 break;
82 default:
83 if (*outsize < ascsize)
84 return -1;
85 memcpy(outasc, asc, ascsize);
86 *outsize = ascsize;
87 }
88 return 0;
89 }
90
91 static
92 int aacenc_channel_mode(const pcm_sample_description_t *format)
93 {
94 uint32_t chanmask = format->channel_mask;
95
96 if (format->channels_per_frame > 8)
97 return 0;
98 if (!chanmask) {
99 static uint32_t defaults[] = { 0x4, 0x3, 0x7, 0, 0x37, 0x3f, 0, 0x63f };
100 chanmask = defaults[format->channels_per_frame - 1];
101 }
102 switch (chanmask) {
103 case 0x3: return MODE_2;
104 case 0x4: return MODE_1;
105 case 0x7: return MODE_1_2;
106 case 0x37: return MODE_1_2_2;
107 case 0x3f: return MODE_1_2_2_1;
108 case 0x107: return MODE_1_2_1;
109 case 0x607: return MODE_1_2_2;
110 case 0x60f: return MODE_1_2_2_1;
111 #if AACENCODER_LIB_VL0 > 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1>=4)
112 case 0xff: return MODE_1_2_2_2_1;
113 case 0x63f: return MODE_7_1_REAR_SURROUND;
114 #endif
115 }
116 return 0;
117 }
118
119 int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params,
120 const pcm_sample_description_t *format,
121 AACENC_InfoStruct *info)
122 {
123 int channel_mode;
124 int aot;
125
126 *encoder = 0;
127 if ((channel_mode = aacenc_channel_mode(format)) == 0) {
128 fprintf(stderr, "ERROR: unsupported channel layout\n");
129 goto FAIL;
130 }
131 if (aacEncOpen(encoder, 0, 0) != AACENC_OK) {
132 fprintf(stderr, "ERROR: aacEncOpen() failed\n");
133 goto FAIL;
134 }
135 aot = (params->profile ? params->profile : AOT_AAC_LC);
136 if (aacEncoder_SetParam(*encoder, AACENC_AOT, aot) != AACENC_OK) {
137 fprintf(stderr, "ERROR: unsupported profile\n");
138 goto FAIL;
139 }
140 if (params->bitrate_mode == 0)
141 aacEncoder_SetParam(*encoder, AACENC_BITRATE, params->bitrate);
142 else if (aacEncoder_SetParam(*encoder, AACENC_BITRATEMODE,
143 params->bitrate_mode) != AACENC_OK) {
144 fprintf(stderr, "ERROR: unsupported bitrate mode\n");
145 goto FAIL;
146 }
147 if (aacEncoder_SetParam(*encoder, AACENC_SAMPLERATE,
148 format->sample_rate) != AACENC_OK) {
149 fprintf(stderr, "ERROR: unsupported sample rate\n");
150 goto FAIL;
151 }
152 aacEncoder_SetParam(*encoder, AACENC_CHANNELMODE, channel_mode);
153 aacEncoder_SetParam(*encoder, AACENC_BANDWIDTH, params->bandwidth);
154 aacEncoder_SetParam(*encoder, AACENC_CHANNELORDER, 1);
155 aacEncoder_SetParam(*encoder, AACENC_AFTERBURNER, !!params->afterburner);
156
157 if (aot == AOT_ER_AAC_ELD && params->lowdelay_sbr)
158 aacEncoder_SetParam(*encoder, AACENC_SBR_MODE, 1);
159
160 if (aacEncoder_SetParam(*encoder, AACENC_TRANSMUX,
161 params->transport_format) != AACENC_OK) {
162 fprintf(stderr, "ERROR: unsupported transport format\n");
163 goto FAIL;
164 }
165 if (aacEncoder_SetParam(*encoder, AACENC_SIGNALING_MODE,
166 params->sbr_signaling) != AACENC_OK) {
167 fprintf(stderr, "ERROR: failed to set SBR signaling mode\n");
168 goto FAIL;
169 }
170 if (params->adts_crc_check)
171 aacEncoder_SetParam(*encoder, AACENC_PROTECTION, 1);
172 if (params->header_period)
173 aacEncoder_SetParam(*encoder, AACENC_HEADER_PERIOD,
174 params->header_period);
175
176 if (aacEncEncode(*encoder, 0, 0, 0, 0) != AACENC_OK) {
177 fprintf(stderr, "ERROR: encoder initialization failed\n");
178 goto FAIL;
179 }
180 if (aacEncInfo(*encoder, info) != AACENC_OK) {
181 fprintf(stderr, "ERROR: cannot retrieve encoder info\n");
182 goto FAIL;
183 }
184 return 0;
185 FAIL:
186 if (encoder)
187 aacEncClose(encoder);
188 return -1;
189 }
190
191 int aac_encode_frame(HANDLE_AACENCODER encoder,
192 const pcm_sample_description_t *format,
193 const int16_t *input, unsigned iframes,
194 aacenc_frame_t *output)
195 {
196 uint32_t ilen = iframes * format->channels_per_frame;
197 AACENC_BufDesc ibdesc = { 0 }, obdesc = { 0 };
198 AACENC_InArgs iargs = { 0 };
199 AACENC_OutArgs oargs = { 0 };
200 void *ibufs[] = { (void*)input };
201 void *obufs[1];
202 INT ibuf_ids[] = { IN_AUDIO_DATA };
203 INT obuf_ids[] = { OUT_BITSTREAM_DATA };
204 INT ibuf_sizes[] = { ilen * sizeof(int16_t) };
205 INT obuf_sizes[1];
206 INT ibuf_el_sizes[] = { sizeof(int16_t) };
207 INT obuf_el_sizes[] = { 1 };
208 AACENC_ERROR err;
209 unsigned channel_mode, obytes;
210
211 channel_mode = aacEncoder_GetParam(encoder, AACENC_CHANNELMODE);
212 obytes = 6144 / 8 * channel_mode;
213 if (!output->data || output->capacity < obytes) {
214 uint8_t *p = realloc(output->data, obytes);
215 if (!p) return -1;
216 output->capacity = obytes;
217 output->data = p;
218 }
219 obufs[0] = output->data;
220 obuf_sizes[0] = obytes;
221
222 iargs.numInSamples = ilen ? ilen : -1; /* -1 for signaling EOF */
223 ibdesc.numBufs = 1;
224 ibdesc.bufs = ibufs;
225 ibdesc.bufferIdentifiers = ibuf_ids;
226 ibdesc.bufSizes = ibuf_sizes;
227 ibdesc.bufElSizes = ibuf_el_sizes;
228 obdesc.numBufs = 1;
229 obdesc.bufs = obufs;
230 obdesc.bufferIdentifiers = obuf_ids;
231 obdesc.bufSizes = obuf_sizes;
232 obdesc.bufElSizes = obuf_el_sizes;
233
234 err = aacEncEncode(encoder, &ibdesc, &obdesc, &iargs, &oargs);
235 if (err != AACENC_ENCODE_EOF && err != AACENC_OK) {
236 fprintf(stderr, "ERROR: aacEncEncode() failed\n");
237 return -1;
238 }
239 output->size = oargs.numOutBytes;
240 return oargs.numInSamples / format->channels_per_frame;
241 }
This page took 0.028739 seconds and 4 git commands to generate.