diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2009-03-06 01:31:10 +0000 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2009-03-06 01:31:10 +0000 |
commit | f48b9304cda7db7ca328f046af48e73931589ff5 (patch) | |
tree | f265ff1e356b7abb86fecaec515cff3c83c6d8df | |
parent | 5b63d33d7d178cdf4581b946a4f758695f2123f9 (diff) | |
download | ffmpeg-f48b9304cda7db7ca328f046af48e73931589ff5.tar.gz |
flacdec: Parse the metadata header in the raw FLAC demuxer.
Originally committed as revision 17852 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/Makefile | 1 | ||||
-rw-r--r-- | libavformat/Makefile | 2 | ||||
-rw-r--r-- | libavformat/flacdec.c | 77 | ||||
-rw-r--r-- | tests/seek.regression.ref | 22 |
4 files changed, 89 insertions, 13 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile index d0123be4d0..ee0d24d403 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -344,6 +344,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o # libavformat dependencies OBJS-$(CONFIG_EAC3_DEMUXER) += ac3_parser.o ac3tab.o aac_ac3_parser.o +OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o flacdec.o diff --git a/libavformat/Makefile b/libavformat/Makefile index e3f59b2a01..6825e2ff85 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -53,7 +53,7 @@ OBJS-$(CONFIG_EAC3_DEMUXER) += raw.o id3v2.o OBJS-$(CONFIG_EAC3_MUXER) += raw.o OBJS-$(CONFIG_FFM_DEMUXER) += ffmdec.o OBJS-$(CONFIG_FFM_MUXER) += ffmenc.o -OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o raw.o id3v2.o +OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o raw.o id3v2.o oggparsevorbis.o OBJS-$(CONFIG_FLAC_MUXER) += flacenc.o OBJS-$(CONFIG_FLIC_DEMUXER) += flic.o OBJS-$(CONFIG_FLV_DEMUXER) += flvdec.o diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 83758b2be0..9db65bdd7d 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -19,15 +19,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/flac.h" #include "avformat.h" #include "raw.h" #include "id3v2.h" +#include "oggdec.h" static int flac_read_header(AVFormatContext *s, AVFormatParameters *ap) { uint8_t buf[ID3v2_HEADER_SIZE]; - int ret; + int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; + uint8_t header[4]; + uint8_t *buffer=NULL; AVStream *st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); @@ -44,6 +48,77 @@ static int flac_read_header(AVFormatContext *s, } else { url_fseek(s->pb, 0, SEEK_SET); } + + /* if fLaC marker is not found, assume there is no header */ + if (get_le32(s->pb) != MKTAG('f','L','a','C')) + return 0; + + /* process metadata blocks */ + while (!url_feof(s->pb) && !metadata_last) { + get_buffer(s->pb, header, 4); + ff_flac_parse_block_header(header, &metadata_last, &metadata_type, + &metadata_size); + switch (metadata_type) { + /* allocate and read metadata block for supported types */ + case FLAC_METADATA_TYPE_STREAMINFO: + case FLAC_METADATA_TYPE_VORBIS_COMMENT: + buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!buffer) { + return AVERROR_NOMEM; + } + if (get_buffer(s->pb, buffer, metadata_size) != metadata_size) { + av_freep(&buffer); + return AVERROR_IO; + } + break; + /* skip metadata block for unsupported types */ + default: + ret = url_fseek(s->pb, metadata_size, SEEK_CUR); + if (ret < 0) + return ret; + } + + if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) { + FLACStreaminfo si; + /* STREAMINFO can only occur once */ + if (found_streaminfo) { + av_freep(&buffer); + return AVERROR_INVALIDDATA; + } + if (metadata_size != FLAC_STREAMINFO_SIZE) { + av_freep(&buffer); + return AVERROR_INVALIDDATA; + } + found_streaminfo = 1; + st->codec->extradata = buffer; + st->codec->extradata_size = metadata_size; + buffer = NULL; + + /* get codec params from STREAMINFO header */ + ff_flac_parse_streaminfo(st->codec, &si, st->codec->extradata); + + /* set time base and duration */ + if (si.samplerate > 0) { + av_set_pts_info(st, 64, 1, si.samplerate); + if (si.samples > 0) + st->duration = si.samples; + } + } else { + /* STREAMINFO must be the first block */ + if (!found_streaminfo) { + av_freep(&buffer); + return AVERROR_INVALIDDATA; + } + /* process supported blocks other than STREAMINFO */ + if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { + if (vorbis_comment(s, buffer, metadata_size)) { + av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n"); + } + } + av_freep(&buffer); + } + } + return 0; } diff --git a/tests/seek.regression.ref b/tests/seek.regression.ref index e918736085..014078c18a 100644 --- a/tests/seek.regression.ref +++ b/tests/seek.regression.ref @@ -585,31 +585,31 @@ ret: 0 st: 0 dts:0.480000 pts:0.480000 pos:796840 size:67971 flags:1 ret:-1 st:-1 ts:-0.645825 flags:1 ---------------- tests/data/a-flac.flac -ret: 0 st: 0 dts:-102481911520608.625000 pts:-102481911520608.625000 pos:0 size:1024 flags:1 +ret: 0 st: 0 dts:-209146758205323.718750 pts:-209146758205323.718750 pos:42 size:1024 flags:1 ret:-1 st:-1 ts:-1.000000 flags:0 ret:-1 st:-1 ts:1.894167 flags:1 -ret:-1 st: 0 ts:0.788333 flags:0 -ret:-1 st: 0 ts:-0.317500 flags:1 +ret:-1 st: 0 ts:0.788345 flags:0 +ret:-1 st: 0 ts:-0.317506 flags:1 ret:-1 st:-1 ts:2.576668 flags:0 ret:-1 st:-1 ts:1.470835 flags:1 -ret:-1 st: 0 ts:0.365000 flags:0 -ret:-1 st: 0 ts:-0.740833 flags:1 +ret:-1 st: 0 ts:0.365011 flags:0 +ret:-1 st: 0 ts:-0.740839 flags:1 ret:-1 st:-1 ts:2.153336 flags:0 ret:-1 st:-1 ts:1.047503 flags:1 -ret:-1 st: 0 ts:-0.058333 flags:0 -ret:-1 st: 0 ts:2.835833 flags:1 +ret:-1 st: 0 ts:-0.058322 flags:0 +ret:-1 st: 0 ts:2.835828 flags:1 ret:-1 st:-1 ts:1.730004 flags:0 ret:-1 st:-1 ts:0.624171 flags:1 -ret:-1 st: 0 ts:-0.481667 flags:0 -ret:-1 st: 0 ts:2.412500 flags:1 +ret:-1 st: 0 ts:-0.481655 flags:0 +ret:-1 st: 0 ts:2.412494 flags:1 ret:-1 st:-1 ts:1.306672 flags:0 ret:-1 st:-1 ts:0.200839 flags:1 ret:-1 st: 0 ts:-0.904989 flags:0 -ret:-1 st: 0 ts:1.989178 flags:1 +ret:-1 st: 0 ts:1.989184 flags:1 ret:-1 st:-1 ts:0.883340 flags:0 ret:-1 st:-1 ts:-0.222493 flags:1 ret:-1 st: 0 ts:2.671678 flags:0 -ret:-1 st: 0 ts:1.565844 flags:1 +ret:-1 st: 0 ts:1.565850 flags:1 ret:-1 st:-1 ts:0.460008 flags:0 ret:-1 st:-1 ts:-0.645825 flags:1 ---------------- |