Line 0
Link Here
|
|
|
1 |
/* |
2 |
* copyright (c) 2008 Paul Kendall <paul@kcbbs.gen.nz> |
3 |
* |
4 |
* This file is part of FFmpeg. |
5 |
* |
6 |
* FFmpeg is free software; you can redistribute it and/or |
7 |
* modify it under the terms of the GNU Lesser General Public |
8 |
* License as published by the Free Software Foundation; either |
9 |
* version 2.1 of the License, or (at your option) any later version. |
10 |
* |
11 |
* FFmpeg is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
* Lesser General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU Lesser General Public |
17 |
* License along with FFmpeg; if not, write to the Free Software |
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 |
*/ |
20 |
|
21 |
/** |
22 |
* @file latmaac.c |
23 |
* LATM wrapped AAC decoder |
24 |
*/ |
25 |
|
26 |
#include <stdio.h> |
27 |
#include <stdlib.h> |
28 |
#include <string.h> |
29 |
#include <math.h> |
30 |
#include <sys/types.h> |
31 |
|
32 |
#include "parser.h" |
33 |
#include "bitstream.h" |
34 |
#include "neaacdec.h" |
35 |
|
36 |
extern const int aac_sample_rates[16]; |
37 |
extern const uint8_t aac_channels[8]; |
38 |
|
39 |
#define min(a,b) ((a)<(b) ? (a) : (b)) |
40 |
|
41 |
|
42 |
/* |
43 |
Note: This decoder filter is intended to decode LATM streams transferred |
44 |
in MPEG transport streams which are only supposed to contain one program. |
45 |
To do a more complex LATM demuxing a separate LATM demuxer should be used. |
46 |
*/ |
47 |
|
48 |
#define AAC_NONE 0 // mode not detected (or indicated in mediatype) |
49 |
#define AAC_LATM 1 // LATM packets (ISO/IEC 14496-3 1.7.3 Multiplex layer) |
50 |
|
51 |
#define SYNC_LATM 0x2b7 // 11 bits |
52 |
|
53 |
#define MAX_SIZE 8*1024 |
54 |
|
55 |
typedef struct AACConfig |
56 |
{ |
57 |
uint8_t extra[64]; // should be way enough |
58 |
int extrasize; |
59 |
|
60 |
int audioObjectType; |
61 |
int samplingFrequencyIndex; |
62 |
int samplingFrequency; |
63 |
int channelConfiguration; |
64 |
int channels; |
65 |
} AACConfig; |
66 |
|
67 |
typedef struct AACParser |
68 |
{ |
69 |
AACConfig config; |
70 |
uint8_t frameLengthType; |
71 |
uint16_t muxSlotLengthBytes; |
72 |
|
73 |
uint8_t audio_mux_version; |
74 |
uint8_t audio_mux_version_A; |
75 |
int taraFullness; |
76 |
uint8_t config_crc; |
77 |
int64_t other_data_bits; |
78 |
|
79 |
int mode; |
80 |
int offset; // byte offset in "buf" buffer |
81 |
uint8_t buf[MAX_SIZE]; // allocated buffer |
82 |
int count; // number of bytes written in buffer |
83 |
} AACParser; |
84 |
|
85 |
typedef struct AACDecoder |
86 |
{ |
87 |
AACParser *parser; |
88 |
faacDecHandle aac_decoder; |
89 |
int open; |
90 |
uint32_t in_samplerate; |
91 |
uint8_t in_channels; |
92 |
} AACDecoder; |
93 |
|
94 |
typedef struct { |
95 |
AACDecoder* decoder; |
96 |
} FAACContext; |
97 |
|
98 |
static inline int64_t latm_get_value(GetBitContext *b) |
99 |
{ |
100 |
uint8_t bytesForValue = get_bits(b, 2); |
101 |
int64_t value = 0; |
102 |
int i; |
103 |
for (i=0; i<=bytesForValue; i++) { |
104 |
value <<= 8; |
105 |
value |= get_bits(b, 8); |
106 |
} |
107 |
return value; |
108 |
} |
109 |
|
110 |
static void readGASpecificConfig(struct AACConfig *cfg, GetBitContext *b, PutBitContext *o) |
111 |
{ |
112 |
int framelen_flag = get_bits(b, 1); |
113 |
put_bits(o, 1, framelen_flag); |
114 |
int dependsOnCoder = get_bits(b, 1); |
115 |
put_bits(o, 1, dependsOnCoder); |
116 |
int ext_flag; |
117 |
int delay; |
118 |
int layerNr; |
119 |
|
120 |
if (dependsOnCoder) { |
121 |
delay = get_bits(b, 14); |
122 |
put_bits(o, 14, delay); |
123 |
} |
124 |
ext_flag = get_bits(b, 1); |
125 |
put_bits(o, 1, ext_flag); |
126 |
if (!cfg->channelConfiguration) { |
127 |
// program config element |
128 |
// TODO: |
129 |
} |
130 |
|
131 |
if (cfg->audioObjectType == 6 || cfg->audioObjectType == 20) { |
132 |
layerNr = get_bits(b, 3); |
133 |
put_bits(o, 3, layerNr); |
134 |
} |
135 |
if (ext_flag) { |
136 |
if (cfg->audioObjectType == 22) { |
137 |
skip_bits(b, 5); // numOfSubFrame |
138 |
skip_bits(b, 11); // layer_length |
139 |
|
140 |
put_bits(o, 16, 0); |
141 |
} |
142 |
if (cfg->audioObjectType == 17 || |
143 |
cfg->audioObjectType == 19 || |
144 |
cfg->audioObjectType == 20 || |
145 |
cfg->audioObjectType == 23) { |
146 |
|
147 |
skip_bits(b, 3); // stuff |
148 |
put_bits(o, 3, 0); |
149 |
} |
150 |
|
151 |
skip_bits(b, 1); // extflag3 |
152 |
put_bits(o, 1, 0); |
153 |
} |
154 |
} |
155 |
|
156 |
static int readAudioSpecificConfig(struct AACConfig *cfg, GetBitContext *b) |
157 |
{ |
158 |
PutBitContext o; |
159 |
init_put_bits(&o, cfg->extra, sizeof(cfg->extra)); |
160 |
|
161 |
// returns the number of bits read |
162 |
int ret = 0; |
163 |
int sbr_present = -1; |
164 |
|
165 |
// object |
166 |
cfg->audioObjectType = get_bits(b, 5); |
167 |
put_bits(&o, 5, cfg->audioObjectType); |
168 |
if (cfg->audioObjectType == 31) { |
169 |
uint8_t n = get_bits(b, 6); |
170 |
put_bits(&o, 6, n); |
171 |
cfg->audioObjectType = 32 + n; |
172 |
} |
173 |
|
174 |
cfg->samplingFrequencyIndex = get_bits(b, 4); |
175 |
cfg->samplingFrequency = aac_sample_rates[cfg->samplingFrequencyIndex]; |
176 |
put_bits(&o, 4, cfg->samplingFrequencyIndex); |
177 |
if (cfg->samplingFrequencyIndex == 0x0f) { |
178 |
uint32_t f = get_bits_long(b, 24); |
179 |
put_bits(&o, 24, f); |
180 |
cfg->samplingFrequency = f; |
181 |
} |
182 |
cfg->channelConfiguration = get_bits(b, 4); |
183 |
put_bits(&o, 4, cfg->channelConfiguration); |
184 |
cfg->channels = aac_channels[cfg->channelConfiguration]; |
185 |
|
186 |
if (cfg->audioObjectType == 5) { |
187 |
sbr_present = 1; |
188 |
|
189 |
// TODO: parsing !!!!!!!!!!!!!!!! |
190 |
} |
191 |
|
192 |
switch (cfg->audioObjectType) { |
193 |
case 1: |
194 |
case 2: |
195 |
case 3: |
196 |
case 4: |
197 |
case 6: |
198 |
case 7: |
199 |
case 17: |
200 |
case 19: |
201 |
case 20: |
202 |
case 21: |
203 |
case 22: |
204 |
case 23: |
205 |
readGASpecificConfig(cfg, b, &o); |
206 |
break; |
207 |
} |
208 |
|
209 |
if (sbr_present == -1) { |
210 |
if (cfg->samplingFrequency <= 24000) { |
211 |
cfg->samplingFrequency *= 2; |
212 |
} |
213 |
} |
214 |
|
215 |
// count the extradata |
216 |
ret = put_bits_count(&o); |
217 |
align_put_bits(&o); |
218 |
flush_put_bits(&o); |
219 |
cfg->extrasize = (ret + 7) >> 3; |
220 |
return ret; |
221 |
} |
222 |
|
223 |
static void readStreamMuxConfig(struct AACParser *parser, GetBitContext *b) |
224 |
{ |
225 |
parser->audio_mux_version_A = 0; |
226 |
parser->audio_mux_version = get_bits(b, 1); |
227 |
if (parser->audio_mux_version == 1) { // audioMuxVersion |
228 |
parser->audio_mux_version_A = get_bits(b, 1); |
229 |
} |
230 |
|
231 |
if (parser->audio_mux_version_A == 0) { |
232 |
if (parser->audio_mux_version == 1) { |
233 |
parser->taraFullness = latm_get_value(b); |
234 |
} |
235 |
get_bits(b, 1); // allStreamSameTimeFraming = 1 |
236 |
get_bits(b, 6); // numSubFrames = 0 |
237 |
get_bits(b, 4); // numPrograms = 0 |
238 |
|
239 |
// for each program |
240 |
get_bits(b, 3); // numLayer = 0 |
241 |
|
242 |
// for each layer |
243 |
if (parser->audio_mux_version == 0) { |
244 |
// audio specific config. |
245 |
readAudioSpecificConfig(&parser->config, b); |
246 |
} else { |
247 |
int ascLen = latm_get_value(b); |
248 |
ascLen -= readAudioSpecificConfig(&parser->config, b); |
249 |
|
250 |
// fill bits |
251 |
while (ascLen > 16) { |
252 |
skip_bits(b, 16); |
253 |
ascLen -= 16; |
254 |
} |
255 |
skip_bits(b, ascLen); |
256 |
} |
257 |
|
258 |
// these are not needed... perhaps |
259 |
int frame_length_type = get_bits(b, 3); |
260 |
parser->frameLengthType = frame_length_type; |
261 |
if (frame_length_type == 0) { |
262 |
get_bits(b, 8); |
263 |
} else if (frame_length_type == 1) { |
264 |
get_bits(b, 9); |
265 |
} else if (frame_length_type == 3 || |
266 |
frame_length_type == 4 || |
267 |
frame_length_type == 5) { |
268 |
int celp_table_index = get_bits(b, 6); |
269 |
} else if (frame_length_type == 6 || |
270 |
frame_length_type == 7) { |
271 |
int hvxc_table_index = get_bits(b, 1); |
272 |
} |
273 |
|
274 |
// other data |
275 |
parser->other_data_bits = 0; |
276 |
if (get_bits(b, 1)) { |
277 |
// other data present |
278 |
if (parser->audio_mux_version == 1) { |
279 |
parser->other_data_bits = latm_get_value(b); |
280 |
} else { |
281 |
// other data not present |
282 |
parser->other_data_bits = 0; |
283 |
int esc, tmp; |
284 |
do { |
285 |
parser->other_data_bits <<= 8; |
286 |
esc = get_bits(b, 1); |
287 |
tmp = get_bits(b, 8); |
288 |
parser->other_data_bits |= tmp; |
289 |
} while (esc); |
290 |
} |
291 |
} |
292 |
|
293 |
// CRC |
294 |
if (get_bits(b, 1)) { |
295 |
parser->config_crc = get_bits(b, 8); |
296 |
} |
297 |
} else { |
298 |
// tbd |
299 |
} |
300 |
} |
301 |
|
302 |
static void readPayloadLengthInfo(struct AACParser *parser, GetBitContext *b) |
303 |
{ |
304 |
uint8_t tmp; |
305 |
if (parser->frameLengthType == 0) { |
306 |
parser->muxSlotLengthBytes = 0; |
307 |
do { |
308 |
tmp = get_bits(b, 8); |
309 |
parser->muxSlotLengthBytes += tmp; |
310 |
} while (tmp == 255); |
311 |
} else { |
312 |
if (parser->frameLengthType == 5 || |
313 |
parser->frameLengthType == 7 || |
314 |
parser->frameLengthType == 3) { |
315 |
get_bits(b, 2); |
316 |
} |
317 |
} |
318 |
} |
319 |
|
320 |
static void readAudioMuxElement(struct AACParser *parser, GetBitContext *b, uint8_t *payload, int *payloadsize) |
321 |
{ |
322 |
uint8_t use_same_mux = get_bits(b, 1); |
323 |
if (!use_same_mux) { |
324 |
readStreamMuxConfig(parser, b); |
325 |
} |
326 |
|
327 |
if (parser->audio_mux_version_A == 0) { |
328 |
int j; |
329 |
|
330 |
readPayloadLengthInfo(parser, b); |
331 |
|
332 |
// copy data |
333 |
for (j=0; j<parser->muxSlotLengthBytes; j++) { |
334 |
*payload++ = get_bits(b, 8); |
335 |
} |
336 |
*payloadsize = parser->muxSlotLengthBytes; |
337 |
|
338 |
// ignore otherdata |
339 |
} else { |
340 |
// TBD |
341 |
} |
342 |
} |
343 |
|
344 |
static int readAudioSyncStream(struct AACParser *parser, GetBitContext *b, int size, uint8_t *payload, int *payloadsize) |
345 |
{ |
346 |
// ISO/IEC 14496-3 Table 1.28 - Syntax of AudioMuxElement() |
347 |
if (get_bits(b, 11) != 0x2b7) return -1; // not LATM |
348 |
int muxlength = get_bits(b, 13); |
349 |
|
350 |
if (3+muxlength > size) return 0; // not enough data |
351 |
|
352 |
readAudioMuxElement(parser, b, payload, payloadsize); |
353 |
|
354 |
// we don't parse anything else here... |
355 |
return (3+muxlength); |
356 |
} |
357 |
|
358 |
|
359 |
static void flush_buf(struct AACParser *parser, int offset) { |
360 |
int bytes_to_flush = min(parser->count, offset); |
361 |
int left = (parser->count - bytes_to_flush); |
362 |
|
363 |
if (bytes_to_flush > 0) { |
364 |
if (left > 0) { |
365 |
memcpy(parser->buf, parser->buf+bytes_to_flush, left); |
366 |
parser->count = left; |
367 |
} else { |
368 |
parser->count = 0; |
369 |
} |
370 |
} |
371 |
} |
372 |
|
373 |
static struct AACParser *latm_create_parser() |
374 |
{ |
375 |
struct AACParser *parser = (struct AACParser *)av_malloc(sizeof(struct AACParser)); |
376 |
memset(parser, 0, sizeof(struct AACParser)); |
377 |
return parser; |
378 |
} |
379 |
|
380 |
static void latm_destroy_parser(struct AACParser *parser) |
381 |
{ |
382 |
av_free(parser); |
383 |
} |
384 |
|
385 |
static void latm_flush(struct AACParser *parser) |
386 |
{ |
387 |
parser->offset = 0; |
388 |
parser->count = 0; |
389 |
} |
390 |
|
391 |
static void latm_write_data(struct AACParser *parser, uint8_t *data, int len) |
392 |
{ |
393 |
// buffer overflow check... just ignore the data before |
394 |
if (parser->count + len > MAX_SIZE) { |
395 |
flush_buf(parser, parser->offset); |
396 |
parser->offset = 0; |
397 |
if (parser->count + len > MAX_SIZE) { |
398 |
int to_flush = (parser->count+len) - MAX_SIZE; |
399 |
flush_buf(parser, to_flush); |
400 |
} |
401 |
} |
402 |
|
403 |
// append data |
404 |
memcpy(parser->buf+parser->count, data, len); |
405 |
parser->count += len; |
406 |
} |
407 |
|
408 |
static int latm_parse_packet(struct AACParser *parser, uint8_t *data, int maxsize) |
409 |
{ |
410 |
/* |
411 |
Return value is either number of bytes parsed or |
412 |
-1 when failed. |
413 |
0 = need more data. |
414 |
*/ |
415 |
|
416 |
uint8_t *start = parser->buf + parser->offset; |
417 |
int bytes = parser->count - parser->offset; |
418 |
GetBitContext b; |
419 |
init_get_bits(&b, start, bytes * 8); |
420 |
|
421 |
if (parser->mode == AAC_LATM) { |
422 |
int outsize = 0; |
423 |
int ret = readAudioSyncStream(parser, &b, bytes, data, &outsize); |
424 |
|
425 |
if (ret < 0) return -1; |
426 |
if (ret == 0) return 0; |
427 |
|
428 |
// update the offset |
429 |
parser->offset += ret; |
430 |
return outsize; |
431 |
} |
432 |
|
433 |
// check for syncwords |
434 |
while (bytes > 2) { |
435 |
if (show_bits(&b, 11) == SYNC_LATM) { |
436 |
// we must parse config first... |
437 |
int outsize = 0; |
438 |
|
439 |
// check if there is a complete packet available... |
440 |
int ret = readAudioSyncStream(parser, &b, bytes, data, &outsize); |
441 |
if (ret < 0) return -1; |
442 |
if (ret == 0) return 0; |
443 |
parser->offset += ret; |
444 |
|
445 |
parser->mode = AAC_LATM; |
446 |
return outsize; |
447 |
} |
448 |
skip_bits(&b, 8); |
449 |
parser->offset++; |
450 |
bytes--; |
451 |
} |
452 |
return 0; |
453 |
} |
454 |
|
455 |
static void aac_filter_close(AACDecoder *decoder) |
456 |
{ |
457 |
if (decoder->aac_decoder) { |
458 |
NeAACDecClose(decoder->aac_decoder); |
459 |
decoder->aac_decoder = NULL; |
460 |
} |
461 |
decoder->open = 0; |
462 |
} |
463 |
|
464 |
static int aac_decoder_open(AACDecoder *decoder) |
465 |
{ |
466 |
if (decoder->aac_decoder) return 0; |
467 |
|
468 |
decoder->aac_decoder = NeAACDecOpen(); |
469 |
if (!decoder->aac_decoder) return -1; |
470 |
|
471 |
// are we going to initialize from decoder specific info ? |
472 |
if (decoder->parser->config.extrasize > 0) { |
473 |
char ret = NeAACDecInit2(decoder->aac_decoder, (unsigned char*)decoder->parser->config.extra, decoder->parser->config.extrasize, &decoder->in_samplerate, &decoder->in_channels); |
474 |
if (ret < 0) { |
475 |
aac_filter_close(decoder); // gone wrong ? |
476 |
return -1; |
477 |
} |
478 |
decoder->open = 1; |
479 |
} else { |
480 |
// we'll open the decoder later... |
481 |
decoder->open = 0; |
482 |
} |
483 |
return 0; |
484 |
} |
485 |
|
486 |
AACDecoder *aac_filter_create() |
487 |
{ |
488 |
AACDecoder *decoder = (AACDecoder *)av_malloc(sizeof(AACDecoder)); |
489 |
decoder->parser = latm_create_parser(); |
490 |
decoder->aac_decoder = NULL; |
491 |
decoder->open = 0; |
492 |
return (void *)decoder; |
493 |
} |
494 |
|
495 |
void aac_filter_destroy(AACDecoder *decoder) |
496 |
{ |
497 |
aac_filter_close(decoder); |
498 |
latm_destroy_parser(decoder->parser); |
499 |
av_free(decoder); |
500 |
} |
501 |
|
502 |
int aac_filter_receive(AACDecoder *decoder, void *out, int *out_size, uint8_t *data, int size) |
503 |
{ |
504 |
uint8_t tempbuf[32*1024]; |
505 |
int ret; |
506 |
int consumed = size; |
507 |
int decoded; |
508 |
int max_size = *out_size; |
509 |
|
510 |
*out_size = 0; |
511 |
|
512 |
//------------------------------------------------------------------------- |
513 |
// Multiplex Parsing |
514 |
//------------------------------------------------------------------------- |
515 |
|
516 |
latm_write_data(decoder->parser, data, size); |
517 |
|
518 |
do { |
519 |
ret = latm_parse_packet(decoder->parser, tempbuf, sizeof(tempbuf)); |
520 |
if (ret < 0) { |
521 |
latm_flush(decoder->parser); |
522 |
return consumed; |
523 |
} |
524 |
if (ret == 0) return consumed; |
525 |
|
526 |
data = tempbuf; |
527 |
size = ret; |
528 |
|
529 |
//------------------------------------------------------------------------- |
530 |
// Initialize decoder (if necessary) |
531 |
//------------------------------------------------------------------------- |
532 |
if (!decoder->open) { |
533 |
aac_filter_close(decoder); |
534 |
if (decoder->parser->mode == AAC_LATM) { |
535 |
ret = aac_decoder_open(decoder); |
536 |
if (ret < 0) return consumed; |
537 |
} |
538 |
|
539 |
if(!decoder->open) return consumed; |
540 |
} |
541 |
|
542 |
//------------------------------------------------------------------------- |
543 |
// Decode samples |
544 |
//------------------------------------------------------------------------- |
545 |
NeAACDecFrameInfo info; |
546 |
void *buf = NeAACDecDecode(decoder->aac_decoder, &info, data, size); |
547 |
|
548 |
if (buf) { |
549 |
decoder->in_samplerate = info.samplerate; |
550 |
decoder->in_channels = info.channels; |
551 |
|
552 |
//--------------------------------------------------------------------- |
553 |
// Deliver decoded samples |
554 |
//--------------------------------------------------------------------- |
555 |
|
556 |
// kram dekoduje 16-bit. my vypustame 16-bit. takze by to malo byt okej |
557 |
decoded = info.samples * sizeof(short); |
558 |
|
559 |
// napraskame tam sample |
560 |
*out_size += decoded; |
561 |
if(*out_size > max_size) { |
562 |
av_log(NULL, AV_LOG_ERROR, "overflow!\n"); |
563 |
} else { |
564 |
memcpy(out, buf, decoded); |
565 |
out = (unsigned char *)out + decoded; |
566 |
} |
567 |
} else { |
568 |
// need more data |
569 |
break; |
570 |
} |
571 |
|
572 |
} while (1); // decode all packets |
573 |
return consumed; |
574 |
} |
575 |
|
576 |
void aac_filter_getinfo(AACDecoder *decoder, int *sample_rate, int *channels) |
577 |
{ |
578 |
if(!decoder->open) return; |
579 |
*sample_rate = decoder->in_samplerate; |
580 |
*channels = decoder->in_channels; |
581 |
} |
582 |
|
583 |
static int faac_decode_init(AVCodecContext *avctx) |
584 |
{ |
585 |
FAACContext *s = avctx->priv_data; |
586 |
avctx->frame_size = 360; |
587 |
avctx->sample_rate = 48000; |
588 |
avctx->channels = 2; |
589 |
avctx->bit_rate = 8192 * 8 * avctx->sample_rate / avctx->frame_size; |
590 |
s->decoder = aac_filter_create(); |
591 |
return 0; |
592 |
} |
593 |
|
594 |
static int faac_decode_frame(AVCodecContext *avctx, |
595 |
void *data, int *data_size, |
596 |
uint8_t *buf, int buf_size) |
597 |
{ |
598 |
FAACContext *s = avctx->priv_data; |
599 |
int ret; |
600 |
|
601 |
if (s->decoder == NULL) faac_decode_init(avctx); |
602 |
ret = aac_filter_receive(s->decoder, data, data_size, buf, buf_size); |
603 |
aac_filter_getinfo(s->decoder, &(avctx->sample_rate), &(avctx->channels)); |
604 |
return ret; |
605 |
} |
606 |
|
607 |
static int faac_decode_end(AVCodecContext *avctx) |
608 |
{ |
609 |
FAACContext *s = avctx->priv_data; |
610 |
if(s->decoder != NULL) { |
611 |
aac_filter_destroy(s->decoder); |
612 |
} |
613 |
return 0; |
614 |
} |
615 |
|
616 |
|
617 |
|
618 |
#define LATM_HEADER 0x56e000 // 0x2b7 (11 bits) |
619 |
#define LATM_MASK 0xFFE000 // top 11 bits |
620 |
#define LATM_SIZE_MASK 0x001FFF // bottom 13 bits |
621 |
|
622 |
typedef struct LATMParseContext{ |
623 |
ParseContext pc; |
624 |
int count; |
625 |
} LATMParseContext; |
626 |
|
627 |
/** |
628 |
* finds the end of the current frame in the bitstream. |
629 |
* @return the position of the first byte of the next frame, or -1 |
630 |
*/ |
631 |
static int latm_find_frame_end(AVCodecParserContext *s1, const uint8_t *buf, |
632 |
int buf_size) { |
633 |
LATMParseContext *s = s1->priv_data; |
634 |
ParseContext *pc = &s->pc; |
635 |
int pic_found, i; |
636 |
uint32_t state; |
637 |
|
638 |
pic_found = pc->frame_start_found; |
639 |
state = pc->state; |
640 |
|
641 |
i = 0; |
642 |
if(!pic_found){ |
643 |
for(i=0; i<buf_size; i++){ |
644 |
state = (state<<8) | buf[i]; |
645 |
if((state & LATM_MASK) == LATM_HEADER){ |
646 |
i++; |
647 |
s->count = - i; |
648 |
pic_found=1; |
649 |
break; |
650 |
} |
651 |
} |
652 |
} |
653 |
|
654 |
if(pic_found){ |
655 |
/* EOF considered as end of frame */ |
656 |
if (buf_size == 0) |
657 |
return 0; |
658 |
if((state & LATM_SIZE_MASK) - s->count <= buf_size) { |
659 |
pc->frame_start_found = 0; |
660 |
pc->state = -1; |
661 |
return (state & LATM_SIZE_MASK) - s->count; |
662 |
} |
663 |
} |
664 |
|
665 |
s->count += buf_size; |
666 |
pc->frame_start_found = pic_found; |
667 |
pc->state = state; |
668 |
return END_NOT_FOUND; |
669 |
} |
670 |
|
671 |
static int latm_parse(AVCodecParserContext *s1, |
672 |
AVCodecContext *avctx, |
673 |
const uint8_t **poutbuf, int *poutbuf_size, |
674 |
const uint8_t *buf, int buf_size) |
675 |
{ |
676 |
LATMParseContext *s = s1->priv_data; |
677 |
ParseContext *pc = &s->pc; |
678 |
int next; |
679 |
|
680 |
if(s1->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
681 |
next = buf_size; |
682 |
}else{ |
683 |
next = latm_find_frame_end(s1, buf, buf_size); |
684 |
|
685 |
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { |
686 |
*poutbuf = NULL; |
687 |
*poutbuf_size = 0; |
688 |
return buf_size; |
689 |
} |
690 |
} |
691 |
*poutbuf = buf; |
692 |
*poutbuf_size = buf_size; |
693 |
return next; |
694 |
} |
695 |
|
696 |
static int latm_split(AVCodecContext *avctx, |
697 |
const uint8_t *buf, int buf_size) |
698 |
{ |
699 |
int i; |
700 |
uint32_t state= -1; |
701 |
|
702 |
for(i=0; i<buf_size; i++){ |
703 |
state= (state<<8) | buf[i]; |
704 |
if((state & LATM_MASK) == LATM_HEADER) |
705 |
return i-2; |
706 |
} |
707 |
return 0; |
708 |
} |
709 |
|
710 |
AVCodec libfaad2_decoder = { |
711 |
.name = "AAC/LATM", |
712 |
.type = CODEC_TYPE_AUDIO, |
713 |
.id = CODEC_ID_AAC_LATM, |
714 |
.priv_data_size = sizeof (FAACContext), |
715 |
.init = faac_decode_init, |
716 |
.close = faac_decode_end, |
717 |
.decode = faac_decode_frame, |
718 |
}; |
719 |
|
720 |
AVCodecParser latm_parser = { |
721 |
{ CODEC_ID_AAC_LATM }, |
722 |
sizeof(LATMParseContext), |
723 |
NULL, |
724 |
latm_parse, |
725 |
ff_parse_close, |
726 |
latm_split, |
727 |
}; |