Coverage Report

Created: 2026-09-14 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/flacdec.c
Line
Count
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 "libavutil/mem.h"
24
#include "libavcodec/avcodec.h"
25
#include "libavcodec/bytestream.h"
26
#include "libavcodec/flac.h"
27
#include "avformat.h"
28
#include "avio_internal.h"
29
#include "demux.h"
30
#include "flac_picture.h"
31
#include "internal.h"
32
#include "rawdec.h"
33
#include "oggdec.h"
34
#include "replaygain.h"
35
36
6.51k
#define SEEKPOINT_SIZE 18
37
38
typedef struct FLACDecContext {
39
    FFRawDemuxerContext rawctx;
40
    int found_seektable;
41
42
    AVCodecContext *parser_dec;
43
} FLACDecContext;
44
45
static void reset_index_position(int64_t metadata_head_size, AVStream *st)
46
1.71k
{
47
1.71k
    FFStream *const sti = ffstream(st);
48
    /* the real seek index offset should be the size of metadata blocks with the offset in the frame blocks */
49
1.71k
    for (int i = 0; i < sti->nb_index_entries; i++)
50
0
        sti->index_entries[i].pos += metadata_head_size;
51
1.71k
}
52
53
static const uint16_t sr_table[16] = {
54
    0, 1764, 3528, 3840, 160, 320, 441, 480, 640, 882, 960, 1920, 0, 0, 0, 0
55
};
56
57
static int flac_read_header(AVFormatContext *s)
58
9.68k
{
59
9.68k
    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
60
9.68k
    uint8_t header[4];
61
9.68k
    uint8_t *buffer=NULL;
62
9.68k
    uint32_t marker;
63
9.68k
    FLACDecContext *flac = s->priv_data;
64
9.68k
    AVStream *st = avformat_new_stream(s, NULL);
65
9.68k
    if (!st)
66
0
        return AVERROR(ENOMEM);
67
9.68k
    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
68
9.68k
    st->codecpar->codec_id = AV_CODEC_ID_FLAC;
69
9.68k
    ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
70
    /* the parameters will be extracted from the compressed bitstream */
71
72
    /* if fLaC marker is not found, assume there is no header */
73
9.68k
    marker = avio_rl32(s->pb);
74
9.68k
    if (marker != MKTAG('f','L','a','C')) {
75
7.01k
        const int sample_rate = 50 * sr_table[(marker >> 16) & 0xF];
76
7.01k
        if (sample_rate)
77
1.44k
            avpriv_set_pts_info(st, 64, 1, sample_rate);
78
7.01k
        avio_seek(s->pb, -4, SEEK_CUR);
79
7.01k
        return 0;
80
7.01k
    }
81
82
    /* process metadata blocks */
83
53.5k
    while (!avio_feof(s->pb) && !metadata_last) {
84
51.8k
        ret = avio_read(s->pb, header, 4);
85
51.8k
        if (ret < 0) {
86
436
            return ret;
87
51.4k
        } else if (ret != 4) {
88
96
            return AVERROR_EOF;
89
96
        }
90
91
51.3k
        flac_parse_block_header(header, &metadata_last, &metadata_type,
92
51.3k
                                   &metadata_size);
93
51.3k
        switch (metadata_type) {
94
        /* allocate and read metadata block for supported types */
95
1.87k
        case FLAC_METADATA_TYPE_STREAMINFO:
96
2.33k
        case FLAC_METADATA_TYPE_CUESHEET:
97
23.5k
        case FLAC_METADATA_TYPE_PICTURE:
98
43.2k
        case FLAC_METADATA_TYPE_VORBIS_COMMENT:
99
49.8k
        case FLAC_METADATA_TYPE_SEEKTABLE:
100
49.8k
            buffer = av_mallocz(metadata_size + AV_INPUT_BUFFER_PADDING_SIZE);
101
49.8k
            if (!buffer) {
102
0
                return AVERROR(ENOMEM);
103
0
            }
104
49.8k
            ret = ffio_read_size(s->pb, buffer, metadata_size);
105
49.8k
            if (ret < 0)
106
166
                goto fail;
107
108
49.6k
            break;
109
        /* skip metadata block for unsupported types */
110
49.6k
        default:
111
1.50k
            ret = avio_skip(s->pb, metadata_size);
112
1.50k
            if (ret < 0)
113
141
                return ret;
114
51.3k
        }
115
116
51.0k
        if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
117
1.80k
            uint32_t samplerate;
118
1.80k
            uint64_t samples;
119
120
            /* STREAMINFO can only occur once */
121
1.80k
            if (found_streaminfo) {
122
20
                RETURN_ERROR(AVERROR_INVALIDDATA);
123
20
            }
124
1.78k
            if (metadata_size != FLAC_STREAMINFO_SIZE) {
125
13
                RETURN_ERROR(AVERROR_INVALIDDATA);
126
13
            }
127
1.76k
            found_streaminfo = 1;
128
1.76k
            st->codecpar->extradata      = buffer;
129
1.76k
            st->codecpar->extradata_size = metadata_size;
130
1.76k
            buffer = NULL;
131
132
            /* get sample rate and sample count from STREAMINFO header;
133
             * other parameters will be extracted by the parser */
134
1.76k
            samplerate = AV_RB24(st->codecpar->extradata + 10) >> 4;
135
1.76k
            samples    = (AV_RB64(st->codecpar->extradata + 13) >> 24) & ((1ULL << 36) - 1);
136
137
            /* set time base and duration */
138
1.76k
            if (samplerate > 0) {
139
1.68k
                avpriv_set_pts_info(st, 64, 1, samplerate);
140
1.68k
                if (samples > 0)
141
1.63k
                    st->duration = samples;
142
1.68k
            }
143
49.2k
        } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {
144
453
            uint8_t isrc[13];
145
453
            uint64_t start;
146
453
            const uint8_t *offset;
147
453
            int i, chapters, track, ti;
148
453
            if (metadata_size < 431)
149
5
                RETURN_ERROR(AVERROR_INVALIDDATA);
150
448
            offset = buffer + 395;
151
448
            chapters = bytestream_get_byte(&offset) - 1;
152
448
            if (chapters <= 0)
153
3
                RETURN_ERROR(AVERROR_INVALIDDATA);
154
3.02k
            for (i = 0; i < chapters; i++) {
155
2.61k
                if (offset + 36 - buffer > metadata_size)
156
34
                    RETURN_ERROR(AVERROR_INVALIDDATA);
157
2.58k
                start = bytestream_get_be64(&offset);
158
2.58k
                track = bytestream_get_byte(&offset);
159
2.58k
                bytestream_get_buffer(&offset, isrc, 12);
160
2.58k
                isrc[12] = 0;
161
2.58k
                offset += 14;
162
2.58k
                ti = bytestream_get_byte(&offset);
163
2.58k
                if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA);
164
2.57k
                offset += ti * 12;
165
2.57k
                avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
166
2.57k
            }
167
403
            av_freep(&buffer);
168
48.7k
        } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
