Coverage Report

Created: 2026-08-25 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/demux_utils.c
Line
Count
Source
1
/*
2
 * Various utility demuxing functions
3
 * Copyright (c) 2000, 2001, 2002 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 <inttypes.h>
23
24
#include "libavutil/mem.h"
25
26
#include "libavutil/avassert.h"
27
#include "libavutil/avstring.h"
28
#include "libavcodec/bytestream.h"
29
#include "packet_internal.h"
30
#include "avformat.h"
31
#include "avformat_internal.h"
32
#include "avio_internal.h"
33
#include "demux.h"
34
#include "internal.h"
35
36
struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
37
0
{
38
0
    return cffstream(st)->parser;
39
0
}
40
41
void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type)
42
0
{
43
0
    ffstream(st)->need_parsing = type;
44
0
}
45
46
AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base,
47
                              int64_t start, int64_t end, const char *title)
48
0
{
49
0
    FormatContextInternal *const fci = ff_fc_internal(s);
50
0
    AVChapter *chapter = NULL;
51
0
    int ret;
52
53
0
    if (end != AV_NOPTS_VALUE && start > end) {
54
0
        av_log(s, AV_LOG_ERROR, "Chapter end time %"PRId64" before start %"PRId64"\n", end, start);
55
0
        return NULL;
56
0
    }
57
58
0
    if (!s->nb_chapters) {
59
0
        fci->chapter_ids_monotonic = 1;
60
0
    } else if (!fci->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) {
61
0
        for (unsigned i = 0; i < s->nb_chapters; i++)
62
0
            if (s->chapters[i]->id == id)
63
0
                chapter = s->chapters[i];
64
0
        if (!chapter)
65
0
            fci->chapter_ids_monotonic = 0;
66
0
    }
67
68
0
    if (!chapter) {
69
0
        chapter = av_mallocz(sizeof(*chapter));
70
0
        if (!chapter)
71
0
            return NULL;
72
0
        ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter);
73
0
        if (ret < 0) {
74
0
            av_free(chapter);
75
0
            return NULL;
76
0
        }
77
0
    }
78
0
    av_dict_set(&chapter->metadata, "title", title, 0);
79
0
    chapter->id        = id;
80
0
    chapter->time_base = time_base;
81
0
    chapter->start     = start;
82
0
    chapter->end       = end;
83
84
0
    return chapter;
85
0
}
86
87
int avformat_queue_attached_pictures(AVFormatContext *s)
88
0
{
89
0
    FormatContextInternal *const fci = ff_fc_internal(s);
90
0
    int ret;
91
0
    for (unsigned i = 0; i < s->nb_streams; i++)
92
0
        if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
93
0
            s->streams[i]->discard < AVDISCARD_ALL) {
94
0
            if (s->streams[i]->attached_pic.size <= 0) {
95
0
                av_log(s, AV_LOG_WARNING,
96
0
                       "Attached picture on stream %d has invalid size, "
97
0
                       "ignoring\n", i);
98
0
                continue;
99
0
            }
100
101
0
            ret = ff_packet_list_put(&fci->raw_packet_buffer,
102
0
                                         &s->streams[i]->attached_pic,
103
0
                                         av_packet_ref, 0);
104
0
            if (ret < 0)
105
0
                return ret;
106
0
        }
107
0
    return 0;
108
0
}
109
110
int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb,
111
                        AVBufferRef **buf, int size)
112
0
{
113
0
    AVStream *st = st0;
114
0
    AVPacket *pkt;
115
0
    int ret;
116
117
0
    if (!st && !(st = avformat_new_stream(s, NULL)))
118
0
        return AVERROR(ENOMEM);
119
0
    pkt = &st->attached_pic;
120
0
    if (buf) {
121
0
        av_assert1(*buf);
122
0
        av_packet_unref(pkt);
123
0
        pkt->buf  = *buf;
124
0
        pkt->data = (*buf)->data;
125
0
        pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE;
126
0
        *buf = NULL;
127
0
    } else {
128
0
        ret = av_get_packet(pb, pkt, size);
129
0
        if (ret < 0)
130
0
            goto fail;
131
0
    }
132
0
    st->disposition         |= AV_DISPOSITION_ATTACHED_PIC;
133
0
    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
134
135
0
    pkt->stream_index = st->index;
136
0
    pkt->flags       |= AV_PKT_FLAG_KEY;
137
138
0
    return 0;
139
0
fail:
140
0
    if (!st0)
141
0
        ff_remove_stream(s, st);
142
0
    return ret;
143
0
}
144
145
int ff_add_param_change(AVPacket *pkt, int32_t channels,
146
                        uint64_t channel_layout, int32_t sample_rate,
147
                        int32_t width, int32_t height)
148
0
{
149
0
    uint32_t flags = 0;
150
0
    int size = 4;
151
0
    uint8_t *data;
152
0
    if (!pkt)
153
0
        return AVERROR(EINVAL);
154
155
0
    if (sample_rate) {
156
0
        size  += 4;
157
0
        flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
158
0
    }
159
0
    if (width || height) {
160
0
        size  += 8;
161
0
        flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
162
0
    }
163
0
    data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
164
0
    if (!data)
165
0
        return AVERROR(ENOMEM);
166
0
    bytestream_put_le32(&data, flags);
167
0
    if (sample_rate)
168
0
        bytestream_put_le32(&data, sample_rate);
169
0
    if (width || height) {
170
0
        bytestream_put_le32(&data, width);
171
0
        bytestream_put_le32(&data, height);
172
0
    }
173
0
    return 0;
174
0
}
175
176
int av_read_play(AVFormatContext *s)
177
0
{
178
0
    if (ffifmt(s->iformat)->read_set_state)
179
0
        return ffifmt(s->iformat)->read_set_state(s, FF_INFMT_STATE_PLAY);
180
0
    if (s->pb)
181
0
        return avio_pause(s->pb, 0);
182
0
    return AVERROR(ENOSYS);
183
0
}
184
185
int av_read_pause(AVFormatContext *s)
186
0
{
187
0
    if (ffifmt(s->iformat)->read_set_state)
188
0
        return ffifmt(s->iformat)->read_set_state(s, FF_INFMT_STATE_PAUSE);
189
0
    if (s->pb)
190
0
        return avio_pause(s->pb, 1);
191
0
    return AVERROR(ENOSYS);
192
0
}
193
194
int avformat_send_command(AVFormatContext *s, enum AVFormatCommandID id, void *data)
195
0
{
196
0
    if (ffifmt(s->iformat)->handle_command)
197
0
        return ffifmt(s->iformat)->handle_command(s, FF_INFMT_COMMAND_SUBMIT, id, data);
198
0
    return AVERROR(ENOSYS);
199
0
}
200
201
int avformat_receive_command_reply(AVFormatContext *s, enum AVFormatCommandID id, void **data_out)
202
0
{
203
0
    if (ffifmt(s->iformat)->handle_command)
204
0
        return ffifmt(s->iformat)->handle_command(s, FF_INFMT_COMMAND_GET_REPLY, id, data_out);
205
0
    return AVERROR(ENOSYS);
206
0
}
207
208
int ff_generate_avci_extradata(AVStream *st)
209
0
{
210
0
    static const uint8_t avci100_1080p_extradata[] = {
211
        // SPS
212
0
        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
213
0
        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
214
0
        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
215
0
        0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
216
0
        0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
217
0
        0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
218
0
        0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
219
0
        0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
220
0
        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221
        // PPS
222
0
        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
223
0
        0xd0
224
0
    };
225
0
    static const uint8_t avci100_1080i_extradata[] = {
226
        // SPS
227
0
        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
228
0
        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
229
0
        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
230
0
        0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
231
0
        0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
232
0
        0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
233
0
        0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
234
0
        0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
235
0
        0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
236
0
        0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
237
0
        0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
238
        // PPS
239
0
        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
240
0
        0xd0
241
0
    };
242
0
    static const uint8_t avci50_1080p_extradata[] = {
243
        // SPS
244
0
        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
245
0
        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
246
0
        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
247
0
        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
248
0
        0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
249
0
        0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
250
0
        0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
251
0
        0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
252
0
        0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
253
        // PPS
254
0
        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
255
0
        0x11
256
0
    };
257
0
    static const uint8_t avci50_1080i_extradata[] = {
258
        // SPS
259
0
        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
260
0
        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
261
0
        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
262
0
        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
263
0
        0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
264
0
        0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
265
0
        0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
266
0
        0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
267
0
        0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
268
0
        0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
269
0
        0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
270
        // PPS
271
0
        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
272
0
        0x11
273
0
    };
274
0
    static const uint8_t avci100_720p_extradata[] = {
275
        // SPS
276
0
        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
277
0
        0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
278
0
        0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
279
0
        0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
280
0
        0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
281
0
        0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
282
0
        0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
283
0
        0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
284
0
        0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
285
0
        0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
286
        // PPS
287
0
        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
288
0
        0x11
289
0
    };
290
0
    static const uint8_t avci50_720p_extradata[] = {
291
        // SPS
292
0
        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
293
0
        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
294
0
        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
295
0
        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
296
0
        0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
297
0
        0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
298
0
        0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
299
0
        0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
300
0
        0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
301
        // PPS
302
0
        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
303
0
        0x11
304
0
    };
305
306
0
    const uint8_t *data = NULL;
307
0
    int ret, size       = 0;
308
309
0
    if (st->codecpar->width == 1920) {
310
0
        if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
311
0
            data = avci100_1080p_extradata;
312
0
            size = sizeof(avci100_1080p_extradata);
313
0
        } else {
314
0
            data = avci100_1080i_extradata;
315
0
            size = sizeof(avci100_1080i_extradata);
316
0
        }
317
0
    } else if (st->codecpar->width == 1440) {
318
0
        if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
319
0
            data = avci50_1080p_extradata;
320
0
            size = sizeof(avci50_1080p_extradata);
321
0
        } else {
322
0
            data = avci50_1080i_extradata;
323
0
            size = sizeof(avci50_1080i_extradata);
324
0
        }
325
0
    } else if (st->codecpar->width == 1280) {
326
0
        data = avci100_720p_extradata;
327
0
        size = sizeof(avci100_720p_extradata);
328
0
    } else if (st->codecpar->width == 960) {
329
0
        data = avci50_720p_extradata;
330
0
        size = sizeof(avci50_720p_extradata);
331
0
    }
332
333
0
    if (!size)
334
0
        return 0;
335
336
0
    if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
337
0
        return ret;
338
0
    memcpy(st->codecpar->extradata, data, size);
339
340
0
    return 0;
341
0
}
342
343
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
344
0
{
345
0
    int ret = ff_alloc_extradata(par, size);
346
0
    if (ret < 0)
347
0
        return ret;
348
0
    ret = ffio_read_size(pb, par->extradata, size);
349
0
    if (ret < 0) {
350
0
        av_freep(&par->extradata);
351
0
        par->extradata_size = 0;
352
0
        av_log(logctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
353
0
        return ret;
354
0
    }
355
356
0
    return ret;
357
0
}
358
359
int ff_find_stream_index(const AVFormatContext *s, int id)
360
0
{
361
0
    for (unsigned i = 0; i < s->nb_streams; i++)
362
0
        if (s->streams[i]->id == id)
363
0
            return i;
364
0
    return -1;
365
0
}
366
367
/* Over nine months at 44.1 kHz; keeps sums and rescalings in range. */
368
0
#define SMPB_MAX_SAMPLES (INT64_C(1) << 40)
369
370
int ff_itunes_parse_smpb(const char *value, int64_t *priming,
371
                         int64_t *remainder, int64_t *samples)
372
0
{
373
0
    uint64_t reserved, p, r, s;
374
0
    int end[4];
375
376
    /* 16 digits is the widest an uint64_t can take, and what the tag writes. */
377
0
    if (sscanf(value, "%16"SCNx64"%n %16"SCNx64"%n %16"SCNx64"%n %16"SCNx64"%n",
378
0
               &reserved, &end[0], &p, &end[1], &r, &end[2], &s, &end[3]) != 4)
379
0
        return AVERROR_INVALIDDATA;
380
381
    /* A field cut short at 16 digits would shift every field after it. */
382
0
    for (int i = 0; i < 4; i++)
383
0
        if (av_isxdigit(value[end[i]]))
384
0
            return AVERROR_INVALIDDATA;
385
386
0
    if (p > SMPB_MAX_SAMPLES || r > SMPB_MAX_SAMPLES || s > SMPB_MAX_SAMPLES)
387
0
        return AVERROR_INVALIDDATA;
388
389
0
    *priming   = p;
390
0
    *remainder = r;
391
0
    *samples   = s;
392
393
0
    return 0;
394
0
}