FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mux_utils.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 48 78 61.5%
Functions: 5 5 100.0%
Branches: 20 48 41.7%

Line Branch Exec Source
1 /*
2 * Various muxing utility 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/dict.h"
23 #include "libavutil/dict_internal.h"
24 #include "libavutil/internal.h"
25 #include "libavutil/log.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/parseutils.h"
28 #include "avformat.h"
29 #include "avio.h"
30 #include "internal.h"
31 #include "mux.h"
32
33 5990 int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
34 int std_compliance)
35 {
36
1/2
✓ Branch 0 taken 5990 times.
✗ Branch 1 not taken.
5990 if (ofmt) {
37 unsigned int codec_tag;
38
2/2
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 5900 times.
5990 if (ffofmt(ofmt)->query_codec)
39 5990 return ffofmt(ofmt)->query_codec(codec_id, std_compliance);
40
2/2
✓ Branch 0 taken 3175 times.
✓ Branch 1 taken 2725 times.
5900 else if (ofmt->codec_tag)
41 3175 return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
42
1/2
✓ Branch 0 taken 2725 times.
✗ Branch 1 not taken.
2725 else if (codec_id != AV_CODEC_ID_NONE &&
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2725 times.
2725 (codec_id == ofmt->video_codec ||
44 codec_id == ofmt->audio_codec ||
45 codec_id == ofmt->subtitle_codec))
46 2725 return 1;
47 else if (ffofmt(ofmt)->flags_internal & FF_OFMT_FLAG_ONLY_DEFAULT_CODECS)
48 return 0;
49 else if (ffofmt(ofmt)->flags_internal & FF_OFMT_FLAG_MAX_ONE_OF_EACH) {
50 enum AVMediaType type = avcodec_get_type(codec_id);
51 switch (type) {
52 case AVMEDIA_TYPE_AUDIO:
53 if (ofmt->audio_codec == AV_CODEC_ID_NONE)
54 return 0;
55 break;
56 case AVMEDIA_TYPE_VIDEO:
57 if (ofmt->video_codec == AV_CODEC_ID_NONE)
58 return 0;
59 break;
60 case AVMEDIA_TYPE_SUBTITLE:
61 if (ofmt->subtitle_codec == AV_CODEC_ID_NONE)
62 return 0;
63 break;
64 default:
65 return 0;
66 }
67 }
68 }
69 return AVERROR_PATCHWELCOME;
70 }
71
72 10 int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size)
73 {
74 int ret;
75 int64_t pos, pos_end;
76 uint8_t *buf, *read_buf[2];
77 10 int read_buf_id = 0;
78 int read_size[2];
79 AVIOContext *read_pb;
80
81 10 buf = av_malloc_array(shift_size, 2);
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!buf)
83 return AVERROR(ENOMEM);
84 10 read_buf[0] = buf;
85 10 read_buf[1] = buf + shift_size;
86
87 /* Shift the data: the AVIO context of the output can only be used for
88 * writing, so we re-open the same output, but for reading. It also avoids
89 * a read/seek/write/seek back and forth. */
90 10 avio_flush(s->pb);
91 10 ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret < 0) {
93 av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for shifting data\n", s->url);
94 goto end;
95 }
96
97 /* mark the end of the shift to up to the last data we wrote, and get ready
98 * for writing */
99 10 pos_end = avio_tell(s->pb);
100 10 avio_seek(s->pb, read_start + shift_size, SEEK_SET);
101
102 10 avio_seek(read_pb, read_start, SEEK_SET);
103 10 pos = avio_tell(read_pb);
104
105 #define READ_BLOCK do { \
106 read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
107 read_buf_id ^= 1; \
108 } while (0)
109
110 /* shift data by chunk of at most shift_size */
111 10 READ_BLOCK;
112 do {
113 int n;
114 28635 READ_BLOCK;
115 28635 n = read_size[read_buf_id];
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28635 times.
28635 if (n <= 0)
117 break;
118 28635 avio_write(s->pb, read_buf[read_buf_id], n);
119 28635 pos += n;
120
2/2
✓ Branch 0 taken 28625 times.
✓ Branch 1 taken 10 times.
28635 } while (pos < pos_end);
121 10 ret = ff_format_io_close(s, &read_pb);
122
123 10 end:
124 10 av_free(buf);
125 10 return ret;
126 }
127
128 51 int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
129 {
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (!s->oformat)
131 return AVERROR(EINVAL);
132
133
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 49 times.
51 if (!(s->oformat->flags & AVFMT_NOFILE))
134 2 return s->io_open(s, &s->pb, url, AVIO_FLAG_WRITE, options);
135 49 return 0;
136 }
137
138 3005 int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
139 {
140 AVDictionaryEntry *entry;
141 int64_t parsed_timestamp;
142 int ret;
143
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3004 times.
3005 if ((entry = av_dict_get(s->metadata, "creation_time", NULL, 0))) {
144
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if ((ret = av_parse_time(&parsed_timestamp, entry->value, 0)) >= 0) {
145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 *timestamp = return_seconds ? parsed_timestamp / 1000000 : parsed_timestamp;
146 1 return 1;
147 } else {
148 av_log(s, AV_LOG_WARNING, "Failed to parse creation_time %s\n", entry->value);
149 return ret;
150 }
151 }
152 3004 return 0;
153 }
154
155 2707 int ff_standardize_creation_time(AVFormatContext *s)
156 {
157 int64_t timestamp;
158 2707 int ret = ff_parse_creation_time_metadata(s, &timestamp, 0);
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2707 times.
2707 if (ret == 1)
160 return avpriv_dict_set_timestamp(&s->metadata, "creation_time", timestamp);
161 2707 return ret;
162 }
163