Coverage Report

Created: 2026-01-16 07:48

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
7.57k
#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.92k
{
47
1.92k
    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.92k
    for (int i = 0; i < sti->nb_index_entries; i++)
50
0
        sti->index_entries[i].pos += metadata_head_size;
51
1.92k
}
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
10.1k
{
59
10.1k
    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
60
10.1k
    uint8_t header[4];
61
10.1k
    uint8_t *buffer=NULL;
62
10.1k
    uint32_t marker;
63
10.1k
    FLACDecContext *flac = s->priv_data;
64
10.1k
    AVStream *st = avformat_new_stream(s, NULL);
65
10.1k
    if (!st)
66
0
        return AVERROR(ENOMEM);
67
10.1k
    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
68
10.1k
    st->codecpar->codec_id = AV_CODEC_ID_FLAC;
69
10.1k
    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
10.1k
    marker = avio_rl32(s->pb);
74
10.1k
    if (marker != MKTAG('f','L','a','C')) {
75
7.18k
        const int sample_rate = 50 * sr_table[(marker >> 16) & 0xF];
76
7.18k
        if (sample_rate)
77
1.48k
            avpriv_set_pts_info(st, 64, 1, sample_rate);
78
7.18k
        avio_seek(s->pb, -4, SEEK_CUR);
79
7.18k
        return 0;
80
7.18k
    }
81
82
    /* process metadata blocks */
83
67.6k
    while (!avio_feof(s->pb) && !metadata_last) {
84
65.7k
        ret = avio_read(s->pb, header, 4);
85
65.7k
        if (ret < 0) {
86
489
            return ret;
87
65.2k
        } else if (ret != 4) {
88
101
            return AVERROR_EOF;
89
101
        }
90
91
65.1k
        flac_parse_block_header(header, &metadata_last, &metadata_type,
92
65.1k
                                   &metadata_size);
93
65.1k
        switch (metadata_type) {
94
        /* allocate and read metadata block for supported types */
95
2.07k
        case FLAC_METADATA_TYPE_STREAMINFO:
96
2.65k
        case FLAC_METADATA_TYPE_CUESHEET:
97
26.6k
        case FLAC_METADATA_TYPE_PICTURE:
98
47.3k
        case FLAC_METADATA_TYPE_VORBIS_COMMENT:
99
54.9k
        case FLAC_METADATA_TYPE_SEEKTABLE:
100
54.9k
            buffer = av_mallocz(metadata_size + AV_INPUT_BUFFER_PADDING_SIZE);
101
54.9k
            if (!buffer) {
102
0
                return AVERROR(ENOMEM);
103
0
            }
104
54.9k
            ret = ffio_read_size(s->pb, buffer, metadata_size);
105
54.9k
            if (ret < 0)
106
176
                goto fail;
107
108
54.8k
            break;
109
        /* skip metadata block for unsupported types */
110
54.8k
        default:
111
10.1k
            ret = avio_skip(s->pb, metadata_size);
112
10.1k
            if (ret < 0)
113
133
                return ret;
114
65.1k
        }
115
116
64.8k
        if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
117
1.98k
            uint32_t samplerate;
118
1.98k
            uint64_t samples;
119
120
            /* STREAMINFO can only occur once */
121
1.98k
            if (found_streaminfo) {
122
21
                RETURN_ERROR(AVERROR_INVALIDDATA);
123
21
            }
124
1.95k
            if (metadata_size != FLAC_STREAMINFO_SIZE) {
125
22
                RETURN_ERROR(AVERROR_INVALIDDATA);
126
22
            }
127
1.93k
            found_streaminfo = 1;
128
1.93k
            st->codecpar->extradata      = buffer;
129
1.93k
            st->codecpar->extradata_size = metadata_size;
130
1.93k
            buffer = NULL;
131
132
            /* get sample rate and sample count from STREAMINFO header;
133
             * other parameters will be extracted by the parser */
134
1.93k
            samplerate = AV_RB24(st->codecpar->extradata + 10) >> 4;
135
1.93k
            samples    = (AV_RB64(st->codecpar->extradata + 13) >> 24) & ((1ULL << 36) - 1);
136
137
            /* set time base and duration */
138
1.93k
            if (samplerate > 0) {
139
1.86k
                avpriv_set_pts_info(st, 64, 1, samplerate);
140
1.86k
                if (samples > 0)
141
1.81k
                    st->duration = samples;
142
1.86k
            }
143
62.8k
        } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {
144
573
            uint8_t isrc[13];
145
573
            uint64_t start;
146
573
            const uint8_t *offset;
147
573
            int i, chapters, track, ti;
148
573
            if (metadata_size < 431)
149
14
                RETURN_ERROR(AVERROR_INVALIDDATA);
150
559
            offset = buffer + 395;
151
559
            chapters = bytestream_get_byte(&offset) - 1;
152
559
            if (chapters <= 0)
153
2
                RETURN_ERROR(AVERROR_INVALIDDATA);
154
3.58k
            for (i = 0; i < chapters; i++) {
155
3.06k
                if (offset + 36 - buffer > metadata_size)
156
28
                    RETURN_ERROR(AVERROR_INVALIDDATA);
157
3.04k
                start = bytestream_get_be64(&offset);
158
3.04k
                track = bytestream_get_byte(&offset);
159
3.04k
                bytestream_get_buffer(&offset, isrc, 12);
160
3.04k
                isrc[12] = 0;
161
3.04k
                offset += 14;
162
3.04k
                ti = bytestream_get_byte(&offset);
163
3.04k
                if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA);
164
3.03k
                offset += ti * 12;
165
3.03k
                avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
166
3.03k
            }
167
520
            av_freep(&buffer);
168
62.2k
        } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
