FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/flacdec.c
Date: 2022-12-05 20:26:17
Exec Total Coverage
Lines: 123 184 66.8%
Functions: 6 6 100.0%
Branches: 64 120 53.3%

Line Branch Exec Source
1 /*
2 * Raw FLAC demuxer
3 * Copyright (c) 2001 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/channel_layout.h"
23 #include "libavcodec/avcodec.h"
24 #include "libavcodec/bytestream.h"
25 #include "libavcodec/flac.h"
26 #include "avformat.h"
27 #include "demux.h"
28 #include "flac_picture.h"
29 #include "internal.h"
30 #include "rawdec.h"
31 #include "oggdec.h"
32 #include "replaygain.h"
33
34 #define SEEKPOINT_SIZE 18
35
36 typedef struct FLACDecContext {
37 FFRawDemuxerContext rawctx;
38 int found_seektable;
39 } FLACDecContext;
40
41 31 static void reset_index_position(int64_t metadata_head_size, AVStream *st)
42 {
43 31 FFStream *const sti = ffstream(st);
44 /* the real seek index offset should be the size of metadata blocks with the offset in the frame blocks */
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 for (int i = 0; i < sti->nb_index_entries; i++)
46 sti->index_entries[i].pos += metadata_head_size;
47 31 }
48
49 31 static int flac_read_header(AVFormatContext *s)
50 {
51 31 int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
52 uint8_t header[4];
53 31 uint8_t *buffer=NULL;
54 31 FLACDecContext *flac = s->priv_data;
55 31 AVStream *st = avformat_new_stream(s, NULL);
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (!st)
57 return AVERROR(ENOMEM);
58 31 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
59 31 st->codecpar->codec_id = AV_CODEC_ID_FLAC;
60 31 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
61 /* the parameters will be extracted from the compressed bitstream */
62
63 /* if fLaC marker is not found, assume there is no header */
64
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
31 if (avio_rl32(s->pb) != MKTAG('f','L','a','C')) {
65 avio_seek(s->pb, -4, SEEK_CUR);
66 return 0;
67 }
68
69 /* process metadata blocks */
70
3/4
✓ Branch 1 taken 145 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
✓ Branch 4 taken 31 times.
145 while (!avio_feof(s->pb) && !metadata_last) {
71
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
114 if (avio_read(s->pb, header, 4) != 4)
72 return AVERROR(AVERROR_INVALIDDATA);
73 114 flac_parse_block_header(header, &metadata_last, &metadata_type,
74 &metadata_size);
75
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 31 times.
114 switch (metadata_type) {
76 /* allocate and read metadata block for supported types */
77 83 case FLAC_METADATA_TYPE_STREAMINFO:
78 case FLAC_METADATA_TYPE_CUESHEET:
79 case FLAC_METADATA_TYPE_PICTURE:
80 case FLAC_METADATA_TYPE_VORBIS_COMMENT:
81 case FLAC_METADATA_TYPE_SEEKTABLE:
82 83 buffer = av_mallocz(metadata_size + AV_INPUT_BUFFER_PADDING_SIZE);
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 if (!buffer) {
84 return AVERROR(ENOMEM);
85 }
86
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 83 times.
83 if (avio_read(s->pb, buffer, metadata_size) != metadata_size) {
87 RETURN_ERROR(AVERROR(EIO));
88 }
89 83 break;
90 /* skip metadata block for unsupported types */
91 31 default:
92 31 ret = avio_skip(s->pb, metadata_size);
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
94 return ret;
95 }
96
97
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 83 times.
114 if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
98 uint32_t samplerate;
99 uint64_t samples;
100
101 /* STREAMINFO can only occur once */
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (found_streaminfo) {
103 RETURN_ERROR(AVERROR_INVALIDDATA);
104 }
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (metadata_size != FLAC_STREAMINFO_SIZE) {
106 RETURN_ERROR(AVERROR_INVALIDDATA);
107 }
108 31 found_streaminfo = 1;
109 31 st->codecpar->extradata = buffer;
110 31 st->codecpar->extradata_size = metadata_size;
111 31 buffer = NULL;
112
113 /* get sample rate and sample count from STREAMINFO header;
114 * other parameters will be extracted by the parser */
115 31 samplerate = AV_RB24(st->codecpar->extradata + 10) >> 4;
116 31 samples = (AV_RB64(st->codecpar->extradata + 13) >> 24) & ((1ULL << 36) - 1);
117
118 /* set time base and duration */
119
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (samplerate > 0) {
120 31 avpriv_set_pts_info(st, 64, 1, samplerate);
121
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (samples > 0)
122 31 st->duration = samples;
123 }
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {
125 uint8_t isrc[13];
126 uint64_t start;
127 const uint8_t *offset;
128 int i, chapters, track, ti;
129 if (metadata_size < 431)
130 RETURN_ERROR(AVERROR_INVALIDDATA);
131 offset = buffer + 395;
132 chapters = bytestream_get_byte(&offset) - 1;
133 if (chapters <= 0)
134 RETURN_ERROR(AVERROR_INVALIDDATA);
135 for (i = 0; i < chapters; i++) {
136 if (offset + 36 - buffer > metadata_size)
137 RETURN_ERROR(AVERROR_INVALIDDATA);
138 start = bytestream_get_be64(&offset);
139 track = bytestream_get_byte(&offset);
140 bytestream_get_buffer(&offset, isrc, 12);
141 isrc[12] = 0;
142 offset += 14;
143 ti = bytestream_get_byte(&offset);
144 if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA);
145 offset += ti * 12;
146 avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
147 }
148 av_freep(&buffer);
149
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 70 times.
83 } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
150 13 ret = ff_flac_parse_picture(s, &buffer, metadata_size, 1);
151 13 av_freep(&buffer);
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (ret < 0) {
153 av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
154 return ret;
155 }
156
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 61 times.
70 } else if (metadata_type == FLAC_METADATA_TYPE_SEEKTABLE) {
157 9 const uint8_t *seekpoint = buffer;
158 9 int i, seek_point_count = metadata_size/SEEKPOINT_SIZE;
159 9 flac->found_seektable = 1;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if ((s->flags&AVFMT_FLAG_FAST_SEEK)) {
161 for(i=0; i<seek_point_count; i++) {
162 int64_t timestamp = bytestream_get_be64(&seekpoint);
163 int64_t pos = bytestream_get_be64(&seekpoint);
164 /* skip number of samples */
165 bytestream_get_be16(&seekpoint);
166 av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
167 }
168 }
169 9 av_freep(&buffer);
170 }
171 else {
172
173 /* STREAMINFO must be the first block */
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (!found_streaminfo) {
175 RETURN_ERROR(AVERROR_INVALIDDATA);
176 }
177 /* process supported blocks other than STREAMINFO */
178
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 31 times.
61 if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
179 AVDictionaryEntry *chmask;
180
181 30 ret = ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1);
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (ret < 0) {
183 av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
184
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 12 times.
30 } else if (ret > 0) {
185 18 s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
186 }
187
188 /* parse the channels mask if present */
189 30 chmask = av_dict_get(s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
190
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 28 times.
30 if (chmask) {
191 2 uint64_t mask = strtol(chmask->value, NULL, 0);
192
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (!mask || mask & ~0x3ffffULL) {
193 av_log(s, AV_LOG_WARNING,
194 "Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
195 } else {
196 2 av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
197 2 av_dict_set(&s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
198 }
199 }
200 }
201 61 av_freep(&buffer);
202 }
203 }
204
205 31 ret = ff_replaygain_export(st, s->metadata);
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
207 return ret;
208
209 31 reset_index_position(avio_tell(s->pb), st);
210 31 return 0;
211
212 fail:
213 av_free(buffer);
214 return ret;
215 }
216
217 16 static int raw_flac_probe(const AVProbeData *p)
218 {
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ((p->buf[2] & 0xF0) == 0) // blocksize code invalid
220 return 0;
221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ((p->buf[2] & 0x0F) == 0x0F) // sample rate code invalid
222 return 0;
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ((p->buf[3] & 0xF0) >= FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE << 4)
224 // channel mode invalid
225 return 0;
226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ((p->buf[3] & 0x06) == 0x06) // bits per sample code invalid
227 return 0;
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ((p->buf[3] & 0x01) == 0x01) // reserved bit set
229 return 0;
230 16 return AVPROBE_SCORE_EXTENSION / 4 + 1;
231 }
232
233 6782 static int flac_probe(const AVProbeData *p)
234 {
235
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6766 times.
6782 if ((AV_RB16(p->buf) & 0xFFFE) == 0xFFF8)
236 16 return raw_flac_probe(p);
237
238 /* file header + metadata header + checked bytes of streaminfo */
239
1/2
✓ Branch 0 taken 6766 times.
✗ Branch 1 not taken.
6766 if (p->buf_size >= 4 + 4 + 13) {
240 6766 int type = p->buf[4] & 0x7f;
241 6766 int size = AV_RB24(p->buf + 5);
242 6766 int min_block_size = AV_RB16(p->buf + 8);
243 6766 int max_block_size = AV_RB16(p->buf + 10);
244 6766 int sample_rate = AV_RB24(p->buf + 18) >> 4;
245
246
2/2
✓ Branch 0 taken 6737 times.
✓ Branch 1 taken 29 times.
6766 if (memcmp(p->buf, "fLaC", 4))
247 6737 return 0;
248
2/4
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
29 if (type == FLAC_METADATA_TYPE_STREAMINFO &&
249
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 size == FLAC_STREAMINFO_SIZE &&
250
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 min_block_size >= 16 &&
251
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 max_block_size >= min_block_size &&
252
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 sample_rate && sample_rate <= 655350)
253 29 return AVPROBE_SCORE_MAX;
254 return AVPROBE_SCORE_EXTENSION;
255 }
256
257 return 0;
258 }
259
260 120 static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_index,
261 int64_t *ppos, int64_t pos_limit)
262 {
263 120 FFFormatContext *const si = ffformatcontext(s);
264 120 AVPacket *const pkt = si->parse_pkt;
265 120 AVStream *st = s->streams[stream_index];
266 AVCodecParserContext *parser;
267 int ret;
268 120 int64_t pts = AV_NOPTS_VALUE;
269
270
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
120 if (avio_seek(s->pb, *ppos, SEEK_SET) < 0)
271 return AV_NOPTS_VALUE;
272
273 120 parser = av_parser_init(st->codecpar->codec_id);
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
120 if (!parser){
275 return AV_NOPTS_VALUE;
276 }
277 120 parser->flags |= PARSER_FLAG_USE_CODEC_TS;
278
279 1534 for (;;){
280 uint8_t *data;
281 int size;
282
283 1654 ret = ff_raw_read_partial_packet(s, pkt);
284
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1618 times.
1654 if (ret < 0){
285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (ret == AVERROR(EAGAIN))
286 continue;
287 else {
288 36 av_packet_unref(pkt);
289 av_assert1(!pkt->size);
290 }
291 }
292 1654 av_parser_parse2(parser, ffstream(st)->avctx,
293 1654 &data, &size, pkt->data, pkt->size,
294 pkt->pts, pkt->dts, *ppos);
295
296 1654 av_packet_unref(pkt);
297
2/2
✓ Branch 0 taken 229 times.
✓ Branch 1 taken 1425 times.
1654 if (size) {
298
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 118 times.
229 if (parser->pts != AV_NOPTS_VALUE){
299 // seeking may not have started from beginning of a frame
300 // calculate frame start position from next frame backwards
301 111 *ppos = parser->next_frame_offset - size;
302 111 pts = parser->pts;
303 111 break;
304 }
305
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1416 times.
1425 } else if (ret < 0)
306 9 break;
307 }
308 120 av_parser_close(parser);
309 120 return pts;
310 }
311
312 26 static int flac_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
313 26 AVStream *const st = s->streams[0];
314 26 FFStream *const sti = ffstream(st);
315 int index;
316 int64_t pos;
317 AVIndexEntry e;
318 26 FLACDecContext *flac = s->priv_data;
319
320
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
26 if (!flac->found_seektable || !(s->flags&AVFMT_FLAG_FAST_SEEK)) {
321 26 return -1;
322 }
323
324 index = av_index_search_timestamp(st, timestamp, flags);
325 if (index < 0 || index >= sti->nb_index_entries)
326 return -1;
327
328 e = sti->index_entries[index];
329 pos = avio_seek(s->pb, e.pos, SEEK_SET);
330 if (pos >= 0) {
331 return 0;
332 }
333 return -1;
334 }
335
336 const AVInputFormat ff_flac_demuxer = {
337 .name = "flac",
338 .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
339 .read_probe = flac_probe,
340 .read_header = flac_read_header,
341 .read_packet = ff_raw_read_partial_packet,
342 .read_seek = flac_seek,
343 .read_timestamp = flac_read_timestamp,
344 .flags = AVFMT_GENERIC_INDEX,
345 .extensions = "flac",
346 .raw_codec_id = AV_CODEC_ID_FLAC,
347 .priv_data_size = sizeof(FLACDecContext),
348 .priv_class = &ff_raw_demuxer_class,
349 };
350