Coverage Report

Created: 2026-01-25 07:18

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