Mercurial > libavcodec.hg
comparison parser.c @ 4913:b7bde71aa752 libavcodec
move mpegaudio_parser in it's own file
author | aurel |
---|---|
date | Sat, 05 May 2007 18:08:16 +0000 |
parents | 5fc99f2a111b |
children | 0d1cc37d9430 |
comparison
equal
deleted
inserted
replaced
4912:5fc99f2a111b | 4913:b7bde71aa752 |
---|---|
311 } | 311 } |
312 return 0; | 312 return 0; |
313 } | 313 } |
314 | 314 |
315 /*************************/ | 315 /*************************/ |
316 | |
317 #ifdef CONFIG_MPEGAUDIO_PARSER | |
318 typedef struct MpegAudioParseContext { | |
319 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ | |
320 uint8_t *inbuf_ptr; | |
321 int frame_size; | |
322 int free_format_frame_size; | |
323 int free_format_next_header; | |
324 uint32_t header; | |
325 int header_count; | |
326 } MpegAudioParseContext; | |
327 | |
328 #define MPA_HEADER_SIZE 4 | |
329 | |
330 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
331 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ | |
332 #define SAME_HEADER_MASK \ | |
333 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) | |
334 | |
335 static int mpegaudio_parse_init(AVCodecParserContext *s1) | |
336 { | |
337 MpegAudioParseContext *s = s1->priv_data; | |
338 s->inbuf_ptr = s->inbuf; | |
339 return 0; | |
340 } | |
341 | |
342 static int mpegaudio_parse(AVCodecParserContext *s1, | |
343 AVCodecContext *avctx, | |
344 uint8_t **poutbuf, int *poutbuf_size, | |
345 const uint8_t *buf, int buf_size) | |
346 { | |
347 MpegAudioParseContext *s = s1->priv_data; | |
348 int len, ret, sr; | |
349 uint32_t header; | |
350 const uint8_t *buf_ptr; | |
351 | |
352 *poutbuf = NULL; | |
353 *poutbuf_size = 0; | |
354 buf_ptr = buf; | |
355 while (buf_size > 0) { | |
356 len = s->inbuf_ptr - s->inbuf; | |
357 if (s->frame_size == 0) { | |
358 /* special case for next header for first frame in free | |
359 format case (XXX: find a simpler method) */ | |
360 if (s->free_format_next_header != 0) { | |
361 s->inbuf[0] = s->free_format_next_header >> 24; | |
362 s->inbuf[1] = s->free_format_next_header >> 16; | |
363 s->inbuf[2] = s->free_format_next_header >> 8; | |
364 s->inbuf[3] = s->free_format_next_header; | |
365 s->inbuf_ptr = s->inbuf + 4; | |
366 s->free_format_next_header = 0; | |
367 goto got_header; | |
368 } | |
369 /* no header seen : find one. We need at least MPA_HEADER_SIZE | |
370 bytes to parse it */ | |
371 len = FFMIN(MPA_HEADER_SIZE - len, buf_size); | |
372 if (len > 0) { | |
373 memcpy(s->inbuf_ptr, buf_ptr, len); | |
374 buf_ptr += len; | |
375 buf_size -= len; | |
376 s->inbuf_ptr += len; | |
377 } | |
378 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
379 got_header: | |
380 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
381 (s->inbuf[2] << 8) | s->inbuf[3]; | |
382 | |
383 ret = mpa_decode_header(avctx, header, &sr); | |
384 if (ret < 0) { | |
385 s->header_count= -2; | |
386 /* no sync found : move by one byte (inefficient, but simple!) */ | |
387 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
388 s->inbuf_ptr--; | |
389 dprintf(avctx, "skip %x\n", header); | |
390 /* reset free format frame size to give a chance | |
391 to get a new bitrate */ | |
392 s->free_format_frame_size = 0; | |
393 } else { | |
394 if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) | |
395 s->header_count= -3; | |
396 s->header= header; | |
397 s->header_count++; | |
398 s->frame_size = ret; | |
399 | |
400 #if 0 | |
401 /* free format: prepare to compute frame size */ | |
402 if (decode_header(s, header) == 1) { | |
403 s->frame_size = -1; | |
404 } | |
405 #endif | |
406 } | |
407 if(s->header_count > 1) | |
408 avctx->sample_rate= sr; | |
409 } | |
410 } else | |
411 #if 0 | |
412 if (s->frame_size == -1) { | |
413 /* free format : find next sync to compute frame size */ | |
414 len = MPA_MAX_CODED_FRAME_SIZE - len; | |
415 if (len > buf_size) | |
416 len = buf_size; | |
417 if (len == 0) { | |
418 /* frame too long: resync */ | |
419 s->frame_size = 0; | |
420 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
421 s->inbuf_ptr--; | |
422 } else { | |
423 uint8_t *p, *pend; | |
424 uint32_t header1; | |
425 int padding; | |
426 | |
427 memcpy(s->inbuf_ptr, buf_ptr, len); | |
428 /* check for header */ | |
429 p = s->inbuf_ptr - 3; | |
430 pend = s->inbuf_ptr + len - 4; | |
431 while (p <= pend) { | |
432 header = (p[0] << 24) | (p[1] << 16) | | |
433 (p[2] << 8) | p[3]; | |
434 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
435 (s->inbuf[2] << 8) | s->inbuf[3]; | |
436 /* check with high probability that we have a | |
437 valid header */ | |
438 if ((header & SAME_HEADER_MASK) == | |
439 (header1 & SAME_HEADER_MASK)) { | |
440 /* header found: update pointers */ | |
441 len = (p + 4) - s->inbuf_ptr; | |
442 buf_ptr += len; | |
443 buf_size -= len; | |
444 s->inbuf_ptr = p; | |
445 /* compute frame size */ | |
446 s->free_format_next_header = header; | |
447 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
448 padding = (header1 >> 9) & 1; | |
449 if (s->layer == 1) | |
450 s->free_format_frame_size -= padding * 4; | |
451 else | |
452 s->free_format_frame_size -= padding; | |
453 dprintf(avctx, "free frame size=%d padding=%d\n", | |
454 s->free_format_frame_size, padding); | |
455 decode_header(s, header1); | |
456 goto next_data; | |
457 } | |
458 p++; | |
459 } | |
460 /* not found: simply increase pointers */ | |
461 buf_ptr += len; | |
462 s->inbuf_ptr += len; | |
463 buf_size -= len; | |
464 } | |
465 } else | |
466 #endif | |
467 if (len < s->frame_size) { | |
468 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
469 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
470 len = FFMIN(s->frame_size - len, buf_size); | |
471 memcpy(s->inbuf_ptr, buf_ptr, len); | |
472 buf_ptr += len; | |
473 s->inbuf_ptr += len; | |
474 buf_size -= len; | |
475 } | |
476 | |
477 if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf | |
478 && buf_size + buf_ptr - buf >= s->frame_size){ | |
479 if(s->header_count > 0){ | |
480 *poutbuf = buf; | |
481 *poutbuf_size = s->frame_size; | |
482 } | |
483 buf_ptr = buf + s->frame_size; | |
484 s->inbuf_ptr = s->inbuf; | |
485 s->frame_size = 0; | |
486 break; | |
487 } | |
488 | |
489 // next_data: | |
490 if (s->frame_size > 0 && | |
491 (s->inbuf_ptr - s->inbuf) >= s->frame_size) { | |
492 if(s->header_count > 0){ | |
493 *poutbuf = s->inbuf; | |
494 *poutbuf_size = s->inbuf_ptr - s->inbuf; | |
495 } | |
496 s->inbuf_ptr = s->inbuf; | |
497 s->frame_size = 0; | |
498 break; | |
499 } | |
500 } | |
501 return buf_ptr - buf; | |
502 } | |
503 #endif /* CONFIG_MPEGAUDIO_PARSER */ | |
504 | 316 |
505 #if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER) | 317 #if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER) |
506 /* also used for ADTS AAC */ | 318 /* also used for ADTS AAC */ |
507 typedef struct AC3ParseContext { | 319 typedef struct AC3ParseContext { |
508 uint8_t *inbuf_ptr; | 320 uint8_t *inbuf_ptr; |
777 } | 589 } |
778 return buf_ptr - buf; | 590 return buf_ptr - buf; |
779 } | 591 } |
780 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ | 592 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ |
781 | 593 |
782 #ifdef CONFIG_MPEGAUDIO_PARSER | |
783 AVCodecParser mpegaudio_parser = { | |
784 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
785 sizeof(MpegAudioParseContext), | |
786 mpegaudio_parse_init, | |
787 mpegaudio_parse, | |
788 NULL, | |
789 }; | |
790 #endif | |
791 #ifdef CONFIG_AC3_PARSER | 594 #ifdef CONFIG_AC3_PARSER |
792 AVCodecParser ac3_parser = { | 595 AVCodecParser ac3_parser = { |
793 { CODEC_ID_AC3 }, | 596 { CODEC_ID_AC3 }, |
794 sizeof(AC3ParseContext), | 597 sizeof(AC3ParseContext), |
795 ac3_parse_init, | 598 ac3_parse_init, |