169
21.1k
            ret = ff_flac_parse_picture(s, &buffer, metadata_size, 1);
170
21.1k
            av_freep(&buffer);
171
21.1k
            if (ret < 0) {
172
13
                av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
173
13
                return ret;
174
13
            }
175
27.5k
        } else if (metadata_type == FLAC_METADATA_TYPE_SEEKTABLE) {
176
6.51k
            const uint8_t *seekpoint = buffer;
177
6.51k
            int i, seek_point_count = metadata_size/SEEKPOINT_SIZE;
178
6.51k
            flac->found_seektable = 1;
179
6.51k
            if ((s->flags&AVFMT_FLAG_FAST_SEEK)) {
180
0
                for(i=0; i<seek_point_count; i++) {
181
0
                    int64_t timestamp = bytestream_get_be64(&seekpoint);
182
0
                    int64_t pos = bytestream_get_be64(&seekpoint);
183
                    /* skip number of samples */
184
0
                    bytestream_get_be16(&seekpoint);
185
0
                    av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
186
0
                }
187
0
            }
188
6.51k
            av_freep(&buffer);
189
6.51k
        }
190
21.0k
        else {
191
192
            /* STREAMINFO must be the first block */
193
21.0k
            if (!found_streaminfo) {
194
18
                RETURN_ERROR(AVERROR_INVALIDDATA);
195
18
            }
196
            /* process supported blocks other than STREAMINFO */
197
21.0k
            if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
198
19.7k
                AVDictionaryEntry *chmask;
199
200
19.7k
                ret = ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1);
