a6984fec8a94aa0216a7d02dea358f8879bf2717
[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_ratio_available()
17 {
18 #if AACENCODER_LIB_VL0 < 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1<4)
19 return 0;
20 #else
21 LIB_INFO lib_info;
22 aacenc_get_lib_info(&lib_info);
23 return lib_info.version > 0x03040000;
24 #endif
25 }
26
27 int aacenc_is_sbr_active(const aacenc_param_t *params)
28 {
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:
33 return 1;
34 }
35 if (params->profile == AOT_ER_AAC_ELD && params->lowdelay_sbr)
36 return 1;
37 return 0;
38 }
39
40 int aacenc_is_dual_rate_sbr(const aacenc_param_t *params)
41 {
42 if (params->profile == AOT_PS || params->profile == AOT_MP2_PS)
43 return 1;
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;
48 return 0;
49 }
50
51 void aacenc_get_lib_info(LIB_INFO *info)
52 {
53 LIB_INFO *lib_info = 0;
54 lib_info = calloc(FDK_MODULE_LAST, sizeof(LIB_INFO));
55 if (aacEncGetLibInfo(lib_info) == AACENC_OK) {
56 int i;
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));
60 break;
61 }
62 }
63 }
64 free(lib_info);
65 }
66
67 static
68 int aacenc_channel_mode(const pcm_sample_description_t *format)
69 {
70 uint32_t chanmask = format->channel_mask;
71
72 if (format->channels_per_frame > 8)
73 return 0;
74 if (!chanmask) {
75 static uint32_t defaults[] = { 0x4, 0x3, 0x7, 0, 0x37, 0x3f, 0, 0x63f };
76 chanmask = defaults[format->channels_per_frame - 1];
77 }
78 switch (chanmask) {
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;
90 #endif
91 }
92 return 0;
93 }
94
95 int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params,
96 const pcm_sample_description_t *format,
97 AACENC_InfoStruct *info)
98 {
99 int channel_mode;
100 int aot;
101 LIB_INFO lib_info;
102
103 *encoder = 0;
104 aacenc_get_lib_info(&lib_info);
105
106 if ((channel_mode = aacenc_channel_mode(format)) == 0) {
107 fprintf(stderr, "ERROR: unsupported channel layout\n");
108 goto FAIL;
109 }
110 if (aacEncOpen(encoder, 0, 0) != AACENC_OK) {
111 fprintf(stderr, "ERROR: aacEncOpen() failed\n");
112 goto FAIL;
113 }
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");
117 goto FAIL;
118 }
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");
124 goto FAIL;
125 }
126 if (aacEncoder_SetParam(*encoder, AACENC_SAMPLERATE,
127 format->sample_rate) != AACENC_OK) {
128 fprintf(stderr, "ERROR: unsupported sample rate\n");
129 goto FAIL;
130 }
131 if (aacEncoder_SetParam(*encoder, AACENC_CHANNELMODE,
132 channel_mode) != AACENC_OK) {
133 fprintf(stderr, "ERROR: unsupported channel mode\n");
134 goto FAIL;
135 }
136 aacEncoder_SetParam(*encoder, AACENC_BANDWIDTH, params->bandwidth);
137 aacEncoder_SetParam(*encoder, AACENC_CHANNELORDER, 1);
138 aacEncoder_SetParam(*encoder, AACENC_AFTERBURNER, !!params->afterburner);
139
140 aacEncoder_SetParam(*encoder, AACENC_SBR_MODE, params->lowdelay_sbr);
141
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);
145 #endif
146
147 if (aacEncoder_SetParam(*encoder, AACENC_TRANSMUX,
148 params->transport_format) != AACENC_OK) {
149 fprintf(stderr, "ERROR: unsupported transport format\n");
150 goto FAIL;
151 }
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");
155 goto FAIL;
156 }
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);
162
163 if (aacEncEncode(*encoder, 0, 0, 0, 0) != AACENC_OK) {
164 fprintf(stderr, "ERROR: encoder initialization failed\n");
165 goto FAIL;
166 }
167 if (aacEncInfo(*encoder, info) != AACENC_OK) {
168 fprintf(stderr, "ERROR: cannot retrieve encoder info\n");
169 goto FAIL;
170 }
171 return 0;
172 FAIL:
173 if (encoder)
174 aacEncClose(encoder);
175 return -1;
176 }
177
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)
182 {
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 };
188 void *obufs[1];
189 INT ibuf_ids[] = { IN_AUDIO_DATA };
190 INT obuf_ids[] = { OUT_BITSTREAM_DATA };
191 INT ibuf_sizes[] = { ilen * sizeof(int16_t) };
192 INT obuf_sizes[1];
193 INT ibuf_el_sizes[] = { sizeof(int16_t) };
194 INT obuf_el_sizes[] = { 1 };
195 AACENC_ERROR err;
196 unsigned channel_mode, obytes;
197
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);
202 if (!p) return -1;
203 output->capacity = obytes;
204 output->data = p;
205 }
206 obufs[0] = output->data;
207 obuf_sizes[0] = obytes;
208
209 iargs.numInSamples = ilen ? ilen : -1; /* -1 for signaling EOF */
210 ibdesc.numBufs = 1;
211 ibdesc.bufs = ibufs;
212 ibdesc.bufferIdentifiers = ibuf_ids;
213 ibdesc.bufSizes = ibuf_sizes;
214 ibdesc.bufElSizes = ibuf_el_sizes;
215 obdesc.numBufs = 1;
216 obdesc.bufs = obufs;
217 obdesc.bufferIdentifiers = obuf_ids;
218 obdesc.bufSizes = obuf_sizes;
219 obdesc.bufElSizes = obuf_el_sizes;
220
221 err = aacEncEncode(encoder, &ibdesc, &obdesc, &iargs, &oargs);
222 if (err != AACENC_ENCODE_EOF && err != AACENC_OK) {
223 fprintf(stderr, "ERROR: aacEncEncode() failed\n");
224 return -1;
225 }
226 output->size = oargs.numOutBytes;
227 return oargs.numInSamples / format->channels_per_frame;
228 }
This page took 0.027357 seconds and 3 git commands to generate.