diff options
author | Aurelien Jacobs <aurel@gnuage.org> | 2006-11-23 22:22:03 +0000 |
---|---|---|
committer | Aurelien Jacobs <aurel@gnuage.org> | 2006-11-23 22:22:03 +0000 |
commit | 17c90b9d62fe395d40e7d80a47ff8a72d57e2a7c (patch) | |
tree | 33b5cfded5940fee9746f7cee4602eb08594577a /libavcodec | |
parent | 3e954443dd4ae9b5f644de11f04cfb59a4e82685 (diff) | |
download | ffmpeg-streaming-17c90b9d62fe395d40e7d80a47ff8a72d57e2a7c.zip ffmpeg-streaming-17c90b9d62fe395d40e7d80a47ff8a72d57e2a7c.tar.gz |
flac: allow reading of full metadata headers from extradata
Originally committed as revision 7161 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/flac.c | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/libavcodec/flac.c b/libavcodec/flac.c index 47459b2..6c64ad0 100644 --- a/libavcodec/flac.c +++ b/libavcodec/flac.c @@ -95,18 +95,23 @@ static int64_t get_utf8(GetBitContext *gb){ } static void metadata_streaminfo(FLACContext *s); -static void dump_headers(FLACContext *s); +static void allocate_buffers(FLACContext *s); +static int metadata_parse(FLACContext *s); static int flac_decode_init(AVCodecContext * avctx) { FLACContext *s = avctx->priv_data; s->avctx = avctx; - /* initialize based on the demuxer-supplied streamdata header */ - if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) { + if (avctx->extradata_size > 4) { + /* initialize based on the demuxer-supplied streamdata header */ init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); - metadata_streaminfo(s); - dump_headers(s); + if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) { + metadata_streaminfo(s); + allocate_buffers(s); + } else { + metadata_parse(s); + } } return 0; @@ -159,7 +164,51 @@ static void metadata_streaminfo(FLACContext *s) skip_bits(&s->gb, 64); /* md5 sum */ skip_bits(&s->gb, 64); /* md5 sum */ - allocate_buffers(s); + dump_headers(s); +} + +/** + * Parse a list of metadata blocks. This list of blocks must begin with + * the fLaC marker. + * @param s the flac decoding context containing the gb bit reader used to + * parse metadata + * @return 1 if some metadata was read, 0 if no fLaC marker was found + */ +static int metadata_parse(FLACContext *s) +{ + int i, metadata_last, metadata_type, metadata_size, streaminfo_updated=0; + + if (show_bits_long(&s->gb, 32) == MKBETAG('f','L','a','C')) { + skip_bits(&s->gb, 32); + + av_log(s->avctx, AV_LOG_DEBUG, "STREAM HEADER\n"); + do { + metadata_last = get_bits(&s->gb, 1); + metadata_type = get_bits(&s->gb, 7); + metadata_size = get_bits_long(&s->gb, 24); + + av_log(s->avctx, AV_LOG_DEBUG, + " metadata block: flag = %d, type = %d, size = %d\n", + metadata_last, metadata_type, metadata_size); + if (metadata_size) { + switch (metadata_type) { + case METADATA_TYPE_STREAMINFO: + metadata_streaminfo(s); + streaminfo_updated = 1; + break; + + default: + for (i=0; i<metadata_size; i++) + skip_bits(&s->gb, 8); + } + } + } while (!metadata_last); + + if (streaminfo_updated) + allocate_buffers(s); + return 1; + } + return 0; } static int decode_residuals(FLACContext *s, int channel, int pred_order) @@ -528,7 +577,6 @@ static int flac_decode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size) { FLACContext *s = avctx->priv_data; - int metadata_last, metadata_type, metadata_size; int tmp = 0, i, j = 0, input_buf_size = 0; int16_t *samples = data; @@ -559,47 +607,8 @@ static int flac_decode_frame(AVCodecContext *avctx, init_get_bits(&s->gb, buf, buf_size*8); - /* fLaC signature (be) */ - if (show_bits_long(&s->gb, 32) == bswap_32(ff_get_fourcc("fLaC"))) + if (!metadata_parse(s)) { - skip_bits(&s->gb, 32); - - av_log(s->avctx, AV_LOG_DEBUG, "STREAM HEADER\n"); - do { - metadata_last = get_bits(&s->gb, 1); - metadata_type = get_bits(&s->gb, 7); - metadata_size = get_bits_long(&s->gb, 24); - - av_log(s->avctx, AV_LOG_DEBUG, " metadata block: flag = %d, type = %d, size = %d\n", - metadata_last, metadata_type, - metadata_size); - if(metadata_size){ - switch(metadata_type) - { - case METADATA_TYPE_STREAMINFO:{ - metadata_streaminfo(s); - - /* Buffer might have been reallocated, reinit bitreader */ - if(buf != &s->bitstream[s->bitstream_index]) - { - int bits_count = get_bits_count(&s->gb); - buf= &s->bitstream[s->bitstream_index]; - init_get_bits(&s->gb, buf, buf_size*8); - skip_bits(&s->gb, bits_count); - } - - dump_headers(s); - break;} - default: - for(i=0; i<metadata_size; i++) - skip_bits(&s->gb, 8); - } - } - } while(!metadata_last); - } - else - { - tmp = show_bits(&s->gb, 16); if(tmp != 0xFFF8){ av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); |