annotate flacdec.c @ 5747:551765b1772b libavformat

Ensure that we write clusters and blocks with known size when streaming Too many demuxers can't cope with clusters of unknown size.
author conrad
date Thu, 04 Mar 2010 08:53:14 +0000
parents 3aabdadf9d5f
children e3830094915a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 868
diff changeset
1 /*
4610
41542d2edcf4 Separate the raw FLAC demuxer from raw.c and put in a new file,
jbr
parents: 4577
diff changeset
2 * Raw FLAC demuxer
4251
77e0c7511d41 cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 4206
diff changeset
3 * Copyright (c) 2001 Fabrice Bellard
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
4 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1245
diff changeset
5 * This file is part of FFmpeg.
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1245
diff changeset
6 *
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1245
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1245
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
11 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1245
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
15 * Lesser General Public License for more details.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
16 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1245
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
896
edbe5c3717f9 Update licensing information: The FSF changed postal address.
diego
parents: 887
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
20 */
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3274
diff changeset
21
4662
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
22 #include "libavcodec/flac.h"
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
23 #include "avformat.h"
2545
213268d7594e move unrelated functions declarations out of allformats.h
aurel
parents: 2368
diff changeset
24 #include "raw.h"
4254
d05b13327b07 Fix probing of files with ID3v2 tags. Discussed at
alexc
parents: 4251
diff changeset
25 #include "id3v2.h"
4662
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
26 #include "oggdec.h"
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
27
4610
41542d2edcf4 Separate the raw FLAC demuxer from raw.c and put in a new file,
jbr
parents: 4577
diff changeset
28 static int flac_read_header(AVFormatContext *s,
3268
319c36da904b set demuxers .value and use common audio_read_header function
bcoudurier
parents: 3238
diff changeset
29 AVFormatParameters *ap)
63
8329ba7cbd01 raw ac3 auto detects parameters
bellard
parents: 49
diff changeset
30 {
4610
41542d2edcf4 Separate the raw FLAC demuxer from raw.c and put in a new file,
jbr
parents: 4577
diff changeset
31 uint8_t buf[ID3v2_HEADER_SIZE];
4662
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
32 int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
33 uint8_t header[4];
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
34 uint8_t *buffer=NULL;
3268
319c36da904b set demuxers .value and use common audio_read_header function
bcoudurier
parents: 3238
diff changeset
35 AVStream *st = av_new_stream(s, 0);
686
e2687b784c3a shorten decoder by (Jeff Muizelaar <jrmuizel gmail com>)
michael
parents: 637
diff changeset
36 if (!st)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2231
diff changeset
37 return AVERROR(ENOMEM);
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 814
diff changeset
38 st->codec->codec_type = CODEC_TYPE_AUDIO;
4610
41542d2edcf4 Separate the raw FLAC demuxer from raw.c and put in a new file,
jbr
parents: 4577
diff changeset
39 st->codec->codec_id = CODEC_ID_FLAC;
2023
a3e79d6e4e3c add an enum for need_parsing
aurel
parents: 2022
diff changeset
40 st->need_parsing = AVSTREAM_PARSE_FULL;
931
7420a756dc7a read/write adts aac
mru
parents: 930
diff changeset
41 /* the parameters will be extracted from the compressed bitstream */
4285
d8803d0a4274 Handle ID3v2 tags in raw FLAC streams by skipping them.
jbr
parents: 4254
diff changeset
42
4612
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
43 /* skip ID3v2 header if found */
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
44 ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
45 if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf)) {
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
46 int len = ff_id3v2_tag_len(buf);
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
47 url_fseek(s->pb, len - ID3v2_HEADER_SIZE, SEEK_CUR);
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
48 } else {
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
49 url_fseek(s->pb, 0, SEEK_SET);
259725e31ef1 cosmetics: indentation
jbr
parents: 4610
diff changeset
50 }
4662
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
51
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
52 /* if fLaC marker is not found, assume there is no header */
4760
9a8c5a8c64ea seek backwards 4 bytes if 'fLaC' marker is not found
jbr
parents: 4662
diff changeset
53 if (get_le32(s->pb) != MKTAG('f','L','a','C')) {
9a8c5a8c64ea seek backwards 4 bytes if 'fLaC' marker is not found
jbr
parents: 4662
diff changeset
54 url_fseek(s->pb, -4, SEEK_CUR);
4662
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
55 return 0;
4760
9a8c5a8c64ea seek backwards 4 bytes if 'fLaC' marker is not found
jbr
parents: 4662
diff changeset
56 }
4662
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
57
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
58 /* process metadata blocks */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
59 while (!url_feof(s->pb) && !metadata_last) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
60 get_buffer(s->pb, header, 4);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
61 ff_flac_parse_block_header(header, &metadata_last, &metadata_type,
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
62 &metadata_size);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
63 switch (metadata_type) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
64 /* allocate and read metadata block for supported types */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
65 case FLAC_METADATA_TYPE_STREAMINFO:
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
66 case FLAC_METADATA_TYPE_VORBIS_COMMENT:
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
67 buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
68 if (!buffer) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
69 return AVERROR_NOMEM;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
70 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
71 if (get_buffer(s->pb, buffer, metadata_size) != metadata_size) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
72 av_freep(&buffer);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
73 return AVERROR_IO;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
74 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
75 break;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
76 /* skip metadata block for unsupported types */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
77 default:
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
78 ret = url_fseek(s->pb, metadata_size, SEEK_CUR);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
79 if (ret < 0)
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
80 return ret;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
81 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
82
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
83 if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
84 FLACStreaminfo si;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
85 /* STREAMINFO can only occur once */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
86 if (found_streaminfo) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
87 av_freep(&buffer);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
88 return AVERROR_INVALIDDATA;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
89 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
90 if (metadata_size != FLAC_STREAMINFO_SIZE) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
91 av_freep(&buffer);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
92 return AVERROR_INVALIDDATA;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
93 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
94 found_streaminfo = 1;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
95 st->codec->extradata = buffer;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
96 st->codec->extradata_size = metadata_size;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
97 buffer = NULL;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
98
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
99 /* get codec params from STREAMINFO header */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
100 ff_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
101
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
102 /* set time base and duration */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
103 if (si.samplerate > 0) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
104 av_set_pts_info(st, 64, 1, si.samplerate);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
105 if (si.samples > 0)
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
106 st->duration = si.samples;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
107 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
108 } else {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
109 /* STREAMINFO must be the first block */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
110 if (!found_streaminfo) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
111 av_freep(&buffer);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
112 return AVERROR_INVALIDDATA;
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
113 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
114 /* process supported blocks other than STREAMINFO */
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
115 if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
116 if (vorbis_comment(s, buffer, metadata_size)) {
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
117 av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
118 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
119 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
120 av_freep(&buffer);
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
121 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
122 }
478a7c56266a flacdec: Parse the metadata header in the raw FLAC demuxer.
jbr
parents: 4612
diff changeset
123
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
124 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
125 }
4548
2c9ebc4029ae add raw demuxer for Chinese AVS elementary streams
stefang
parents: 4510
diff changeset
126
2365
76827ffd1cf6 flac probe
michael
parents: 2313
diff changeset
127 static int flac_probe(AVProbeData *p)
76827ffd1cf6 flac probe
michael
parents: 2313
diff changeset
128 {
4285
d8803d0a4274 Handle ID3v2 tags in raw FLAC streams by skipping them.
jbr
parents: 4254
diff changeset
129 uint8_t *bufptr = p->buf;
4292
0e275ee37217 Check buffer is inside what is passed when probing for flac.
benoit
parents: 4285
diff changeset
130 uint8_t *end = p->buf + p->buf_size;
4285
d8803d0a4274 Handle ID3v2 tags in raw FLAC streams by skipping them.
jbr
parents: 4254
diff changeset
131
d8803d0a4274 Handle ID3v2 tags in raw FLAC streams by skipping them.
jbr
parents: 4254
diff changeset
132 if(ff_id3v2_match(bufptr))
d8803d0a4274 Handle ID3v2 tags in raw FLAC streams by skipping them.
jbr
parents: 4254
diff changeset
133 bufptr += ff_id3v2_tag_len(bufptr);
d8803d0a4274 Handle ID3v2 tags in raw FLAC streams by skipping them.
jbr
parents: 4254
diff changeset
134
4292
0e275ee37217 Check buffer is inside what is passed when probing for flac.
benoit
parents: 4285
diff changeset
135 if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0;
4293
491a0b1d4f62 Whitespace cosmetics to align return statements.
benoit
parents: 4292
diff changeset
136 else return AVPROBE_SCORE_MAX/2;
2365
76827ffd1cf6 flac probe
michael
parents: 2313
diff changeset
137 }
76827ffd1cf6 flac probe
michael
parents: 2313
diff changeset
138
3546
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
139 AVInputFormat flac_demuxer = {
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
140 "flac",
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
141 NULL_IF_CONFIG_SMALL("raw FLAC"),
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
142 0,
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
143 flac_probe,
4610
41542d2edcf4 Separate the raw FLAC demuxer from raw.c and put in a new file,
jbr
parents: 4577
diff changeset
144 flac_read_header,
41542d2edcf4 Separate the raw FLAC demuxer from raw.c and put in a new file,
jbr
parents: 4577
diff changeset
145 ff_raw_read_partial_packet,
1756
5d72afc6c8aa better generic index building and seeking code
michael
parents: 1463
diff changeset
146 .flags= AVFMT_GENERIC_INDEX,
3546
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
147 .extensions = "flac",
45c3d2b2b2fb Alphabetically order AVInputFormat/AVOutputFormat declarations.
diego
parents: 3545
diff changeset
148 .value = CODEC_ID_FLAC,
5032
3aabdadf9d5f Add a VorbisComment metadata conversion table and use it in the FLAC and
jbr
parents: 4760
diff changeset
149 .metadata_conv = ff_vorbiscomment_metadata_conv,
931
7420a756dc7a read/write adts aac
mru
parents: 930
diff changeset
150 };