FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_mux.c
Date: 2022-05-23 03:24:52
Exec Total Coverage
Lines: 98 172 57.0%
Branches: 84 134 62.7%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <stdio.h>
20 #include <string.h>
21
22 #include "ffmpeg.h"
23
24 #include "libavutil/fifo.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/log.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/timestamp.h"
29
30 #include "libavcodec/packet.h"
31
32 #include "libavformat/avformat.h"
33 #include "libavformat/avio.h"
34
35 static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
36 {
37 int i;
38 for (i = 0; i < nb_output_streams; i++) {
39 OutputStream *ost2 = output_streams[i];
40 ost2->finished |= ost == ost2 ? this_stream : others;
41 }
42 }
43
44 440858 void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
45 int unqueue)
46 {
47 440858 AVFormatContext *s = of->ctx;
48 440858 AVStream *st = ost->st;
49 int ret;
50
51 /*
52 * Audio encoders may split the packets -- #frames in != #packets out.
53 * But there is no reordering, so we can limit the number of output packets
54 * by simply dropping them here.
55 * Counting encoded video frames needs to be done separately because of
56 * reordering, see do_video_out().
57 * Do not count the packet when unqueued because it has been counted when queued.
58 */
59
6/6
✓ Branch 0 taken 111709 times.
✓ Branch 1 taken 329149 times.
✓ Branch 2 taken 11304 times.
✓ Branch 3 taken 100405 times.
✓ Branch 4 taken 340178 times.
✓ Branch 5 taken 275 times.
440858 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
60
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 340172 times.
340178 if (ost->frame_number >= ost->max_frames) {
61 6 av_packet_unref(pkt);
62 6 return;
63 }
64 340172 ost->frame_number++;
65 }
66
67
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 440521 times.
440852 if (!of->header_written) {
68 AVPacket *tmp_pkt;
69 /* the muxer is not initialized yet, buffer the packet */
70
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 313 times.
331 if (!av_fifo_can_write(ost->muxing_queue)) {
71 18 size_t cur_size = av_fifo_can_read(ost->muxing_queue);
72 18 unsigned int are_we_over_size =
73 18 (ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 size_t limit = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
75 18 size_t new_size = FFMIN(2 * cur_size, limit);
76
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (new_size <= cur_size) {
78 av_log(NULL, AV_LOG_ERROR,
79 "Too many packets buffered for output stream %d:%d.\n",
80 ost->file_index, ost->st->index);
81 exit_program(1);
82 }
83 18 ret = av_fifo_grow2(ost->muxing_queue, new_size - cur_size);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (ret < 0)
85 exit_program(1);
86 }
87 331 ret = av_packet_make_refcounted(pkt);
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 331 times.
331 if (ret < 0)
89 exit_program(1);
90 331 tmp_pkt = av_packet_alloc();
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 331 times.
331 if (!tmp_pkt)
92 exit_program(1);
93 331 av_packet_move_ref(tmp_pkt, pkt);
94 331 ost->muxing_queue_data_size += tmp_pkt->size;
95 331 av_fifo_write(ost->muxing_queue, &tmp_pkt, 1);
96 331 return;
97 }
98
99
3/4
✓ Branch 0 taken 111639 times.
✓ Branch 1 taken 328882 times.
✓ Branch 2 taken 111639 times.
✗ Branch 3 not taken.
440521 if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
100
3/4
✓ Branch 0 taken 327295 times.
✓ Branch 1 taken 113226 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 327295 times.
440521 (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
101 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
102
103
2/2
✓ Branch 0 taken 111639 times.
✓ Branch 1 taken 328882 times.
440521 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
104 int i;
105 111639 uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
106 NULL);
107
2/2
✓ Branch 0 taken 9539 times.
✓ Branch 1 taken 102100 times.
111639 ost->quality = sd ? AV_RL32(sd) : -1;
108
2/2
✓ Branch 0 taken 9539 times.
✓ Branch 1 taken 102100 times.
111639 ost->pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE;
109
110
2/2
✓ Branch 0 taken 446556 times.
✓ Branch 1 taken 111639 times.
558195 for (i = 0; i<FF_ARRAY_ELEMS(ost->error); i++) {
111
3/4
✓ Branch 0 taken 38156 times.
✓ Branch 1 taken 408400 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 38156 times.
446556 if (sd && i < sd[5])
112 ost->error[i] = AV_RL64(sd + 8 + 8*i);
113 else
114 446556 ost->error[i] = -1;
115 }
116
117
4/4
✓ Branch 0 taken 100429 times.
✓ Branch 1 taken 11210 times.
✓ Branch 2 taken 9936 times.
✓ Branch 3 taken 90493 times.
111639 if (ost->frame_rate.num && ost->is_cfr) {
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9936 times.
9936 if (pkt->duration > 0)
119 av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
120 9936 pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
121 ost->mux_timebase);
122 }
123 }
124
125 440521 av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
126
127
2/2
✓ Branch 0 taken 206031 times.
✓ Branch 1 taken 234490 times.
440521 if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
128
1/2
✓ Branch 0 taken 206031 times.
✗ Branch 1 not taken.
206031 if (pkt->dts != AV_NOPTS_VALUE &&
129
2/2
✓ Branch 0 taken 205047 times.
✓ Branch 1 taken 984 times.
206031 pkt->pts != AV_NOPTS_VALUE &&
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 205047 times.
205047 pkt->dts > pkt->pts) {
131 av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
132 pkt->dts, pkt->pts,
133 ost->file_index, ost->st->index);
134 pkt->pts =
135 pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
136 - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
137 - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
138 }
139
6/6
✓ Branch 0 taken 83173 times.
✓ Branch 1 taken 122858 times.
✓ Branch 2 taken 1092 times.
✓ Branch 3 taken 82081 times.
✓ Branch 4 taken 1077 times.
✓ Branch 5 taken 15 times.
206031 if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
140
1/2
✓ Branch 0 taken 206016 times.
✗ Branch 1 not taken.
206016 pkt->dts != AV_NOPTS_VALUE &&
141
2/2
✓ Branch 0 taken 200905 times.
✓ Branch 1 taken 5111 times.
206016 ost->last_mux_dts != AV_NOPTS_VALUE) {
142 200905 int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
143
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 200882 times.
200905 if (pkt->dts < max) {
144
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
23 int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (exit_on_error)
146 loglevel = AV_LOG_ERROR;
147 23 av_log(s, loglevel, "Non-monotonous DTS in output stream "
148 "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
149 23 ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (exit_on_error) {
151 av_log(NULL, AV_LOG_FATAL, "aborting.\n");
152 exit_program(1);
153 }
154 23 av_log(s, loglevel, "changing to %"PRId64". This may result "
155 "in incorrect timestamps in the output file.\n",
156 max);
157
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 if (pkt->pts >= pkt->dts)
158 23 pkt->pts = FFMAX(pkt->pts, max);
159 23 pkt->dts = max;
160 }
161 }
162 }
163 440521 ost->last_mux_dts = pkt->dts;
164
165 440521 ost->data_size += pkt->size;
166 440521 ost->packets_written++;
167
168 440521 pkt->stream_index = ost->index;
169
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440521 times.
440521 if (debug_ts) {
171 av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
172 "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
173 av_get_media_type_string(ost->enc_ctx->codec_type),
174 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
175 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
176 av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
177 pkt->size
178 );
179 }
180
181 440521 ret = av_interleaved_write_frame(s, pkt);
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440521 times.
440521 if (ret < 0) {
183 print_error("av_interleaved_write_frame()", ret);
184 main_return_code = 1;
185 close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
186 }
187 }
188
189 static int print_sdp(void)
190 {
191 char sdp[16384];
192 int i;
193 int j, ret;
194 AVIOContext *sdp_pb;
195 AVFormatContext **avc;
196
197 for (i = 0; i < nb_output_files; i++) {
198 if (!output_files[i]->header_written)
199 return 0;
200 }
201
202 avc = av_malloc_array(nb_output_files, sizeof(*avc));
203 if (!avc)
204 exit_program(1);
205 for (i = 0, j = 0; i < nb_output_files; i++) {
206 if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
207 avc[j] = output_files[i]->ctx;
208 j++;
209 }
210 }
211
212 if (!j) {
213 av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
214 ret = AVERROR(EINVAL);
215 goto fail;
216 }
217
218 ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
219 if (ret < 0)
220 goto fail;
221
222 if (!sdp_filename) {
223 printf("SDP:\n%s\n", sdp);
224 fflush(stdout);
225 } else {
226 ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
227 if (ret < 0) {
228 av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
229 goto fail;
230 }
231
232 avio_print(sdp_pb, sdp);
233 avio_closep(&sdp_pb);
234 av_freep(&sdp_filename);
235 }
236
237 fail:
238 av_freep(&avc);
239 return ret;
240 }
241
242 /* open the muxer when all the streams are initialized */
243 6432 int of_check_init(OutputFile *of)
244 {
245 int ret, i;
246
247
2/2
✓ Branch 0 taken 6941 times.
✓ Branch 1 taken 6202 times.
13143 for (i = 0; i < of->ctx->nb_streams; i++) {
248 6941 OutputStream *ost = output_streams[of->ost_index + i];
249
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 6711 times.
6941 if (!ost->initialized)
250 230 return 0;
251 }
252
253 6202 ret = avformat_write_header(of->ctx, &of->opts);
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6202 times.
6202 if (ret < 0) {
255 av_log(NULL, AV_LOG_ERROR,
256 "Could not write header for output file #%d "
257 "(incorrect codec parameters ?): %s\n",
258 of->index, av_err2str(ret));
259 return ret;
260 }
261 //assert_avoptions(of->opts);
262 6202 of->header_written = 1;
263
264 6202 av_dump_format(of->ctx, of->index, of->ctx->url, 1);
265 6202 nb_output_dumped++;
266
267
2/4
✓ Branch 0 taken 6202 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6202 times.
6202 if (sdp_filename || want_sdp) {
268 ret = print_sdp();
269 if (ret < 0) {
270 av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
271 return ret;
272 }
273 }
274
275 /* flush the muxing queues */
276
2/2
✓ Branch 0 taken 6432 times.
✓ Branch 1 taken 6202 times.
12634 for (i = 0; i < of->ctx->nb_streams; i++) {
277 6432 OutputStream *ost = output_streams[of->ost_index + i];
278 AVPacket *pkt;
279
280 /* try to improve muxing time_base (only possible if nothing has been written yet) */
281
2/2
✓ Branch 1 taken 6340 times.
✓ Branch 2 taken 92 times.
6432 if (!av_fifo_can_read(ost->muxing_queue))
282 6340 ost->mux_timebase = ost->st->time_base;
283
284
2/2
✓ Branch 1 taken 331 times.
✓ Branch 2 taken 6432 times.
6763 while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0) {
285 331 ost->muxing_queue_data_size -= pkt->size;
286 331 of_write_packet(of, pkt, ost, 1);
287 331 av_packet_free(&pkt);
288 }
289 }
290
291 6202 return 0;
292 }
293
294 6202 int of_write_trailer(OutputFile *of)
295 {
296 int ret;
297
298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6202 times.
6202 if (!of->header_written) {
299 av_log(NULL, AV_LOG_ERROR,
300 "Nothing was written into output file %d (%s), because "
301 "at least one of its streams received no packets.\n",
302 of->index, of->ctx->url);
303 return AVERROR(EINVAL);
304 }
305
306 6202 ret = av_write_trailer(of->ctx);
307
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6202 times.
6202 if (ret < 0) {
308 av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
309 return ret;
310 }
311
312 6202 return 0;
313 }
314
315 6202 void of_close(OutputFile **pof)
316 {
317 6202 OutputFile *of = *pof;
318 AVFormatContext *s;
319
320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6202 times.
6202 if (!of)
321 return;
322
323 6202 s = of->ctx;
324
4/6
✓ Branch 0 taken 6202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6202 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6135 times.
✓ Branch 5 taken 67 times.
6202 if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
325 6135 avio_closep(&s->pb);
326 6202 avformat_free_context(s);
327 6202 av_dict_free(&of->opts);
328
329 6202 av_freep(pof);
330 }
331