1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2000-2020
6 * All rights reserved
7 *
8 * This file is part of GPAC / AAC ADTS reframer 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/avparse.h>
27 #include <gpac/constants.h>
28 #include <gpac/filters.h>
29
30 #ifndef GPAC_DISABLE_AV_PARSERS
31
32 enum
33 {
34 AAC_SIGNAL_NONE=0,
35 AAC_SIGNAL_IMPLICIT,
36 AAC_SIGNAL_EXPLICIT
37 };
38
39 typedef struct
40 {
41 Bool is_mp2, no_crc;
42 u32 profile, sr_idx, nb_ch, frame_size, hdr_size;
43 } ADTSHeader;
44
45 typedef struct
46 {
47 u64 pos;
48 Double duration;
49 } ADTSIdx;
50
51 typedef struct
52 {
53 //filter args
54 u32 frame_size;
55 Double index;
56 u32 sbr;
57 u32 ps;
58 // Bool mpeg4;
59 Bool ovsbr;
60 Bool expart;
61
62 //only one input pid declared
63 GF_FilterPid *ipid;
64 //output pid for audio
65 GF_FilterPid *opid;
66
67 //video pid for cover art
68 GF_FilterPid *vpid;
69
70 GF_BitStream *bs;
71 u64 file_pos, cts;
72 u32 sr_idx, nb_ch, is_mp2, profile;
73 GF_Fraction64 duration;
74 Double start_range;
75 Bool in_seek;
76 u32 timescale;
77
78 ADTSHeader hdr;
79 u32 dts_inc;
80
81 Bool is_playing;
82 Bool is_file, file_loaded;
83 Bool initial_play_done;
84
85 GF_FilterPacket *src_pck;
86
87 ADTSIdx *indexes;
88 u32 index_alloc_size, index_size;
89
90 u8 *adts_buffer;
91 u32 adts_buffer_size, adts_buffer_alloc, resume_from;
92 u64 byte_offset;
93
94 u32 tag_size;
95 u8 *id3_buffer;
96 u32 id3_buffer_size, id3_buffer_alloc;
97 u32 nb_frames;
98 } GF_ADTSDmxCtx;
99
100
adts_dmx_sync_frame_bs(GF_BitStream * bs,ADTSHeader * hdr)101 static Bool adts_dmx_sync_frame_bs(GF_BitStream *bs, ADTSHeader *hdr)
102 {
103 u32 val;
104 u64 pos;
105
106 while (gf_bs_available(bs)>7) {
107 val = gf_bs_read_u8(bs);
108 if (val!=0xFF) continue;
109 val = gf_bs_read_int(bs, 4);
110 if (val != 0x0F) {
111 gf_bs_read_int(bs, 4);
112 continue;
113 }
114 hdr->is_mp2 = (Bool)gf_bs_read_int(bs, 1);
115 gf_bs_read_int(bs, 2);
116 hdr->no_crc = (Bool)gf_bs_read_int(bs, 1);
117 pos = gf_bs_get_position(bs) - 2;
118
119 hdr->profile = 1 + gf_bs_read_int(bs, 2);
120 hdr->sr_idx = gf_bs_read_int(bs, 4);
121 gf_bs_read_int(bs, 1);
122 hdr->nb_ch = gf_bs_read_int(bs, 3);
123 gf_bs_read_int(bs, 4);
124 hdr->frame_size = gf_bs_read_int(bs, 13);
125 gf_bs_read_int(bs, 11);
126 gf_bs_read_int(bs, 2);
127 hdr->hdr_size = 7;
128 if (!hdr->no_crc) {
129 gf_bs_read_u16(bs);
130 hdr->hdr_size = 9;
131 }
132 if (!GF_M4ASampleRates[hdr->sr_idx] || (hdr->frame_size < hdr->hdr_size)) {
133 gf_bs_seek(bs, pos+1);
134 continue;
135 }
136 hdr->frame_size -= hdr->hdr_size;
137
138 if (gf_bs_available(bs) == hdr->frame_size) {
139 return GF_TRUE;
140 }
141 if (gf_bs_available(bs) < hdr->frame_size) {
142 break;
143 }
144
145 gf_bs_skip_bytes(bs, hdr->frame_size);
146 val = gf_bs_read_u8(bs);
147 if (val!=0xFF) {
148 gf_bs_seek(bs, pos+1);
149 continue;
150 }
151 val = gf_bs_read_int(bs, 4);
152 if (val!=0x0F) {
153 gf_bs_read_int(bs, 4);
154 gf_bs_seek(bs, pos+1);
155 continue;
156 }
157 gf_bs_seek(bs, pos+hdr->hdr_size);
158 return GF_TRUE;
159 }
160 return GF_FALSE;
161 }
162
163 void id3dmx_flush(GF_Filter *filter, u8 *id3_buf, u32 id3_buf_size, GF_FilterPid *audio_pid, GF_FilterPid **video_pid_p);
164
165
adts_dmx_configure_pid(GF_Filter * filter,GF_FilterPid * pid,Bool is_remove)166 GF_Err adts_dmx_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
167 {
168 const GF_PropertyValue *p;
169 GF_ADTSDmxCtx *ctx = gf_filter_get_udta(filter);
170
171 if (is_remove) {
172 ctx->ipid = NULL;
173 gf_filter_pid_remove(ctx->opid);
174 return GF_OK;
175 }
176 if (! gf_filter_pid_check_caps(pid))
177 return GF_NOT_SUPPORTED;
178
179 ctx->ipid = pid;
180 p = gf_filter_pid_get_property(pid, GF_PROP_PID_TIMESCALE);
181 if (p) ctx->timescale = p->value.uint;
182
183 if (ctx->timescale && !ctx->opid) {
184 ctx->opid = gf_filter_pid_new(filter);
185 gf_filter_pid_copy_properties(ctx->opid, ctx->ipid);
186 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_UNFRAMED, NULL);
187 //we don't update copy props on output for now - if we decide we need it, we will need to also force resengin the decoder config
188 }
189
190 return GF_OK;
191 }
192
adts_dmx_check_dur(GF_Filter * filter,GF_ADTSDmxCtx * ctx)193 static void adts_dmx_check_dur(GF_Filter *filter, GF_ADTSDmxCtx *ctx)
194 {
195 FILE *stream;
196 GF_BitStream *bs;
197 ADTSHeader hdr;
198 u64 duration, cur_dur;
199 s32 sr_idx = -1;
200 const GF_PropertyValue *p;
201 if (!ctx->opid || ctx->timescale || ctx->file_loaded) return;
202
203 if (ctx->index<=0) {
204 ctx->file_loaded = GF_TRUE;
205 return;
206 }
207
208 p = gf_filter_pid_get_property(ctx->ipid, GF_PROP_PID_FILEPATH);
209 if (!p || !p->value.string || !strncmp(p->value.string, "gmem://", 7)) {
210 ctx->is_file = GF_FALSE;
211 ctx->file_loaded = GF_TRUE;
212 return;
213 }
214 ctx->is_file = GF_TRUE;
215
216 stream = gf_fopen(p->value.string, "rb");
217 if (!stream) return;
218
219 ctx->index_size = 0;
220
221 bs = gf_bs_from_file(stream, GF_BITSTREAM_READ);
222 duration = 0;
223 cur_dur = 0;
224 while (adts_dmx_sync_frame_bs(bs, &hdr)) {
225 if ((sr_idx>=0) && (sr_idx != hdr.sr_idx)) {
226 duration *= GF_M4ASampleRates[hdr.sr_idx];
227 duration /= GF_M4ASampleRates[sr_idx];
228
229 cur_dur *= GF_M4ASampleRates[hdr.sr_idx];
230 cur_dur /= GF_M4ASampleRates[sr_idx];
231 }
232 sr_idx = hdr.sr_idx;
233 duration += ctx->frame_size;
234 cur_dur += ctx->frame_size;
235 if (cur_dur > ctx->index * GF_M4ASampleRates[sr_idx]) {
236 if (!ctx->index_alloc_size) ctx->index_alloc_size = 10;
237 else if (ctx->index_alloc_size == ctx->index_size) ctx->index_alloc_size *= 2;
238 ctx->indexes = gf_realloc(ctx->indexes, sizeof(ADTSIdx)*ctx->index_alloc_size);
239 ctx->indexes[ctx->index_size].pos = gf_bs_get_position(bs) - hdr.hdr_size;
240 ctx->indexes[ctx->index_size].duration = (Double) duration;
241 ctx->indexes[ctx->index_size].duration /= GF_M4ASampleRates[sr_idx];
242 ctx->index_size ++;
243 cur_dur = 0;
244 }
245
246 gf_bs_skip_bytes(bs, hdr.frame_size);
247 }
248 gf_bs_del(bs);
249 gf_fclose(stream);
250
251 if (sr_idx>=0) {
252 if (!ctx->duration.num || (ctx->duration.num * GF_M4ASampleRates[sr_idx] != duration * ctx->duration.den)) {
253 ctx->duration.num = (s32) duration;
254 ctx->duration.den = GF_M4ASampleRates[sr_idx];
255
256 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DURATION, & PROP_FRAC64(ctx->duration));
257 }
258 }
259
260 p = gf_filter_pid_get_property(ctx->ipid, GF_PROP_PID_FILE_CACHED);
261 if (p && p->value.boolean) ctx->file_loaded = GF_TRUE;
262 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CAN_DATAREF, & PROP_BOOL(GF_TRUE ) );
263 }
264
adts_dmx_check_pid(GF_Filter * filter,GF_ADTSDmxCtx * ctx)265 static void adts_dmx_check_pid(GF_Filter *filter, GF_ADTSDmxCtx *ctx)
266 {
267 GF_BitStream *dsi;
268 GF_M4ADecSpecInfo acfg;
269 u8 *dsi_b;
270 u32 i, sbr_sr_idx, dsi_s, sr, sbr_sr, codecid, timescale=0;
271
272 if (!ctx->opid) {
273 ctx->opid = gf_filter_pid_new(filter);
274 gf_filter_pid_copy_properties(ctx->opid, ctx->ipid);
275 adts_dmx_check_dur(filter, ctx);
276 }
277
278 if ((ctx->sr_idx == ctx->hdr.sr_idx) && (ctx->nb_ch == ctx->hdr.nb_ch)
279 && (ctx->is_mp2 == ctx->hdr.is_mp2) && (ctx->profile == ctx->hdr.profile) ) return;
280
281 //copy properties at init or reconfig
282 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STREAM_TYPE, & PROP_UINT( GF_STREAM_AUDIO));
283 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, & PROP_UINT( GF_CODECID_AAC_MPEG4));
284 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLES_PER_FRAME, & PROP_UINT(ctx->frame_size) );
285 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_UNFRAMED, & PROP_BOOL(GF_FALSE) );
286 if (ctx->is_file && ctx->index) {
287 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PLAYBACK_MODE, & PROP_UINT(GF_PLAYBACK_MODE_FASTFORWARD) );
288 }
289
290 if (ctx->duration.num)
291 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DURATION, & PROP_FRAC64(ctx->duration));
292
293
294 ctx->is_mp2 = ctx->hdr.is_mp2;
295 ctx->nb_ch = ctx->hdr.nb_ch;
296 ctx->profile = ctx->hdr.profile;
297
298 sr = GF_M4ASampleRates[ctx->hdr.sr_idx];
299 if (!ctx->timescale) {
300 //we change sample rate, change cts
301 if (ctx->cts && (ctx->sr_idx != ctx->hdr.sr_idx)) {
302 ctx->cts *= sr;
303 ctx->cts /= GF_M4ASampleRates[ctx->sr_idx];
304 }
305 }
306 ctx->sr_idx = ctx->hdr.sr_idx;
307
308 /*keep MPEG-2 AAC codecid even for HE-SBR (that's correct according to latest MPEG-4 audio spec)*/
309 codecid = ctx->hdr.is_mp2 ? ctx->hdr.profile+GF_CODECID_AAC_MPEG2_MP-1 : GF_CODECID_AAC_MPEG4;
310 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, & PROP_UINT(codecid) );
311
312 //force explicit SBR if explicit PS
313 if (ctx->ps==AAC_SIGNAL_EXPLICIT) {
314 ctx->sbr = AAC_SIGNAL_EXPLICIT;
315 }
316 /*no provision for explicit indication of MPEG-2 AAC through MPEG-4 PLs, so force implicit*/
317 if (ctx->hdr.is_mp2) {
318 if (ctx->sbr == AAC_SIGNAL_EXPLICIT) ctx->sbr = AAC_SIGNAL_IMPLICIT;
319 if (ctx->ps == AAC_SIGNAL_EXPLICIT) ctx->ps = AAC_SIGNAL_IMPLICIT;
320 }
321
322 dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
323 ctx->dts_inc = ctx->frame_size;
324
325 sbr_sr = sr;
326 sbr_sr_idx = ctx->hdr.sr_idx;
327 if (!ctx->ovsbr) {
328 for (i=0; i<16; i++) {
329 if (GF_M4ASampleRates[i] == (u32) 2*sr) {
330 sbr_sr_idx = i;
331 sbr_sr = 2*sr;
332 break;
333 }
334 }
335 }
336
337 memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo));
338 acfg.base_object_type = ctx->hdr.profile;
339 acfg.base_sr = sr;
340 acfg.nb_chan = gf_m4a_get_channel_cfg(ctx->hdr.nb_ch);
341 acfg.sbr_object_type = 0;
342 if (ctx->sbr==AAC_SIGNAL_EXPLICIT) {
343 acfg.has_sbr = GF_TRUE;
344 acfg.base_object_type = 5;
345 acfg.sbr_object_type = ctx->hdr.profile;
346
347 /*for better interop, always store using full SR when using explict signaling*/
348 ctx->dts_inc *= 2;
349 sr = sbr_sr;
350 } else if (ctx->sbr==AAC_SIGNAL_IMPLICIT) {
351 acfg.has_sbr = GF_TRUE;
352 }
353 if (ctx->ps==AAC_SIGNAL_EXPLICIT) {
354 acfg.has_ps = GF_TRUE;
355 acfg.base_object_type = 29;
356 } else if (ctx->ps==AAC_SIGNAL_IMPLICIT) {
357 acfg.has_ps = GF_TRUE;
358 }
359
360 acfg.audioPL = gf_m4a_get_profile(&acfg);
361 /*explicit SBR or PS signal (non backward-compatible)*/
362 if (ctx->ps==AAC_SIGNAL_EXPLICIT) {
363 gf_bs_write_int(dsi, 29, 5);
364 gf_bs_write_int(dsi, ctx->hdr.sr_idx, 4);
365 gf_bs_write_int(dsi, ctx->hdr.nb_ch, 4);
366 gf_bs_write_int(dsi, sbr_sr ? sbr_sr_idx : ctx->hdr.sr_idx, 4);
367 gf_bs_write_int(dsi, ctx->hdr.profile, 5);
368 }
369 /*explicit SBR signal (non backward-compatible)*/
370 else if (ctx->sbr==AAC_SIGNAL_EXPLICIT) {
371 gf_bs_write_int(dsi, 5, 5);
372 gf_bs_write_int(dsi, ctx->hdr.sr_idx, 4);
373 gf_bs_write_int(dsi, ctx->hdr.nb_ch, 4);
374 gf_bs_write_int(dsi, sbr_sr ? sbr_sr_idx : ctx->hdr.sr_idx, 4);
375 gf_bs_write_int(dsi, ctx->hdr.profile, 5);
376 } else {
377 /*regular AAC*/
378 gf_bs_write_int(dsi, ctx->hdr.profile, 5);
379 gf_bs_write_int(dsi, ctx->hdr.sr_idx, 4);
380 gf_bs_write_int(dsi, ctx->hdr.nb_ch, 4);
381 gf_bs_align(dsi);
382 /*implicit AAC SBR signal*/
383 if (ctx->sbr==AAC_SIGNAL_IMPLICIT) {
384 gf_bs_write_int(dsi, 0x2b7, 11); /*sync extension type*/
385 gf_bs_write_int(dsi, 5, 5); /*SBR objectType*/
386 gf_bs_write_int(dsi, 1, 1); /*SBR present flag*/
387 gf_bs_write_int(dsi, sbr_sr_idx, 4);
388 }
389 if (ctx->ps==AAC_SIGNAL_IMPLICIT) {
390 gf_bs_write_int(dsi, 0x548, 11); /*sync extension type*/
391 gf_bs_write_int(dsi, 1, 1); /* PS present flag */
392 }
393 }
394 gf_bs_align(dsi);
395
396 gf_bs_get_content(dsi, &dsi_b, &dsi_s);
397 gf_bs_del(dsi);
398 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG, & PROP_DATA_NO_COPY(dsi_b, dsi_s) );
399 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PROFILE_LEVEL, & PROP_UINT (acfg.audioPL) );
400 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLE_RATE, & PROP_UINT(sr));
401
402 timescale = sr;
403 if (ctx->ovsbr) timescale = 2*sr;
404
405 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_TIMESCALE, & PROP_UINT(ctx->timescale ? ctx->timescale : timescale));
406 gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_NUM_CHANNELS, & PROP_UINT(ctx->nb_ch) );
407
408 if (ctx->id3_buffer_size) {
409 id3dmx_flush(filter, ctx->id3_buffer, ctx->id3_buffer_size, ctx->opid, ctx->expart ? &ctx->vpid : NULL);
410 ctx->id3_buffer_size = 0;
411 }
412
413 }
414
adts_dmx_process_event(GF_Filter * filter,const GF_FilterEvent * evt)415 static Bool adts_dmx_process_event(GF_Filter *filter, const GF_FilterEvent *evt)
416 {
417 u32 i;
418 GF_FilterEvent fevt;
419 GF_ADTSDmxCtx *ctx = gf_filter_get_udta(filter);
420
421 switch (evt->base.type) {
422 case GF_FEVT_PLAY:
423 if (!ctx->is_playing) {
424 ctx->is_playing = GF_TRUE;
425 ctx->cts = 0;
426 }
427 ctx->nb_frames = 0;
428 ctx->id3_buffer_size = 0;
429
430 if (! ctx->is_file) {
431 if (evt->play.start_range || ctx->initial_play_done) {
432 ctx->adts_buffer_size = 0;
433 ctx->resume_from = 0;
434 }
435
436 ctx->initial_play_done = GF_TRUE;
437 return GF_FALSE;
438 }
439 ctx->start_range = evt->play.start_range;
440 ctx->in_seek = GF_TRUE;
441 ctx->file_pos = 0;
442 if (ctx->start_range) {
443 for (i=1; i<ctx->index_size; i++) {
444 if (ctx->indexes[i].duration>ctx->start_range) {
445 ctx->cts = (u64) (ctx->indexes[i-1].duration * GF_M4ASampleRates[ctx->sr_idx]);
446 ctx->file_pos = ctx->indexes[i-1].pos;
447 break;
448 }
449 }
450 }
451 if (!ctx->initial_play_done) {
452 ctx->initial_play_done = GF_TRUE;
453 //seek will not change the current source state, don't send a seek
454 if (!ctx->file_pos)
455 return GF_TRUE;
456 }
457 ctx->resume_from = 0;
458 ctx->adts_buffer_size = 0;
459 //post a seek
460 GF_FEVT_INIT(fevt, GF_FEVT_SOURCE_SEEK, ctx->ipid);
461 fevt.seek.start_offset = ctx->file_pos;
462 gf_filter_pid_send_event(ctx->ipid, &fevt);
463
464 //cancel event
465 return GF_TRUE;
466
467 case GF_FEVT_STOP:
468 //don't cancel event
469 ctx->is_playing = GF_FALSE;
470 return GF_FALSE;
471
472 case GF_FEVT_SET_SPEED:
473 //cancel event
474 return GF_TRUE;
475 default:
476 break;
477 }
478 //by default don't cancel event - to rework once we have downloading in place
479 return GF_FALSE;
480 }
481
adts_dmx_update_cts(GF_ADTSDmxCtx * ctx)482 static GFINLINE void adts_dmx_update_cts(GF_ADTSDmxCtx *ctx)
483 {
484 assert(ctx->dts_inc);
485
486 if (ctx->timescale) {
487 u64 inc = ctx->dts_inc;
488 inc *= ctx->timescale;
489 inc /= GF_M4ASampleRates[ctx->sr_idx];
490 ctx->cts += inc;
491 } else {
492 ctx->cts += ctx->dts_inc;
493 }
494 }
495
adts_dmx_process(GF_Filter * filter)496 GF_Err adts_dmx_process(GF_Filter *filter)
497 {
498 GF_ADTSDmxCtx *ctx = gf_filter_get_udta(filter);
499 GF_FilterPacket *pck, *dst_pck;
500 u8 *data, *output;
501 u8 *start;
502 u32 pck_size, remain, prev_pck_size;
503 u64 cts = GF_FILTER_NO_TS;
504
505 //always reparse duration
506 if (!ctx->duration.num)
507 adts_dmx_check_dur(filter, ctx);
508
509 if (ctx->opid && !ctx->is_playing)
510 return GF_OK;
511
512 pck = gf_filter_pid_get_packet(ctx->ipid);
513 if (!pck) {
514 if (gf_filter_pid_is_eos(ctx->ipid)) {
515 if (!ctx->adts_buffer_size) {
516 if (ctx->opid)
517 gf_filter_pid_set_eos(ctx->opid);
518 if (ctx->src_pck) gf_filter_pck_unref(ctx->src_pck);
519 ctx->src_pck = NULL;
520 return GF_EOS;
521 }
522 } else {
523 return GF_OK;
524 }
525 }
526
527 prev_pck_size = ctx->adts_buffer_size;
528 if (pck && !ctx->resume_from) {
529 data = (char *) gf_filter_pck_get_data(pck, &pck_size);
530 if (!pck_size) {
531 gf_filter_pid_drop_packet(ctx->ipid);
532 return GF_OK;
533 }
534
535 if (ctx->byte_offset != GF_FILTER_NO_BO) {
536 u64 byte_offset = gf_filter_pck_get_byte_offset(pck);
537 if (!ctx->adts_buffer_size) {
538 ctx->byte_offset = byte_offset;
539 } else if (ctx->byte_offset + ctx->adts_buffer_size != byte_offset) {
540 ctx->byte_offset = GF_FILTER_NO_BO;
541 if ((byte_offset != GF_FILTER_NO_BO) && (byte_offset>ctx->adts_buffer_size) ) {
542 ctx->byte_offset = byte_offset - ctx->adts_buffer_size;
543 }
544 }
545 }
546
547 if (ctx->adts_buffer_size + pck_size > ctx->adts_buffer_alloc) {
548 ctx->adts_buffer_alloc = ctx->adts_buffer_size + pck_size;
549 ctx->adts_buffer = gf_realloc(ctx->adts_buffer, ctx->adts_buffer_alloc);
550 }
551 memcpy(ctx->adts_buffer + ctx->adts_buffer_size, data, pck_size);
552 ctx->adts_buffer_size += pck_size;
553 }
554
555 //input pid sets some timescale - we flushed pending data , update cts
556 if (ctx->timescale && pck) {
557 cts = gf_filter_pck_get_cts(pck);
558 }
559
560 if (cts == GF_FILTER_NO_TS) {
561 //avoids updating cts
562 prev_pck_size = 0;
563 }
564
565 remain = ctx->adts_buffer_size;
566 start = ctx->adts_buffer;
567
568 if (ctx->resume_from) {
569 start += ctx->resume_from - 1;
570 remain -= ctx->resume_from - 1;
571 ctx->resume_from = 0;
572 }
573
574 while (remain) {
575 u8 *sync;
576 u32 sync_pos, size, offset, bytes_to_drop=0;
577
578 if (!ctx->tag_size && (remain>3)) {
579
580 /* Did we read an ID3v2 ? */
581 if (start[0] == 'I' && start[1] == 'D' && start[2] == '3') {
582 if (remain<10)
583 return GF_OK;
584
585 ctx->tag_size = ((start[9] & 0x7f) + ((start[8] & 0x7f) << 7) + ((start[7] & 0x7f) << 14) + ((start[6] & 0x7f) << 21));
586
587 bytes_to_drop = 10;
588 if (ctx->id3_buffer_alloc < ctx->tag_size+10) {
589 ctx->id3_buffer = gf_realloc(ctx->id3_buffer, ctx->tag_size+10);
590 ctx->id3_buffer_alloc = ctx->tag_size+10;
591 }
592 memcpy(ctx->id3_buffer, start, 10);
593 ctx->id3_buffer_size = 10;
594 goto drop_byte;
595 }
596 }
597 if (ctx->tag_size) {
598 if (ctx->tag_size>remain) {
599 bytes_to_drop = remain;
600 ctx->tag_size-=remain;
601 } else {
602 bytes_to_drop = ctx->tag_size;
603 ctx->tag_size = 0;
604 }
605 memcpy(ctx->id3_buffer + ctx->id3_buffer_size, start, bytes_to_drop);
606 ctx->id3_buffer_size += bytes_to_drop;
607
608 if (!ctx->tag_size && ctx->opid) {
609 id3dmx_flush(filter, ctx->id3_buffer, ctx->id3_buffer_size, ctx->opid, ctx->expart ? &ctx->vpid : NULL);
610 ctx->id3_buffer_size = 0;
611 }
612 goto drop_byte;
613
614 }
615
616 sync = memchr(start, 0xFF, remain);
617 sync_pos = (u32) (sync ? sync - start : remain);
618
619 //couldn't find sync byte in this packet
620 if (remain - sync_pos < 7) {
621 break;
622 }
623
624 //not sync !
625 if ((sync[1] & 0xF0) != 0xF0) {
626 GF_LOG(ctx->nb_frames ? GF_LOG_WARNING : GF_LOG_DEBUG, GF_LOG_PARSER, ("[ADTSDmx] invalid ADTS sync bytes, resyncing\n"));
627 ctx->nb_frames = 0;
628 goto drop_byte;
629 }
630 if (!ctx->bs) {
631 ctx->bs = gf_bs_new(sync + 1, remain - sync_pos - 1, GF_BITSTREAM_READ);
632 } else {
633 gf_bs_reassign_buffer(ctx->bs, sync + 1, remain - sync_pos - 1);
634 }
635
636 //ok parse header
637 gf_bs_read_int(ctx->bs, 4);
638
639 ctx->hdr.is_mp2 = (Bool)gf_bs_read_int(ctx->bs, 1);
640 //if (ctx->mpeg4)
641 //we deprecate old MPEG-2 signaling for AAC in ISOBMFF, as it is not well supported anyway and we don't write adif_header as
642 //supposed to be for these types
643 ctx->hdr.is_mp2 = 0;
644
645 gf_bs_read_int(ctx->bs, 2);
646 ctx->hdr.no_crc = (Bool)gf_bs_read_int(ctx->bs, 1);
647
648 ctx->hdr.profile = 1 + gf_bs_read_int(ctx->bs, 2);
649 ctx->hdr.sr_idx = gf_bs_read_int(ctx->bs, 4);
650 gf_bs_read_int(ctx->bs, 1);
651 ctx->hdr.nb_ch = gf_bs_read_int(ctx->bs, 3);
652 gf_bs_read_int(ctx->bs, 4);
653 ctx->hdr.frame_size = gf_bs_read_int(ctx->bs, 13);
654 gf_bs_read_int(ctx->bs, 11);
655 gf_bs_read_int(ctx->bs, 2);
656 ctx->hdr.hdr_size = 7;
657
658 if (!ctx->hdr.no_crc) {
659 ctx->hdr.hdr_size = 9;
660 }
661
662 if (!ctx->hdr.frame_size || !GF_M4ASampleRates[ctx->hdr.sr_idx] || !ctx->hdr.nb_ch) {
663 GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[ADTSDmx] invalid ADTS frame header, resyncing\n"));
664 ctx->nb_frames = 0;
665 goto drop_byte;
666 }
667
668 //ready to send packet
669 if (ctx->hdr.frame_size + 1 < remain) {
670 u32 next_frame = ctx->hdr.frame_size;
671 //make sure we are sync!
672 if ((sync[next_frame] !=0xFF) || ((sync[next_frame+1] & 0xF0) !=0xF0) ) {
673 GF_LOG(ctx->nb_frames ? GF_LOG_WARNING : GF_LOG_DEBUG, GF_LOG_PARSER, ("[ADTSDmx] invalid next ADTS frame sync, resyncing\n"));
674 ctx->nb_frames = 0;
675 goto drop_byte;
676 }
677 }
678 //otherwise wait for next frame, unless if end of stream
679 else if (pck) {
680 if (ctx->timescale && !prev_pck_size && (cts != GF_FILTER_NO_TS) ) {
681 ctx->cts = cts;
682 }
683 break;
684 }
685
686 adts_dmx_check_pid(filter, ctx);
687
688 if (!ctx->is_playing) {
689 ctx->resume_from = 1 + ctx->adts_buffer_size - remain;
690 return GF_OK;
691 }
692
693 ctx->nb_frames++;
694 size = ctx->hdr.frame_size - ctx->hdr.hdr_size;
695 offset = ctx->hdr.hdr_size;
696
697 if (ctx->in_seek) {
698 u64 nb_samples_at_seek = (u64) (ctx->start_range * GF_M4ASampleRates[ctx->sr_idx]);
699 if (ctx->cts + ctx->dts_inc >= nb_samples_at_seek) {
700 //u32 samples_to_discard = (ctx->cts + ctx->dts_inc) - nb_samples_at_seek;
701 ctx->in_seek = GF_FALSE;
702 }
703 }
704
705 bytes_to_drop = ctx->hdr.frame_size;
706 if (ctx->timescale && !prev_pck_size && (cts != GF_FILTER_NO_TS) ) {
707 ctx->cts = cts;
708 cts = GF_FILTER_NO_TS;
709 }
710
711 if (!ctx->in_seek) {
712 dst_pck = gf_filter_pck_new_alloc(ctx->opid, size, &output);
713 if (ctx->src_pck) gf_filter_pck_merge_properties(ctx->src_pck, dst_pck);
714
715 memcpy(output, sync + offset, size);
716 gf_filter_pck_set_dts(dst_pck, ctx->cts);
717 gf_filter_pck_set_cts(dst_pck, ctx->cts);
718 gf_filter_pck_set_duration(dst_pck, ctx->dts_inc);
719 gf_filter_pck_set_framing(dst_pck, GF_TRUE, GF_TRUE);
720 gf_filter_pck_set_sap(dst_pck, GF_FILTER_SAP_1);
721
722 if (ctx->byte_offset != GF_FILTER_NO_BO) {
723 gf_filter_pck_set_byte_offset(dst_pck, ctx->byte_offset + ctx->hdr.hdr_size);
724 }
725
726 gf_filter_pck_send(dst_pck);
727 }
728 adts_dmx_update_cts(ctx);
729
730
731 //truncated last frame
732 if (bytes_to_drop>remain) {
733 GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[ADTSDmx] truncated ADTS frame!\n"));
734 bytes_to_drop=remain;
735 }
736
737 drop_byte:
738 if (!bytes_to_drop) {
739 bytes_to_drop = 1;
740 }
741 start += bytes_to_drop;
742 remain -= bytes_to_drop;
743
744 if (prev_pck_size) {
745 if (prev_pck_size > bytes_to_drop) prev_pck_size -= bytes_to_drop;
746 else {
747 prev_pck_size=0;
748 if (ctx->src_pck) gf_filter_pck_unref(ctx->src_pck);
749 ctx->src_pck = pck;
750 if (pck)
751 gf_filter_pck_ref_props(&ctx->src_pck);
752 }
753 }
754 if (ctx->byte_offset != GF_FILTER_NO_BO)
755 ctx->byte_offset += bytes_to_drop;
756 }
757
758 if (!pck) {
759 ctx->adts_buffer_size = 0;
760 return adts_dmx_process(filter);
761 } else {
762 if (remain) {
763 memmove(ctx->adts_buffer, start, remain);
764 }
765 ctx->adts_buffer_size = remain;
766 gf_filter_pid_drop_packet(ctx->ipid);
767 }
768 return GF_OK;
769 }
770
adts_dmx_finalize(GF_Filter * filter)771 static void adts_dmx_finalize(GF_Filter *filter)
772 {
773 GF_ADTSDmxCtx *ctx = gf_filter_get_udta(filter);
774 if (ctx->bs) gf_bs_del(ctx->bs);
775 if (ctx->indexes) gf_free(ctx->indexes);
776 if (ctx->adts_buffer) gf_free(ctx->adts_buffer);
777 if (ctx->id3_buffer) gf_free(ctx->id3_buffer);
778 }
779
adts_dmx_probe_data(const u8 * data,u32 size,GF_FilterProbeScore * score)780 static const char *adts_dmx_probe_data(const u8 *data, u32 size, GF_FilterProbeScore *score)
781 {
782 u32 nb_frames=0, next_pos=0, max_consecutive_frames=0;
783 ADTSHeader prev_hdr;
784 GF_BitStream *bs;
785 Bool has_id3=GF_FALSE;
786
787 /*check for id3*/
788 if (size>= 10) {
789 if (data[0] == 'I' && data[1] == 'D' && data[2] == '3') {
790 u32 tag_size = ((data[9] & 0x7f) + ((data[8] & 0x7f) << 7) + ((data[7] & 0x7f) << 14) + ((data[6] & 0x7f) << 21));
791
792 if (tag_size+10 > size) {
793 GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("ID3 tag detected size %d but probe data only %d bytes, will rely on file extension (try increasing probe size using --block_size)\n", tag_size+10, size));
794 *score = GF_FPROBE_EXT_MATCH;
795 return "aac|adts";
796 }
797 data += tag_size+10;
798 size -= tag_size+10;
799 has_id3 = GF_TRUE;
800 }
801 }
802
803 bs = gf_bs_new(data, size, GF_BITSTREAM_READ);
804 memset(&prev_hdr, 0, sizeof(ADTSHeader));
805 while (gf_bs_available(bs)) {
806 ADTSHeader hdr;
807 u32 pos;
808 hdr.frame_size = 0;
809 if (!adts_dmx_sync_frame_bs(bs, &hdr)) {
810 if (hdr.frame_size) {
811 //nb_frames++;
812 max_consecutive_frames++;
813 }
814 break;
815 }
816 if ((hdr.hdr_size!=7) && (hdr.hdr_size!=9)) continue;
817 if (!hdr.nb_ch) continue;
818 pos = (u32) gf_bs_get_position(bs);
819 if ((next_pos + hdr.hdr_size == pos) && (hdr.sr_idx==prev_hdr.sr_idx) && (hdr.nb_ch==prev_hdr.nb_ch) ) {
820 nb_frames++;
821 if (max_consecutive_frames<nb_frames) max_consecutive_frames = nb_frames;
822 if (max_consecutive_frames>5)
823 break;
824 } else {
825 nb_frames=1;
826 }
827 prev_hdr = hdr;
828 gf_bs_skip_bytes(bs, hdr.frame_size);
829 next_pos = (u32) gf_bs_get_position(bs);
830 }
831 gf_bs_del(bs);
832 if (max_consecutive_frames>=4) {
833 *score = GF_FPROBE_SUPPORTED;
834 return "audio/aac";
835 }
836 if (has_id3 && max_consecutive_frames) {
837 *score = GF_FPROBE_MAYBE_SUPPORTED;
838 return "audio/aac";
839 }
840 return NULL;
841 }
842
843 static const GF_FilterCapability ADTSDmxCaps[] =
844 {
845 CAP_UINT(GF_CAPS_INPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_FILE),
846 CAP_STRING(GF_CAPS_INPUT, GF_PROP_PID_FILE_EXT, "aac|adts"),
847 CAP_STRING(GF_CAPS_INPUT, GF_PROP_PID_MIME, "audio/x-m4a|audio/aac|audio/aacp|audio/x-aac"),
848 CAP_UINT(GF_CAPS_OUTPUT_STATIC, GF_PROP_PID_STREAM_TYPE, GF_STREAM_AUDIO),
849 CAP_UINT(GF_CAPS_OUTPUT_STATIC, GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG4),
850 CAP_UINT(GF_CAPS_OUTPUT_STATIC, GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG2_MP),
851 CAP_UINT(GF_CAPS_OUTPUT_STATIC, GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG2_LCP),
852 CAP_UINT(GF_CAPS_OUTPUT_STATIC, GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG2_SSRP),
853 //we explitely set this one to prevent adts->latm reframer connection
854 CAP_BOOL(GF_CAPS_OUTPUT_STATIC_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
855 {0},
856 CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_STREAM_TYPE, GF_STREAM_AUDIO),
857 CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_AAC_MPEG4),
858 CAP_BOOL(GF_CAPS_INPUT,GF_PROP_PID_UNFRAMED, GF_TRUE),
859 };
860
861
862 #define OFFS(_n) #_n, offsetof(GF_ADTSDmxCtx, _n)
863 static const GF_FilterArgs ADTSDmxArgs[] =
864 {
865 { OFFS(frame_size), "size of AAC frame in audio samples", GF_PROP_UINT, "1024", NULL, GF_FS_ARG_HINT_EXPERT},
866 { OFFS(index), "indexing window length", GF_PROP_DOUBLE, "1.0", NULL, 0},
867 // { OFFS(mpeg4), "force signaling as MPEG-4 AAC", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED},
868 { OFFS(ovsbr), "force oversampling SBR (does not multiply timescales by 2)", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED},
869 { OFFS(sbr), "set SBR signaling\n"\
870 "- no: no SBR signaling at all\n"\
871 "- imp: backward-compatible SBR signaling (audio signaled as AAC-LC)\n"\
872 "- exp: explicit SBR signaling (audio signaled as AAC-SBR)"\
873 , GF_PROP_UINT, "no", "no|imp|exp", GF_FS_ARG_HINT_ADVANCED},
874 { OFFS(ps), "set PS signaling\n"\
875 "- no: no PS signaling at all\n"\
876 "- imp: backward-compatible PS signaling (audio signaled as AAC-LC)\n"\
877 "- exp: explicit PS signaling (audio signaled as AAC-PS)"\
878 , GF_PROP_UINT, "no", "no|imp|exp", GF_FS_ARG_HINT_ADVANCED},
879 { OFFS(expart), "expose pictures as a dedicated video pid", GF_PROP_BOOL, "false", NULL, 0},
880 {0}
881 };
882
883
884 GF_FilterRegister ADTSDmxRegister = {
885 .name = "rfadts",
886 GF_FS_SET_DESCRIPTION("ADTS reframer")
887 GF_FS_SET_HELP("This filter parses AAC files/data and outputs corresponding audio PID and frames.")
888 .private_size = sizeof(GF_ADTSDmxCtx),
889 .args = ADTSDmxArgs,
890 .finalize = adts_dmx_finalize,
891 SETCAPS(ADTSDmxCaps),
892 .configure_pid = adts_dmx_configure_pid,
893 .process = adts_dmx_process,
894 .probe_data = adts_dmx_probe_data,
895 .process_event = adts_dmx_process_event
896 };
897
898
adts_dmx_register(GF_FilterSession * session)899 const GF_FilterRegister *adts_dmx_register(GF_FilterSession *session)
900 {
901 return &ADTSDmxRegister;
902 }
903
904 #else
adts_dmx_register(GF_FilterSession * session)905 const GF_FilterRegister *adts_dmx_register(GF_FilterSession *session)
906 {
907 return NULL;
908 }
909 #endif // GPAC_DISABLE_AV_PARSERS
910