FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mux_utils.c
Date: 2022-12-09 07:38:14
Exec Total Coverage
Lines: 44 63 69.8%
Functions: 5 6 83.3%
Branches: 16 36 44.4%

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 #if FF_API_GET_END_PTS
34 int64_t av_stream_get_end_pts(const AVStream *st)
35 {
36 if (cffstream(st)->priv_pts) {
37 return cffstream(st)->priv_pts->val;
38 } else
39 return AV_NOPTS_VALUE;
40 }
41 #endif
42
43 5375 int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
44 int std_compliance)
45 {
46
1/2
✓ Branch 0 taken 5375 times.
✗ Branch 1 not taken.
5375 if (ofmt) {
47 unsigned int codec_tag;
48
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 5288 times.
5375 if (ofmt->query_codec)
49 5375 return ofmt->query_codec(codec_id, std_compliance);
50
2/2
✓ Branch 0 taken 2763 times.
✓ Branch 1 taken 2525 times.
5288 else if (ofmt->codec_tag)
51 2763 return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2525 times.
2525 else if (codec_id == ofmt->video_codec ||
53 codec_id == ofmt->audio_codec ||
54 codec_id == ofmt->subtitle_codec ||
55 codec_id == ofmt->data_codec)
56 2525 return 1;
57 }
58 return AVERROR_PATCHWELCOME;
59 }
60
61 10 int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size)
62 {
63 int ret;
64 int64_t pos, pos_end;
65 uint8_t *buf, *read_buf[2];
66 10 int read_buf_id = 0;
67 int read_size[2];
68 AVIOContext *read_pb;
69
70 10 buf = av_malloc_array(shift_size, 2);
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!buf)
72 return AVERROR(ENOMEM);
73 10 read_buf[0] = buf;
74 10 read_buf[1] = buf + shift_size;
75
76 /* Shift the data: the AVIO context of the output can only be used for
77 * writing, so we re-open the same output, but for reading. It also avoids
78 * a read/seek/write/seek back and forth. */
79 10 avio_flush(s->pb);
80 10 ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret < 0) {
82 av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for shifting data\n", s->url);
83 goto end;
84 }
85
86 /* mark the end of the shift to up to the last data we wrote, and get ready
87 * for writing */
88 10 pos_end = avio_tell(s->pb);
89 10 avio_seek(s->pb, read_start + shift_size, SEEK_SET);
90
91 10 avio_seek(read_pb, read_start, SEEK_SET);
92 10 pos = avio_tell(read_pb);
93
94 #define READ_BLOCK do { \
95 read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
96 read_buf_id ^= 1; \
97 } while (0)
98
99 /* shift data by chunk of at most shift_size */
100 10 READ_BLOCK;
101 do {
102 int n;
103 22826 READ_BLOCK;
104 22826 n = read_size[read_buf_id];
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22826 times.
22826 if (n <= 0)
106 break;
107 22826 avio_write(s->pb, read_buf[read_buf_id], n);
108 22826 pos += n;
109
2/2
✓ Branch 0 taken 22816 times.
✓ Branch 1 taken 10 times.
22826 } while (pos < pos_end);
110 10 ret = ff_format_io_close(s, &read_pb);
111
112 10 end:
113 10 av_free(buf);
114 10 return ret;
115 }
116
117 51 int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
118 {
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (!s->oformat)
120 return AVERROR(EINVAL);
121
122
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 49 times.
51 if (!(s->oformat->flags & AVFMT_NOFILE))
123 2 return s->io_open(s, &s->pb, url, AVIO_FLAG_WRITE, options);
124 49 return 0;
125 }
126
127 2600 int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
128 {
129 AVDictionaryEntry *entry;
130 int64_t parsed_timestamp;
131 int ret;
132
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2600 times.
2600 if ((entry = av_dict_get(s->metadata, "creation_time", NULL, 0))) {
133 if ((ret = av_parse_time(&parsed_timestamp, entry->value, 0)) >= 0) {
134 *timestamp = return_seconds ? parsed_timestamp / 1000000 : parsed_timestamp;
135 return 1;
136 } else {
137 av_log(s, AV_LOG_WARNING, "Failed to parse creation_time %s\n", entry->value);
138 return ret;
139 }
140 }
141 2600 return 0;
142 }
143
144 2339 int ff_standardize_creation_time(AVFormatContext *s)
145 {
146 int64_t timestamp;
147 2339 int ret = ff_parse_creation_time_metadata(s, &timestamp, 0);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2339 times.
2339 if (ret == 1)
149 return avpriv_dict_set_timestamp(&s->metadata, "creation_time", timestamp);
150 2339 return ret;
151 }
152