201
19.7k
                if (ret < 0) {
202
9.38k
                    av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
203
10.3k
                } else if (ret > 0) {
204
3.06k
                    s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
205
3.06k
                }
206
207
                /* parse the channels mask if present */
208
19.7k
                chmask = av_dict_get(s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
209
19.7k
                if (chmask) {
210
0
                    uint64_t mask = strtol(chmask->value, NULL, 0);
211
0
                    if (!mask || mask & ~0x3ffffULL) {
212
0
                        av_log(s, AV_LOG_WARNING,
213
0
                               "Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
214
0
                    } else {
215
0
                        av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
216
0
                        av_dict_set(&s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
217
0
                    }
218
0
                }
219
19.7k
            }
220
21.0k
            av_freep(&buffer);
221
21.0k
        }
222
51.0k
    }
223
224
1.71k
    ret = ff_replaygain_export(st, s->metadata);
225
1.71k
    if (ret < 0)
226
0
        return ret;
227
228
1.71k
    reset_index_position(avio_tell(s->pb), st);
229
1.71k
    return 0;
230
231
267
fail:
232
267
    av_free(buffer);
233
267
    return ret;
234
1.71k
}
235
236
static int raw_flac_probe(const AVProbeData *p)
237
4.42k
{
238
4.42k
    if ((p->buf[2] & 0xF0) == 0)    // blocksize code invalid
239
821
        return 0;
240
3.60k
    if ((p->buf[2] & 0x0F) == 0x0F) // sample rate code invalid
241
881
        return 0;
242
2.72k
    if ((p->buf[3] & 0xF0) >= FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE << 4)
243
        // channel mode invalid
244
327
        return 0;
245
2.39k
    if ((p->buf[3] & 0x06) == 0x06) // bits per sample code invalid
246
307
        return 0;
247
2.08k
    if ((p->buf[3] & 0x01) == 0x01) // reserved bit set
248
309
        return 0;
249
1.78k
    return AVPROBE_SCORE_EXTENSION / 4 + 1;
250
2.08k
}
251
252
static int flac_probe(const AVProbeData *p)
253
964k
{
254
964k
    if ((AV_RB16(p->buf) & 0xFFFE) == 0xFFF8)
255
4.42k
        return raw_flac_probe(p);
256
257
    /* file header + metadata header + checked bytes of streaminfo */
258
960k
    if (p->buf_size >= 4 + 4 + 13) {
259
788k
        int type           = p->buf[4] & 0x7f;
260
788k
        int size           = AV_RB24(p->buf + 5);
261
788k
        int min_block_size = AV_RB16(p->buf + 8);
262
788k
        int max_block_size = AV_RB16(p->buf + 10);
263
788k
        int sample_rate    = AV_RB24(p->buf + 18) >> 4;
264
265
788k
        if (memcmp(p->buf, "fLaC", 4))
266
786k
            return 0;
267
1.81k
        if (type == FLAC_METADATA_TYPE_STREAMINFO &&
268
1.36k
            size == FLAC_STREAMINFO_SIZE          &&
269
1.19k
            min_block_size >= 16                  &&
270
997
            max_block_size >= min_block_size      &&
271
639
            sample_rate && sample_rate <= 655350)
272
311
            return AVPROBE_SCORE_MAX;
273
1.50k
        return AVPROBE_SCORE_EXTENSION;
274
1.81k
    }
275
276
171k
    return 0;
277
960k
}
278
279
av_unused static int64_t flac_read_timestamp(AVFormatContext *s, int stream_index,
280
                                             int64_t *ppos, int64_t pos_limit)