169
23.9k
            ret = ff_flac_parse_picture(s, &buffer, metadata_size, 1);
170
23.9k
            av_freep(&buffer);
171
23.9k
            if (ret < 0) {
172
14
                av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
173
14
                return ret;
174
14
            }
175
38.3k
        } else if (metadata_type == FLAC_METADATA_TYPE_SEEKTABLE) {
176
7.57k
            const uint8_t *seekpoint = buffer;
177
7.57k
            int i, seek_point_count = metadata_size/SEEKPOINT_SIZE;
178
7.57k
            flac->found_seektable = 1;
179
7.57k
            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
7.57k
            av_freep(&buffer);
189
7.57k
        }
190
30.8k
        else {
191
192
            /* STREAMINFO must be the first block */
193
30.8k
            if (!found_streaminfo) {
194
23
                RETURN_ERROR(AVERROR_INVALIDDATA);
195
23
            }
196
            /* process supported blocks other than STREAMINFO */
197
30.7k
            if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
198
20.7k
                AVDictionaryEntry *chmask;
199
200
20.7k
                ret = ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1);
201
20.7k
                if (ret < 0) {
202
10.4k
                    av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
203
10.4k
                } else if (ret > 0) {
204
3.15k
                    s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
205
3.15k
                }
206
207
                /* parse the channels mask if present */
208
20.7k
                chmask = av_dict_get(s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
209
20.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
20.7k
            }
220
30.7k
            av_freep(&buffer);
221
30.7k
        }
222
64.8k
    }
223
224
1.92k
    ret = ff_replaygain_export(st, s->metadata);
225
1.92k
    if (ret < 0)
226
0
        return ret;
227
228
1.92k
    reset_index_position(avio_tell(s->pb), st);
229
1.92k
    return 0;
230
231
295
fail:
232
295
    av_free(buffer);
233
295
    return ret;
234
1.92k
}
235
236
static int raw_flac_probe(const AVProbeData *p)
237
4.67k
{
238
4.67k
    if ((p->buf[2] & 0xF0) == 0)    // blocksize code invalid
239
818
        return 0;
240
3.86k
    if ((p->buf[2] & 0x0F) == 0x0F) // sample rate code invalid
241
899
        return 0;
242
2.96k
    if ((p->buf[3] & 0xF0) >= FLAC_MAX_CHANNELS + FLAC_CHMODE_MID_SIDE << 4)
243
        // channel mode invalid
244
319
        return 0;
245
2.64k
    if ((p->buf[3] & 0x06) == 0x06) // bits per sample code invalid
246
341
        return 0;
247
2.30k
    if ((p->buf[3] & 0x01) == 0x01) // reserved bit set
248
321
        return 0;
249
1.98k
    return AVPROBE_SCORE_EXTENSION / 4 + 1;
250
2.30k
}
251
252
static int flac_probe(const AVProbeData *p)
253
958k
{
254
958k
    if ((AV_RB16(p->buf) & 0xFFFE) == 0xFFF8)
255
4.67k
        return raw_flac_probe(p);
256
257
    /* file header + metadata header + checked bytes of streaminfo */
258
953k
    if (p->buf_size >= 4 + 4 + 13) {
259
773k
        int type           = p->buf[4] & 0x7f;
260
773k
        int size           = AV_RB24(p->buf + 5);
261
773k
        int min_block_size = AV_RB16(p->buf + 8);
262
773k
        int max_block_size = AV_RB16(p->buf + 10);
263
773k
        int sample_rate    = AV_RB24(p->buf + 18) >> 4;
264
265
773k
        if (memcmp(p->buf, "fLaC", 4))
266
771k
            return 0;
267
1.77k
        if (type == FLAC_METADATA_TYPE_STREAMINFO &&
268
1.38k
            size == FLAC_STREAMINFO_SIZE          &&
269
1.19k
            min_block_size >= 16                  &&
270
1.03k
            max_block_size >= min_block_size      &&
271
660
            sample_rate && sample_rate <= 655350)
272
315
            return AVPROBE_SCORE_MAX;
273
1.46k
        return AVPROBE_SCORE_EXTENSION;
274
1.77k
    }
275
276
180k
    return 0;
277
953k
}
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
9.10k
{
343
9.10k
    FLACDecContext *flac = s->priv_data;
344
345
9.10k
    avcodec_free_context(&flac->parser_dec);
346
347
9.10k
    return 0;
348
9.10k
}
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
};