Coverage Report

Created: 2025-12-31 07:57

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
3.43M
{
46
3.43M
    FormatContextInternal *const fci = ff_fc_internal(s);
47
3.43M
    AVChapter *chapter = NULL;
48
3.43M
    int ret;
49
50
3.43M
    if (end != AV_NOPTS_VALUE && start > end) {
51
6.63k
        av_log(s, AV_LOG_ERROR, "Chapter end time %"PRId64" before start %"PRId64"\n", end, start);
52
6.63k
        return NULL;
53
6.63k
    }
54
55
3.42M
    if (!s->nb_chapters) {
56
10.5k
        fci->chapter_ids_monotonic = 1;
57
3.41M
    } else if (!fci->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) {
58
386M
        for (unsigned i = 0; i < s->nb_chapters; i++)
59
385M
            if (s->chapters[i]->id == id)
60
680k
                chapter = s->chapters[i];
61
697k
        if (!chapter)
62
17.6k
            fci->chapter_ids_monotonic = 0;
63
697k
    }
64
65
3.42M
    if (!chapter) {
66
2.74M
        chapter = av_mallocz(sizeof(*chapter));
67
2.74M
        if (!chapter)
68
0
            return NULL;
69
2.74M
        ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter);
70
2.74M
        if (ret < 0) {
71
0
            av_free(chapter);
72
0
            return NULL;
73
0
        }
74
2.74M
    }
75
3.42M
    av_dict_set(&chapter->metadata, "title", title, 0);
76
3.42M
    chapter->id        = id;
77
3.42M
    chapter->time_base = time_base;
78
3.42M
    chapter->start     = start;
79
3.42M
    chapter->end       = end;
80
81
3.42M
    return chapter;
82
3.42M
}
83
84
int avformat_queue_attached_pictures(AVFormatContext *s)
85
836k
{
86
836k
    FormatContextInternal *const fci = ff_fc_internal(s);
87
836k
    int ret;
88
2.69M
    for (unsigned i = 0; i < s->nb_streams; i++)
89
1.85M
        if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
90
172k
            s->streams[i]->discard < AVDISCARD_ALL) {
91
172k
            if (s->streams[i]->attached_pic.size <= 0) {
92
591
                av_log(s, AV_LOG_WARNING,
93
591
                       "Attached picture on stream %d has invalid size, "
94
591
                       "ignoring\n", i);
95
591
                continue;
96
591
            }
97
98
172k
            ret = avpriv_packet_list_put(&fci->raw_packet_buffer,
99
172k
                                         &s->streams[i]->attached_pic,
100
172k
                                         av_packet_ref, 0);
101
172k
            if (ret < 0)
102
0
                return ret;
103
172k
        }
104
836k
    return 0;
105
836k
}
106
107
int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb,
108
                        AVBufferRef **buf, int size)
