1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2000-2017
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / AAC FAAD2 decoder filter
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 #include <gpac/filters.h>
27 #include <gpac/constants.h>
28 
29 #ifdef GPAC_HAS_FAAD
30 
31 #ifdef __GNUC__
32 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
33 #endif
34 
35 #if !defined(__GNUC__)
36 # if defined(_WIN32_WCE) || defined (WIN32)
37 #  pragma comment(lib, "libfaad")
38 # endif
39 #endif
40 
41 #include <neaacdec.h>
42 #include <gpac/constants.h>
43 #include <gpac/avparse.h>
44 
45 
46 typedef struct
47 {
48 	NeAACDecHandle codec;
49 	NeAACDecFrameInfo info;	u32 sample_rate, timescale, num_samples;
50 	u8 num_channels;
51 
52 	GF_FilterPid *ipid, *opid;
53 	u32 cfg_crc;
54 
55 	Bool signal_mc;
56 	Bool is_sbr;
57 
58 	u32 channel_mask;
59 	char ch_reorder[16];
60 	u64 last_cts;
61 } GF_FAADCtx;
62 
faaddec_check_mc_config(GF_FAADCtx * ctx)63 static void faaddec_check_mc_config(GF_FAADCtx *ctx)
64 {
65 	u32 i, channel_mask = 0;
66 	for (i=0; i<ctx->num_channels; i++) {
67 		switch (ctx->info.channel_position[i]) {
68 		case FRONT_CHANNEL_CENTER:
69 			channel_mask |= GF_AUDIO_CH_FRONT_CENTER;
70 			break;
71 		case FRONT_CHANNEL_LEFT:
72 			channel_mask |= GF_AUDIO_CH_FRONT_LEFT;
73 			break;
74 		case FRONT_CHANNEL_RIGHT:
75 			channel_mask |= GF_AUDIO_CH_FRONT_RIGHT;
76 			break;
77 		case SIDE_CHANNEL_LEFT:
78 			channel_mask |= GF_AUDIO_CH_REAR_SURROUND_LEFT;
79 			break;
80 		case SIDE_CHANNEL_RIGHT:
81 			channel_mask |= GF_AUDIO_CH_REAR_SURROUND_RIGHT;
82 			break;
83 		case BACK_CHANNEL_LEFT:
84 			channel_mask |= GF_AUDIO_CH_SURROUND_LEFT;
85 			break;
86 		case BACK_CHANNEL_RIGHT:
87 			channel_mask |= GF_AUDIO_CH_SURROUND_RIGHT;
88 			break;
89 		case BACK_CHANNEL_CENTER:
90 			channel_mask |= GF_AUDIO_CH_REAR_CENTER;
91 			break;
92 		case LFE_CHANNEL:
93 			channel_mask |= GF_AUDIO_CH_LFE;
94 			break;
95 		default:
96 			break;
97 		}
98 	}
99 	if (ctx->channel_mask != channel_mask) {
100 		ctx->channel_mask = channel_mask;
101 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(channel_mask) );
102 	}
103 }
104 
faaddec_configure_pid(GF_Filter * filter,GF_FilterPid * pid,Bool is_remove)105 static GF_Err faaddec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
106 {
107 	const GF_PropertyValue *p;
108 	GF_FAADCtx *ctx = gf_filter_get_udta(filter);
109 #ifndef GPAC_DISABLE_AV_PARSERS
110 	GF_Err e;
111 	GF_M4ADecSpecInfo a_cfg;
112 #endif
113 
114 	if (is_remove) {
115 		if (ctx->opid) gf_filter_pid_remove(ctx->opid);
116 		ctx->opid = NULL;
117 		ctx->ipid = NULL;
118 		return GF_OK;
119 	}
120 	if (! gf_filter_pid_check_caps(pid))
121 		return GF_NOT_SUPPORTED;
122 
123 	if (!ctx->opid) {
124 		ctx->opid = gf_filter_pid_new(filter);
125 	}
126 	//copy properties at init or reconfig
127 	gf_filter_pid_copy_properties(ctx->opid, pid);
128 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, &PROP_UINT(GF_CODECID_RAW) );
129 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_AUDIO_FORMAT, &PROP_UINT(GF_AUDIO_FMT_S16) );
130 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG, NULL );
131 	ctx->ipid = pid;
132 
133 
134 	p = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
135 	if (p && p->value.data.ptr && p->value.data.size) {
136 		u32 ex_crc = gf_crc_32(p->value.data.ptr, p->value.data.size);
137 		if (ctx->cfg_crc && (ctx->cfg_crc != ex_crc)) {
138 			//shoud we flush ?
139 			if (ctx->codec) NeAACDecClose(ctx->codec);
140 			ctx->codec = NULL;
141 		}
142 	} else {
143 		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] Reconfiguring but no DSI set, skipping\n"));
144 		return GF_OK;
145 	}
146 
147 	ctx->codec = NeAACDecOpen();
148 	if (!ctx->codec) {
149 		GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error initializing decoder\n"));
150 		return GF_IO_ERR;
151 	}
152 
153 #ifndef GPAC_DISABLE_AV_PARSERS
154 	e = gf_m4a_get_config(p->value.data.ptr, p->value.data.size, &a_cfg);
155 	if (e) return e;
156 #endif
157 	if (NeAACDecInit2(ctx->codec, (unsigned char *)p->value.data.ptr, p->value.data.size, (unsigned long*)&ctx->sample_rate, (u8*)&ctx->num_channels) < 0)
158 	{
159 #ifndef GPAC_DISABLE_AV_PARSERS
160 		s8 res;
161 		u8 *dsi, *s_base_object_type;
162 		u32 dsi_len;
163 		switch (a_cfg.base_object_type) {
164 		case GF_M4A_AAC_MAIN:
165 			s_base_object_type = gf_stringizer(GF_M4A_AAC_MAIN);
166 			goto base_object_type_error;
167 		case GF_M4A_AAC_LC:
168 			s_base_object_type = gf_stringizer(GF_M4A_AAC_LC);
169 			goto base_object_type_error;
170 		case GF_M4A_AAC_SSR:
171 			s_base_object_type = gf_stringizer(GF_M4A_AAC_SSR);
172 			goto base_object_type_error;
173 		case GF_M4A_AAC_LTP:
174 			s_base_object_type = gf_stringizer(GF_M4A_AAC_LTP);
175 			goto base_object_type_error;
176 		case GF_M4A_AAC_SBR:
177 			s_base_object_type = gf_stringizer(GF_M4A_AAC_SBR);
178 			goto base_object_type_error;
179 		case GF_M4A_AAC_PS:
180 			s_base_object_type = gf_stringizer(GF_M4A_AAC_PS);
181 base_object_type_error: /*error case*/
182 			GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error: unsupported %s format for stream - defaulting to AAC LC\n", s_base_object_type));
183 		default:
184 			break;
185 		}
186 		a_cfg.base_object_type = GF_M4A_AAC_LC;
187 		a_cfg.has_sbr = GF_FALSE;
188 		a_cfg.nb_chan = a_cfg.nb_chan > 2 ? 1 : a_cfg.nb_chan;
189 
190 		gf_m4a_write_config(&a_cfg, &dsi, &dsi_len);
191 		res = NeAACDecInit2(ctx->codec, (unsigned char *) dsi, dsi_len, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels);
192 		gf_free(dsi);
193 		if (res < 0)
194 #endif
195 		{
196 			GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error when initializing AAC decoder for stream\n"));
197 			return GF_NOT_SUPPORTED;
198 		}
199 	}
200 
201 #ifndef GPAC_DISABLE_AV_PARSERS
202 	ctx->is_sbr = a_cfg.has_sbr;
203 #endif
204 	ctx->num_samples = 1024;
205 	ctx->signal_mc = ctx->num_channels>2 ? GF_TRUE : GF_FALSE;
206 
207 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLE_RATE, &PROP_UINT(ctx->sample_rate) );
208 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLES_PER_FRAME, &PROP_UINT(ctx->num_samples) );
209 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(ctx->num_channels) );
210 
211 #if 0
212 	if (!strcmp(FAAD2_VERSION, "unknown")) {
213 		if (ctx->is_sbr) gf_filter_set_name(filter, "dec_faad:FAAD2-" FAAD2_VERSION "-SBR");
214 		else gf_filter_set_name(filter,  "dec_faad:FAAD2-" FAAD2_VERSION);
215 	} else
216 #endif
217 	{
218 		if (ctx->is_sbr) gf_filter_set_name(filter, "dec_faad:FAAD2-SBR");
219 		else gf_filter_set_name(filter,  "dec_faad:FAAD2");
220 	}
221 	gf_filter_pid_set_framing_mode(pid, GF_TRUE);
222 	return GF_OK;
223 }
224 
faaddec_get_channel_pos(GF_FAADCtx * ffd,u32 ch_cfg)225 static s8 faaddec_get_channel_pos(GF_FAADCtx *ffd, u32 ch_cfg)
226 {
227 	u32 i;
228 	for (i=0; i<ffd->info.channels; i++) {
229 		switch (ffd->info.channel_position[i]) {
230 		case FRONT_CHANNEL_CENTER:
231 			if (ch_cfg==GF_AUDIO_CH_FRONT_CENTER) return i;
232 			break;
233 		case FRONT_CHANNEL_LEFT:
234 			if (ch_cfg==GF_AUDIO_CH_FRONT_LEFT) return i;
235 			break;
236 		case FRONT_CHANNEL_RIGHT:
237 			if (ch_cfg==GF_AUDIO_CH_FRONT_RIGHT) return i;
238 			break;
239 		case SIDE_CHANNEL_LEFT:
240 			if (ch_cfg==GF_AUDIO_CH_REAR_SURROUND_LEFT) return i;
241 			break;
242 		case SIDE_CHANNEL_RIGHT:
243 			if (ch_cfg==GF_AUDIO_CH_REAR_SURROUND_RIGHT) return i;
244 			break;
245 		case BACK_CHANNEL_LEFT:
246 			if (ch_cfg==GF_AUDIO_CH_SURROUND_LEFT) return i;
247 			break;
248 		case BACK_CHANNEL_RIGHT:
249 			if (ch_cfg==GF_AUDIO_CH_SURROUND_RIGHT) return i;
250 			break;
251 		case BACK_CHANNEL_CENTER:
252 			if (ch_cfg==GF_AUDIO_CH_REAR_CENTER) return i;
253 			break;
254 		case LFE_CHANNEL:
255 			if (ch_cfg==GF_AUDIO_CH_LFE) return i;
256 			break;
257 		}
258 	}
259 	return -1;
260 }
261 
faaddec_process(GF_Filter * filter)262 static GF_Err faaddec_process(GF_Filter *filter)
263 {
264 	GF_FAADCtx *ctx = gf_filter_get_udta(filter);
265 	void *buffer;
266 	u8 *output;
267 	u32 i, j;
268 	Bool is_eos = GF_FALSE;
269 	GF_FilterPacket *dst_pck;
270 	GF_FilterPacket *pck = gf_filter_pid_get_packet(ctx->ipid);
271 
272 	if (!pck) {
273 		is_eos = gf_filter_pid_is_eos(ctx->ipid);
274 		if (!is_eos) return GF_OK;
275 	}
276 
277 	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] Decoding AU\n"));
278 	if (!pck) {
279 		buffer = NeAACDecDecode(ctx->codec, &ctx->info, NULL, 0);
280 	} else {
281 		Bool start, end;
282 		u32 size;
283 		const char *data = gf_filter_pck_get_data(pck, &size);
284 		buffer = NeAACDecDecode(ctx->codec, &ctx->info, (char *) data, size);
285 
286 		gf_filter_pck_get_framing(pck, &start, &end);
287 		assert(start && end);
288 	}
289 
290 	if (ctx->info.error>0) {
291 		GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error decoding AU %s\n", NeAACDecGetErrorMessage(ctx->info.error) ));
292 		if (pck) gf_filter_pid_drop_packet(ctx->ipid);
293 		return GF_NON_COMPLIANT_BITSTREAM;
294 	}
295 	if (!ctx->info.samples || !buffer || !ctx->info.bytesconsumed) {
296 		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] empty/non complete AU\n"));
297 		if (is_eos) gf_filter_pid_set_eos(ctx->opid);
298 		if (pck) gf_filter_pid_drop_packet(ctx->ipid);
299 		return GF_OK;
300 	}
301 	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] AU decoded\n"));
302 
303 	/*FAAD froces us to decode a frame to get channel cfg*/
304 	if (ctx->signal_mc) {
305 		s32 ch, idx;
306 		ctx->signal_mc = GF_FALSE;
307 		idx = 0;
308 		/*NOW WATCH OUT!! FAAD may very well decide to output more channels than indicated!!!*/
309 		ctx->num_channels = ctx->info.channels;
310 
311 		/*get cfg*/
312 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_FRONT_LEFT);
313 		if (ch>=0) {
314 			ctx->ch_reorder[idx] = ch;
315 			idx++;
316 		}
317 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_FRONT_RIGHT);
318 		if (ch>=0) {
319 			ctx->ch_reorder[idx] = ch;
320 			idx++;
321 		}
322 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_FRONT_CENTER);
323 		if (ch>=0) {
324 			ctx->ch_reorder[idx] = ch;
325 			idx++;
326 		}
327 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_LFE);
328 		if (ch>=0) {
329 			ctx->ch_reorder[idx] = ch;
330 			idx++;
331 		}
332 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_SURROUND_LEFT);
333 		if (ch>=0) {
334 			ctx->ch_reorder[idx] = ch;
335 			idx++;
336 		}
337 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_SURROUND_RIGHT);
338 		if (ch>=0) {
339 			ctx->ch_reorder[idx] = ch;
340 			idx++;
341 		}
342 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_REAR_CENTER);
343 		if (ch>=0) {
344 			ctx->ch_reorder[idx] = ch;
345 			idx++;
346 		}
347 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_REAR_SURROUND_LEFT);
348 		if (ch>=0) {
349 			ctx->ch_reorder[idx] = ch;
350 			idx++;
351 		}
352 		ch = faaddec_get_channel_pos(ctx, GF_AUDIO_CH_REAR_SURROUND_RIGHT);
353 		if (ch>=0) {
354 			ctx->ch_reorder[idx] = ch;
355 			//last one, no need to increment idx++;
356 		}
357 		faaddec_check_mc_config(ctx);
358 	}
359 
360 	dst_pck = gf_filter_pck_new_alloc(ctx->opid, (u32) (sizeof(short) * ctx->info.samples), &output);
361 	if (!dst_pck) {
362 		if (pck) gf_filter_pid_drop_packet(ctx->ipid);
363 		return GF_OUT_OF_MEM;
364 	}
365 	if (pck) {
366 		ctx->last_cts = gf_filter_pck_get_cts(pck);
367 		ctx->timescale = gf_filter_pck_get_timescale(pck);
368 		gf_filter_pck_merge_properties(pck, dst_pck);
369 	}
370 	gf_filter_pck_set_cts(dst_pck, ctx->last_cts);
371 	if (ctx->timescale != ctx->sample_rate) {
372 		u64 dur =ctx->info.samples * ctx->timescale;
373 		dur /= ctx->sample_rate;
374 		gf_filter_pck_set_duration(dst_pck, (u32) dur);
375 		ctx->last_cts += dur;
376 	} else {
377 		gf_filter_pck_set_duration(dst_pck, (u32) ctx->info.samples);
378 		ctx->last_cts += ctx->info.samples;
379 	}
380 	/*we assume left/right order*/
381 	if (ctx->num_channels<=2) {
382 		memcpy(output, buffer, sizeof(short)* ctx->info.samples);
383 	} else {
384 		unsigned short *conv_in, *conv_out;
385 		conv_in = (unsigned short *) buffer;
386 		conv_out = (unsigned short *) output;
387 		for (i=0; i<ctx->info.samples; i+=ctx->info.channels) {
388 			for (j=0; j<ctx->info.channels; j++) {
389 				conv_out[i + j] = conv_in[i + ctx->ch_reorder[j]];
390 			}
391 		}
392 	}
393 	gf_filter_pck_send(dst_pck);
394 	if (pck) gf_filter_pid_drop_packet(ctx->ipid);
395 	return GF_OK;
396 }
397 
398 static const GF_FilterCapability FAADCaps[] =
399 {
400 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_STREAM_TYPE, GF_STREAM_AUDIO),
401 	CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
402 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG4),
403 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG2_MP),
404 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG2_LCP),
405 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG2_SSRP),
406 	CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_AUDIO),
407 	CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW),
408 };
409 
410 GF_FilterRegister FAADRegister = {
411 	.name = "faad",
412 	GF_FS_SET_DESCRIPTION("FAAD decoder")
413 	GF_FS_SET_HELP("This filter decodes AAC streams through faad library.")
414 	.private_size = sizeof(GF_FAADCtx),
415 	.priority = 1,
416 	SETCAPS(FAADCaps),
417 	.configure_pid = faaddec_configure_pid,
418 	.process = faaddec_process,
419 };
420 
421 #endif
422 
faad_register(GF_FilterSession * session)423 const GF_FilterRegister *faad_register(GF_FilterSession *session)
424 {
425 #ifdef GPAC_HAS_FAAD
426 	return &FAADRegister;
427 #else
428 	return NULL;
429 #endif
430 }
431