281
0
{
282
0
    FLACDecContext *flac = s->priv_data;
283
0
    FFFormatContext *const si = ffformatcontext(s);
284
0
    AVPacket *const pkt = si->parse_pkt;
285
0
    AVStream *st = s->streams[stream_index];
286
0
    AVCodecParserContext *parser;
287
0
    int ret;
288
0
    int64_t pts = AV_NOPTS_VALUE;
289
290
0
    if (avio_seek(s->pb, *ppos, SEEK_SET) < 0)
291
0
        return AV_NOPTS_VALUE;
292
293
0
    if (!flac->parser_dec) {
294
0
        flac->parser_dec = avcodec_alloc_context3(NULL);
295
0
        if (!flac->parser_dec)
296
0
            return AV_NOPTS_VALUE;
297
298
0
        ret = avcodec_parameters_to_context(flac->parser_dec, st->codecpar);
299
0
        if (ret < 0)
300
0
            return ret;
301
0
    }
302
303
0
    parser = av_parser_init(st->codecpar->codec_id);
304
0
    if (!parser)
305
0
        return AV_NOPTS_VALUE;
306
0
    parser->flags |= PARSER_FLAG_USE_CODEC_TS;
307
308
0
    for (;;){
309
0
        uint8_t *data;
310
0
        int size;
311
312
0
        ret = ff_raw_read_partial_packet(s, pkt);
313
0
        if (ret < 0){
314
0
            if (ret == AVERROR(EAGAIN))
315
0
                continue;
316
0
            else {
317
0
                av_packet_unref(pkt);
318
0
                av_assert1(!pkt->size);
319
0
            }
320
0
        }
321
0
        av_parser_parse2(parser, flac->parser_dec,
322
0
                         &data, &size, pkt->data, pkt->size,
323
0
                         pkt->pts, pkt->dts, *ppos);
324
325
0
        av_packet_unref(pkt);
326
0
        if (size) {
327
0
            if (parser->pts != AV_NOPTS_VALUE){
328
                // seeking may not have started from beginning of a frame
329
                // calculate frame start position from next frame backwards
330
0
                *ppos = parser->next_frame_offset - size;
331
0
                pts = parser->pts;
332
0
                break;
333
0
            }
334
0
        } else if (ret < 0)
335
0
            break;
336
0
    }
337
0
    av_parser_close(parser);
338
0
    return pts;
339
0
}
340
341
static int flac_close(AVFormatContext *s)
342
8.73k
{
343
8.73k
    FLACDecContext *flac = s->priv_data;
344
345
8.73k
    avcodec_free_context(&flac->parser_dec);
346
347
8.73k
    return 0;
348
8.73k
}
349
350
0
static int flac_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
351
0
    AVStream *const st  = s->streams[0];
352
0
    FFStream *const sti = ffstream(st);
353
0
    int index;
354
0
    int64_t pos;
355
0
    AVIndexEntry e;
356
0
    FLACDecContext *flac = s->priv_data;
357
358
0
    if (!flac->found_seektable || !(s->flags&AVFMT_FLAG_FAST_SEEK)) {
359
0
        return -1;
360
0
    }
361
362
0
    index = av_index_search_timestamp(st, timestamp, flags);
363
0
    if (index < 0 || index >= sti->nb_index_entries)
364
0
        return -1;
365
366
0
    e   = sti->index_entries[index];
367
0
    pos = avio_seek(s->pb, e.pos, SEEK_SET);
368
0
    if (pos >= 0) {
369
0
        return 0;
370
0
    }
371
0
    return -1;
372
0
}
373
374
const FFInputFormat ff_flac_demuxer = {
375
    .p.name         = "flac",
376
    .p.long_name    = NULL_IF_CONFIG_SMALL("raw FLAC"),
377
    .p.flags        = AVFMT_GENERIC_INDEX,
378
    .p.extensions   = "flac",
379
    .p.priv_class   = &ff_raw_demuxer_class,
380
    .read_probe     = flac_probe,
381
    .read_header    = flac_read_header,
382
    .read_close     = flac_close,
383
    .read_packet    = ff_raw_read_partial_packet,
384
    .read_seek      = flac_seek,
385
    .read_timestamp = flac_read_timestamp,
386
    .raw_codec_id   = AV_CODEC_ID_FLAC,
387
    .priv_data_size = sizeof(FLACDecContext),
388
    .flags_internal = FF_INFMT_FLAG_ID3V2_AUTO,
389
};