109
273k
{
110
273k
    AVStream *st = st0;
111
273k
    AVPacket *pkt;
112
273k
    int ret;
113
114
273k
    if (!st && !(st = avformat_new_stream(s, NULL)))
115
452
        return AVERROR(ENOMEM);
116
273k
    pkt = &st->attached_pic;
117
273k
    if (buf) {
118
222k
        av_assert1(*buf);
119
222k
        av_packet_unref(pkt);
120
222k
        pkt->buf  = *buf;
121
222k
        pkt->data = (*buf)->data;
122
222k
        pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE;
123
222k
        *buf = NULL;
124
222k
    } else {
125
51.0k
        ret = av_get_packet(pb, pkt, size);
126
51.0k
        if (ret < 0)
127
1.49k
            goto fail;
128
51.0k
    }
129
271k
    st->disposition         |= AV_DISPOSITION_ATTACHED_PIC;
130
271k
    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
131
132
271k
    pkt->stream_index = st->index;
133
271k
    pkt->flags       |= AV_PKT_FLAG_KEY;
134
135
271k
    return 0;
136
1.49k
fail:
137
1.49k
    if (!st0)
138
33
        ff_remove_stream(s, st);
139
1.49k
    return ret;
140
273k
}
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
275k
{
146
275k
    uint32_t flags = 0;
147
275k
    int size = 4;
148
275k
    uint8_t *data;
149
275k
    if (!pkt)
150
0
        return AVERROR(EINVAL);
151
152
275k
    if (sample_rate) {
153
271k
        size  += 4;
154
271k
        flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
155
271k
    }
156
275k
    if (width || height) {
157
3.61k
        size  += 8;
158
3.61k
        flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
159
3.61k
    }
160
275k
    data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
161
275k
    if (!data)
162
0
        return AVERROR(ENOMEM);
163
275k
    bytestream_put_le32(&data, flags);
164
275k
    if (sample_rate)
165
271k
        bytestream_put_le32(&data, sample_rate);
166
275k
    if (width || height) {
167
3.61k
        bytestream_put_le32(&data, width);
168
3.61k
        bytestream_put_le32(&data, height);
169
3.61k
    }
170
275k
    return 0;
171
275k
}
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
3.75k
{
193
3.75k
    static const uint8_t avci100_1080p_extradata[] = {
194
        // SPS
195
3.75k
        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
196
3.75k
        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
197
3.75k
        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
198
3.75k
        0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
199
3.75k
        0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
200
3.75k
        0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
201
3.75k
        0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
202
3.75k
        0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
203
3.75k
        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204
        // PPS
205
3.75k
        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
206
3.75k
        0xd0
207
3.75k
    };
208
3.75k
    static const uint8_t avci100_1080i_extradata[] = {
209
        // SPS
210
3.75k
        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
211
3.75k
        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
212
3.75k
        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
213
3.75k
        0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
214
3.75k
        0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
215
3.75k
        0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
216
3.75k
        0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
217
3.75k
        0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
218
3.75k
        0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
219
3.75k
        0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
220
3.75k
        0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
221
        // PPS
222
3.75k
        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
223
3.75k
        0xd0
224
3.75k
    };
225
3.75k
    static const uint8_t avci50_1080p_extradata[] = {
226
        // SPS
227
3.75k
        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
228
3.75k
        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
229
3.75k
        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
230
3.75k
        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
231
3.75k
        0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
232
3.75k
        0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
233
3.75k
        0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
234
3.75k
        0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
235
3.75k
        0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
236
        // PPS
237
3.75k
        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
238
3.75k
        0x11
239
3.75k
    };
240
3.75k
    static const uint8_t avci50_1080i_extradata[] = {
241
        // SPS
242
3.75k
        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
243
3.75k
        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
244
3.75k
        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
245
3.75k
        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
246
3.75k
        0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
247
3.75k
        0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
248
3.75k
        0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
249
3.75k
        0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
250
3.75k
        0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
251
3.75k
        0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
252
3.75k
        0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
253
        // PPS
254
3.75k
        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
255
3.75k
        0x11
256
3.75k
    };
257
3.75k
    static const uint8_t avci100_720p_extradata[] = {
258
        // SPS
259
3.75k
        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
260
3.75k
        0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
261
3.75k
        0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
262
3.75k
        0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
263
3.75k
        0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
264
3.75k
        0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
265
3.75k
        0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
266
3.75k
        0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
267
3.75k
        0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
268
3.75k
        0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
269
        // PPS
270
3.75k
        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
271
3.75k
        0x11
272
3.75k
    };
273
3.75k
    static const uint8_t avci50_720p_extradata[] = {
274
        // SPS
275
3.75k
        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
276
3.75k
        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
277
3.75k
        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
278
3.75k
        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
279
3.75k
        0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
280
3.75k
        0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
281
3.75k
        0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
282
3.75k
        0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
283
3.75k
        0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
284
        // PPS
285
3.75k
        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
286
3.75k
        0x11
287
3.75k
    };
288
289
3.75k
    const uint8_t *data = NULL;
290
3.75k
    int ret, size       = 0;
291
292
3.75k
    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
3.75k
    } 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
3.75k
    } else if (st->codecpar->width == 1280) {
309
0
        data = avci100_720p_extradata;
310
0
        size = sizeof(avci100_720p_extradata);
311
3.75k
    } else if (st->codecpar->width == 960) {
312
0
        data = avci50_720p_extradata;
313
0
        size = sizeof(avci50_720p_extradata);
314
0
    }
315
316
3.75k
    if (!size)
317
3.75k
        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
447k
{
328
447k
    int ret = ff_alloc_extradata(par, size);
329
447k
    if (ret < 0)
330
66.7k
        return ret;
331
380k
    ret = ffio_read_size(pb, par->extradata, size);
332
380k
    if (ret < 0) {
333
10.3k
        av_freep(&par->extradata);
334
10.3k
        par->extradata_size = 0;
335
10.3k
        av_log(logctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
336
10.3k
        return ret;
337
10.3k
    }
338
339
370k
    return ret;
340
380k
}
341
342
int ff_find_stream_index(const AVFormatContext *s, int id)
343
48.7k
{
344
150k
    for (unsigned i = 0; i < s->nb_streams; i++)
345
142k
        if (s->streams[i]->id == id)
346
40.7k
            return i;
347
7.99k
    return -1;
348
48.7k
}