FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_mux.c
Date: 2023-01-27 00:32:08
Exec Total Coverage
Lines: 298 413 72.2%
Functions: 21 22 95.5%
Branches: 159 240 66.2%

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 <stdatomic.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "ffmpeg.h"
24 #include "ffmpeg_mux.h"
25 #include "objpool.h"
26 #include "sync_queue.h"
27 #include "thread_queue.h"
28
29 #include "libavutil/fifo.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/log.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/timestamp.h"
34 #include "libavutil/thread.h"
35
36 #include "libavcodec/packet.h"
37
38 #include "libavformat/avformat.h"
39 #include "libavformat/avio.h"
40
41 int want_sdp = 1;
42
43 984983 static Muxer *mux_from_of(OutputFile *of)
44 {
45 984983 return (Muxer*)of;
46 }
47
48 488120 static int64_t filesize(AVIOContext *pb)
49 {
50 488120 int64_t ret = -1;
51
52
2/2
✓ Branch 0 taken 479219 times.
✓ Branch 1 taken 8901 times.
488120 if (pb) {
53 479219 ret = avio_size(pb);
54
2/2
✓ Branch 0 taken 101208 times.
✓ Branch 1 taken 378011 times.
479219 if (ret <= 0) // FIXME improve avio_size() so it works with non seekable output too
55 101208 ret = avio_tell(pb);
56 }
57
58 488120 return ret;
59 }
60
61 481658 static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
62 {
63 481658 MuxStream *ms = ms_from_ost(ost);
64 481658 AVFormatContext *s = mux->fc;
65 481658 AVStream *st = ost->st;
66 int64_t fs;
67 int ret;
68
69 481658 fs = filesize(s->pb);
70 481658 atomic_store(&mux->last_filesize, fs);
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 481658 times.
481658 if (fs >= mux->limit_filesize) {
72 ret = AVERROR_EOF;
73 goto fail;
74 }
75
76
3/4
✓ Branch 0 taken 116211 times.
✓ Branch 1 taken 365447 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 116211 times.
481658 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
77 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
78
79
2/2
✓ Branch 0 taken 116211 times.
✓ Branch 1 taken 365447 times.
481658 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
80
4/4
✓ Branch 0 taken 103514 times.
✓ Branch 1 taken 12697 times.
✓ Branch 2 taken 10633 times.
✓ Branch 3 taken 92881 times.
116211 if (ost->frame_rate.num && ost->is_cfr) {
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10633 times.
10633 if (pkt->duration > 0)
82 av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
83 10633 pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
84 ost->mux_timebase);
85 }
86 }
87
88 481658 av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
89
90
2/2
✓ Branch 0 taken 229380 times.
✓ Branch 1 taken 252278 times.
481658 if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
91
1/2
✓ Branch 0 taken 229380 times.
✗ Branch 1 not taken.
229380 if (pkt->dts != AV_NOPTS_VALUE &&
92
2/2
✓ Branch 0 taken 227215 times.
✓ Branch 1 taken 2165 times.
229380 pkt->pts != AV_NOPTS_VALUE &&
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 227215 times.
227215 pkt->dts > pkt->pts) {
94 av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
95 pkt->dts, pkt->pts,
96 ost->file_index, ost->st->index);
97 pkt->pts =
98 pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
99 - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
100 - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
101 }
102
6/6
✓ Branch 0 taken 86171 times.
✓ Branch 1 taken 143209 times.
✓ Branch 2 taken 1204 times.
✓ Branch 3 taken 84967 times.
✓ Branch 4 taken 1189 times.
✓ Branch 5 taken 15 times.
229380 if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
103
1/2
✓ Branch 0 taken 229365 times.
✗ Branch 1 not taken.
229365 pkt->dts != AV_NOPTS_VALUE &&
104
2/2
✓ Branch 0 taken 224061 times.
✓ Branch 1 taken 5304 times.
229365 ms->last_mux_dts != AV_NOPTS_VALUE) {
105 224061 int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
106
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 224031 times.
224061 if (pkt->dts < max) {
107
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
30 int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (exit_on_error)
109 loglevel = AV_LOG_ERROR;
110 30 av_log(s, loglevel, "Non-monotonous DTS in output stream "
111 "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
112 30 ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (exit_on_error) {
114 ret = AVERROR(EINVAL);
115 goto fail;
116 }
117
118 30 av_log(s, loglevel, "changing to %"PRId64". This may result "
119 "in incorrect timestamps in the output file.\n",
120 max);
121
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (pkt->pts >= pkt->dts)
122 30 pkt->pts = FFMAX(pkt->pts, max);
123 30 pkt->dts = max;
124 }
125 }
126 }
127 481658 ms->last_mux_dts = pkt->dts;
128
129 481658 ost->data_size_mux += pkt->size;
130 481658 atomic_fetch_add(&ost->packets_written, 1);
131
132 481658 pkt->stream_index = ost->index;
133
134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 481658 times.
481658 if (debug_ts) {
135 av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
136 "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
137 av_get_media_type_string(st->codecpar->codec_type),
138 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
139 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
140 av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
141 pkt->size
142 );
143 }
144
145 481658 ret = av_interleaved_write_frame(s, pkt);
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 481658 times.
481658 if (ret < 0) {
147 print_error("av_interleaved_write_frame()", ret);
148 goto fail;
149 }
150
151 481658 return 0;
152 fail:
153 av_packet_unref(pkt);
154 return ret;
155 }
156
157 488437 static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt)
158 {
159 488437 OutputFile *of = &mux->of;
160
161
2/2
✓ Branch 0 taken 811 times.
✓ Branch 1 taken 487626 times.
488437 if (ost->sq_idx_mux >= 0) {
162 811 int ret = sq_send(mux->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
163
2/2
✓ Branch 0 taken 773 times.
✓ Branch 1 taken 38 times.
811 if (ret < 0)
164 38 return ret;
165
166 719 while (1) {
167 1492 ret = sq_receive(mux->sq_mux, -1, SQPKT(mux->sq_pkt));
168
2/2
✓ Branch 0 taken 773 times.
✓ Branch 1 taken 719 times.
1492 if (ret < 0)
169
3/4
✓ Branch 0 taken 764 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 764 times.
773 return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret;
170
171 719 ret = write_packet(mux, of->streams[ret],
172 mux->sq_pkt);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 719 times.
719 if (ret < 0)
174 return ret;
175 }
176
2/2
✓ Branch 0 taken 480939 times.
✓ Branch 1 taken 6687 times.
487626 } else if (pkt)
177 480939 return write_packet(mux, ost, pkt);
178
179 6687 return 0;
180 }
181
182 6462 static void thread_set_name(OutputFile *of)
183 {
184 char name[16];
185 6462 snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
186 6462 ff_thread_setname(name);
187 6462 }
188
189 6462 static void *muxer_thread(void *arg)
190 {
191 6462 Muxer *mux = arg;
192 6462 OutputFile *of = &mux->of;
193 6462 AVPacket *pkt = NULL;
194 6462 int ret = 0;
195
196 6462 pkt = av_packet_alloc();
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (!pkt) {
198 ret = AVERROR(ENOMEM);
199 goto finish;
200 }
201
202 6462 thread_set_name(of);
203
204 488437 while (1) {
205 OutputStream *ost;
206 int stream_idx;
207
208 494899 ret = tq_receive(mux->tq, &stream_idx, pkt);
209
2/2
✓ Branch 0 taken 6462 times.
✓ Branch 1 taken 488437 times.
494899 if (stream_idx < 0) {
210 6462 av_log(NULL, AV_LOG_VERBOSE,
211 "All streams finished for output file #%d\n", of->index);
212 6462 ret = 0;
213 6462 break;
214 }
215
216 488437 ost = of->streams[stream_idx];
217
2/2
✓ Branch 0 taken 481744 times.
✓ Branch 1 taken 6693 times.
488437 ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt);
218 488437 av_packet_unref(pkt);
219
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 488399 times.
488437 if (ret == AVERROR_EOF)
220 38 tq_receive_finish(mux->tq, stream_idx);
221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 488399 times.
488399 else if (ret < 0) {
222 av_log(NULL, AV_LOG_ERROR,
223 "Error muxing a packet for output file #%d\n", of->index);
224 break;
225 }
226 }
227
228 6462 finish:
229 6462 av_packet_free(&pkt);
230
231
2/2
✓ Branch 0 taken 6707 times.
✓ Branch 1 taken 6462 times.
13169 for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
232 6707 tq_receive_finish(mux->tq, i);
233
234 6462 av_log(NULL, AV_LOG_VERBOSE, "Terminating muxer thread %d\n", of->index);
235
236 6462 return (void*)(intptr_t)ret;
237 }
238
239 491462 static int thread_submit_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
240 {
241 491462 int ret = 0;
242
243
3/4
✓ Branch 0 taken 481756 times.
✓ Branch 1 taken 9706 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 481756 times.
491462 if (!pkt || ost->finished & MUXER_FINISHED)
244 9706 goto finish;
245
246 481756 ret = tq_send(mux->tq, ost->index, pkt);
247
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 481744 times.
481756 if (ret < 0)
248 12 goto finish;
249
250 481744 return 0;
251
252 9718 finish:
253
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9706 times.
9718 if (pkt)
254 12 av_packet_unref(pkt);
255
256 9718 ost->finished |= MUXER_FINISHED;
257 9718 tq_send_finish(mux->tq, ost->index);
258
2/2
✓ Branch 0 taken 9706 times.
✓ Branch 1 taken 12 times.
9718 return ret == AVERROR_EOF ? 0 : ret;
259 }
260
261 333 static int queue_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
262 {
263 333 MuxStream *ms = ms_from_ost(ost);
264 333 AVPacket *tmp_pkt = NULL;
265 int ret;
266
267
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 315 times.
333 if (!av_fifo_can_write(ms->muxing_queue)) {
268 18 size_t cur_size = av_fifo_can_read(ms->muxing_queue);
269
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 size_t pkt_size = pkt ? pkt->size : 0;
270 18 unsigned int are_we_over_size =
271 18 (ms->muxing_queue_data_size + pkt_size) > ms->muxing_queue_data_threshold;
272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 size_t limit = are_we_over_size ? ms->max_muxing_queue_size : SIZE_MAX;
273 18 size_t new_size = FFMIN(2 * cur_size, limit);
274
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (new_size <= cur_size) {
276 av_log(NULL, AV_LOG_ERROR,
277 "Too many packets buffered for output stream %d:%d.\n",
278 ost->file_index, ost->st->index);
279 return AVERROR(ENOSPC);
280 }
281 18 ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (ret < 0)
283 return ret;
284 }
285
286
1/2
✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
333 if (pkt) {
287 333 ret = av_packet_make_refcounted(pkt);
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
333 if (ret < 0)
289 return ret;
290
291 333 tmp_pkt = av_packet_alloc();
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
333 if (!tmp_pkt)
293 return AVERROR(ENOMEM);
294
295 333 av_packet_move_ref(tmp_pkt, pkt);
296 333 ms->muxing_queue_data_size += tmp_pkt->size;
297 }
298 333 av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
299
300 333 return 0;
301 }
302
303 491462 static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost)
304 {
305 int ret;
306
307
2/2
✓ Branch 0 taken 491129 times.
✓ Branch 1 taken 333 times.
491462 if (mux->tq) {
308 491129 return thread_submit_packet(mux, ost, pkt);
309 } else {
310 /* the muxer is not initialized yet, buffer the packet */
311 333 ret = queue_packet(mux, ost, pkt);
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
333 if (ret < 0) {
313 if (pkt)
314 av_packet_unref(pkt);
315 return ret;
316 }
317 }
318
319 333 return 0;
320 }
321
322 491473 void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof)
323 {
324 491473 Muxer *mux = mux_from_of(of);
325 491473 MuxStream *ms = ms_from_ost(ost);
326 const char *err_msg;
327 491473 int ret = 0;
328
329
4/4
✓ Branch 0 taken 481767 times.
✓ Branch 1 taken 9706 times.
✓ Branch 2 taken 481766 times.
✓ Branch 3 taken 1 times.
491473 if (!eof && pkt->dts != AV_NOPTS_VALUE)
330 481766 ost->last_mux_dts = av_rescale_q(pkt->dts, ost->mux_timebase, AV_TIME_BASE_Q);
331
332 /* apply the output bitstream filters */
333
2/2
✓ Branch 0 taken 7526 times.
✓ Branch 1 taken 483947 times.
491473 if (ms->bsf_ctx) {
334 7526 int bsf_eof = 0;
335
336
2/2
✓ Branch 0 taken 7337 times.
✓ Branch 1 taken 189 times.
7526 ret = av_bsf_send_packet(ms->bsf_ctx, eof ? NULL : pkt);
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7526 times.
7526 if (ret < 0) {
338 err_msg = "submitting a packet for bitstream filtering";
339 goto fail;
340 }
341
342
2/2
✓ Branch 0 taken 14852 times.
✓ Branch 1 taken 189 times.
15041 while (!bsf_eof) {
343 14852 ret = av_bsf_receive_packet(ms->bsf_ctx, pkt);
344
2/2
✓ Branch 0 taken 7335 times.
✓ Branch 1 taken 7517 times.
14852 if (ret == AVERROR(EAGAIN))
345 7335 return;
346
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 7328 times.
7517 else if (ret == AVERROR_EOF)
347 189 bsf_eof = 1;
348
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7326 times.
7328 else if (ret < 0) {
349 2 err_msg = "applying bitstream filters to a packet";
350 2 goto fail;
351 }
352
353
2/2
✓ Branch 0 taken 7326 times.
✓ Branch 1 taken 189 times.
7515 ret = submit_packet(mux, bsf_eof ? NULL : pkt, ost);
354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7515 times.
7515 if (ret < 0)
355 goto mux_fail;
356 }
357 } else {
358
2/2
✓ Branch 0 taken 474430 times.
✓ Branch 1 taken 9517 times.
483947 ret = submit_packet(mux, eof ? NULL : pkt, ost);
359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483947 times.
483947 if (ret < 0)
360 goto mux_fail;
361 }
362
363 484136 return;
364
365 mux_fail:
366 err_msg = "submitting a packet to the muxer";
367
368 2 fail:
369 2 av_log(NULL, AV_LOG_ERROR, "Error %s for output stream #%d:%d.\n",
370 err_msg, ost->file_index, ost->index);
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (exit_on_error)
372 exit_program(1);
373
374 }
375
376 12924 static int thread_stop(Muxer *mux)
377 {
378 void *ret;
379
380
3/4
✓ Branch 0 taken 12924 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6462 times.
✓ Branch 3 taken 6462 times.
12924 if (!mux || !mux->tq)
381 6462 return 0;
382
383
2/2
✓ Branch 0 taken 6707 times.
✓ Branch 1 taken 6462 times.
13169 for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
384 6707 tq_send_finish(mux->tq, i);
385
386 6462 pthread_join(mux->thread, &ret);
387
388 6462 tq_free(&mux->tq);
389
390 6462 return (int)(intptr_t)ret;
391 }
392
393 963488 static void pkt_move(void *dst, void *src)
394 {
395 963488 av_packet_move_ref(dst, src);
396 963488 }
397
398 6462 static int thread_start(Muxer *mux)
399 {
400 6462 AVFormatContext *fc = mux->fc;
401 ObjPool *op;
402 int ret;
403
404 6462 op = objpool_alloc_packets();
405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (!op)
406 return AVERROR(ENOMEM);
407
408 6462 mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (!mux->tq) {
410 objpool_free(&op);
411 return AVERROR(ENOMEM);
412 }
413
414 6462 ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)mux);
415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (ret) {
416 tq_free(&mux->tq);
417 return AVERROR(ret);
418 }
419
420 /* flush the muxing queues */
421
2/2
✓ Branch 0 taken 6707 times.
✓ Branch 1 taken 6462 times.
13169 for (int i = 0; i < fc->nb_streams; i++) {
422 6707 OutputStream *ost = mux->of.streams[i];
423 6707 MuxStream *ms = ms_from_ost(ost);
424 AVPacket *pkt;
425
426 /* try to improve muxing time_base (only possible if nothing has been written yet) */
427
2/2
✓ Branch 1 taken 6614 times.
✓ Branch 2 taken 93 times.
6707 if (!av_fifo_can_read(ms->muxing_queue))
428 6614 ost->mux_timebase = ost->st->time_base;
429
430
2/2
✓ Branch 1 taken 333 times.
✓ Branch 2 taken 6707 times.
7040 while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
431 333 ret = thread_submit_packet(mux, ost, pkt);
432
1/2
✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
333 if (pkt) {
433 333 ms->muxing_queue_data_size -= pkt->size;
434 333 av_packet_free(&pkt);
435 }
436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
333 if (ret < 0)
437 return ret;
438 }
439 }
440
441 6462 return 0;
442 }
443
444 static int print_sdp(void)
445 {
446 char sdp[16384];
447 int i;
448 int j, ret;
449 AVIOContext *sdp_pb;
450 AVFormatContext **avc;
451
452 for (i = 0; i < nb_output_files; i++) {
453 if (!mux_from_of(output_files[i])->header_written)
454 return 0;
455 }
456
457 avc = av_malloc_array(nb_output_files, sizeof(*avc));
458 if (!avc)
459 return AVERROR(ENOMEM);
460 for (i = 0, j = 0; i < nb_output_files; i++) {
461 if (!strcmp(output_files[i]->format->name, "rtp")) {
462 avc[j] = mux_from_of(output_files[i])->fc;
463 j++;
464 }
465 }
466
467 if (!j) {
468 av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
469 ret = AVERROR(EINVAL);
470 goto fail;
471 }
472
473 ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
474 if (ret < 0)
475 goto fail;
476
477 if (!sdp_filename) {
478 printf("SDP:\n%s\n", sdp);
479 fflush(stdout);
480 } else {
481 ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
482 if (ret < 0) {
483 av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
484 goto fail;
485 }
486
487 avio_print(sdp_pb, sdp);
488 avio_closep(&sdp_pb);
489 av_freep(&sdp_filename);
490 }
491
492 // SDP successfully written, allow muxer threads to start
493 ret = 1;
494
495 fail:
496 av_freep(&avc);
497 return ret;
498 }
499
500 6707 int mux_check_init(Muxer *mux)
501 {
502 6707 OutputFile *of = &mux->of;
503 6707 AVFormatContext *fc = mux->fc;
504 int ret, i;
505
506
2/2
✓ Branch 0 taken 7244 times.
✓ Branch 1 taken 6462 times.
13706 for (i = 0; i < fc->nb_streams; i++) {
507 7244 OutputStream *ost = of->streams[i];
508
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 6999 times.
7244 if (!ost->initialized)
509 245 return 0;
510 }
511
512 6462 ret = avformat_write_header(fc, &mux->opts);
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (ret < 0) {
514 av_log(NULL, AV_LOG_ERROR,
515 "Could not write header for output file #%d "
516 "(incorrect codec parameters ?): %s\n",
517 of->index, av_err2str(ret));
518 return ret;
519 }
520 //assert_avoptions(of->opts);
521 6462 mux->header_written = 1;
522
523 6462 av_dump_format(fc, of->index, fc->url, 1);
524 6462 nb_output_dumped++;
525
526
2/4
✓ Branch 0 taken 6462 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6462 times.
6462 if (sdp_filename || want_sdp) {
527 ret = print_sdp();
528 if (ret < 0) {
529 av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
530 return ret;
531 } else if (ret == 1) {
532 /* SDP is written only after all the muxers are ready, so now we
533 * start ALL the threads */
534 for (i = 0; i < nb_output_files; i++) {
535 ret = thread_start(mux_from_of(output_files[i]));
536 if (ret < 0)
537 return ret;
538 }
539 }
540 } else {
541 6462 ret = thread_start(mux_from_of(of));
542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (ret < 0)
543 return ret;
544 }
545
546 6462 return 0;
547 }
548
549 6707 static int bsf_init(MuxStream *ms)
550 {
551 6707 OutputStream *ost = &ms->ost;
552 6707 AVBSFContext *ctx = ms->bsf_ctx;
553 int ret;
554
555
2/2
✓ Branch 0 taken 6610 times.
✓ Branch 1 taken 97 times.
6707 if (!ctx)
556 6610 return 0;
557
558 97 ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (ret < 0)
560 return ret;
561
562 97 ctx->time_base_in = ost->st->time_base;
563
564 97 ret = av_bsf_init(ctx);
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (ret < 0) {
566 av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
567 ctx->filter->name);
568 return ret;
569 }
570
571 97 ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (ret < 0)
573 return ret;
574 97 ost->st->time_base = ctx->time_base_out;
575
576 97 return 0;
577 }
578
579 6707 int of_stream_init(OutputFile *of, OutputStream *ost)
580 {
581 6707 Muxer *mux = mux_from_of(of);
582 6707 MuxStream *ms = ms_from_ost(ost);
583 int ret;
584
585
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 6687 times.
6707 if (ost->sq_idx_mux >= 0)
586 20 sq_set_tb(mux->sq_mux, ost->sq_idx_mux, ost->mux_timebase);
587
588 /* initialize bitstream filters for the output stream
589 * needs to be done here, because the codec id for streamcopy is not
590 * known until now */
591 6707 ret = bsf_init(ms);
592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6707 times.
6707 if (ret < 0)
593 return ret;
594
595 6707 ost->initialized = 1;
596
597 6707 return mux_check_init(mux);
598 }
599
600 6462 int of_write_trailer(OutputFile *of)
601 {
602 6462 Muxer *mux = mux_from_of(of);
603 6462 AVFormatContext *fc = mux->fc;
604 int ret;
605
606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (!mux->tq) {
607 av_log(NULL, AV_LOG_ERROR,
608 "Nothing was written into output file %d (%s), because "
609 "at least one of its streams received no packets.\n",
610 of->index, fc->url);
611 return AVERROR(EINVAL);
612 }
613
614 6462 ret = thread_stop(mux);
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (ret < 0)
616 main_return_code = ret;
617
618 6462 ret = av_write_trailer(fc);
619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (ret < 0) {
620 av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", fc->url, av_err2str(ret));
621 return ret;
622 }
623
624 6462 mux->last_filesize = filesize(fc->pb);
625
626
2/2
✓ Branch 0 taken 6376 times.
✓ Branch 1 taken 86 times.
6462 if (!(of->format->flags & AVFMT_NOFILE)) {
627 6376 ret = avio_closep(&fc->pb);
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6376 times.
6376 if (ret < 0) {
629 av_log(NULL, AV_LOG_ERROR, "Error closing file %s: %s\n",
630 fc->url, av_err2str(ret));
631 return ret;
632 }
633 }
634
635 6462 return 0;
636 }
637
638 6707 static void ost_free(OutputStream **post)
639 {
640 6707 OutputStream *ost = *post;
641 MuxStream *ms;
642
643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6707 times.
6707 if (!ost)
644 return;
645 6707 ms = ms_from_ost(ost);
646
647
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6703 times.
6707 if (ost->logfile) {
648
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (fclose(ost->logfile))
649 av_log(NULL, AV_LOG_ERROR,
650 "Error closing logfile, loss of information possible: %s\n",
651 av_err2str(AVERROR(errno)));
652 4 ost->logfile = NULL;
653 }
654
655
1/2
✓ Branch 0 taken 6707 times.
✗ Branch 1 not taken.
6707 if (ms->muxing_queue) {
656 AVPacket *pkt;
657
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6707 times.
6707 while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
658 av_packet_free(&pkt);
659 6707 av_fifo_freep2(&ms->muxing_queue);
660 }
661
662 6707 av_bsf_free(&ms->bsf_ctx);
663
664 6707 av_frame_free(&ost->filtered_frame);
665 6707 av_frame_free(&ost->sq_frame);
666 6707 av_frame_free(&ost->last_frame);
667 6707 av_packet_free(&ost->pkt);
668 6707 av_dict_free(&ost->encoder_opts);
669
670 6707 av_freep(&ost->kf.pts);
671 6707 av_expr_free(ost->kf.pexpr);
672
673 6707 av_freep(&ost->avfilter);
674 6707 av_freep(&ost->logfile_prefix);
675 6707 av_freep(&ost->apad);
676
677 #if FFMPEG_OPT_MAP_CHANNEL
678 6707 av_freep(&ost->audio_channels_map);
679 6707 ost->audio_channels_mapped = 0;
680 #endif
681
682 6707 av_dict_free(&ost->sws_dict);
683 6707 av_dict_free(&ost->swr_opts);
684
685
2/2
✓ Branch 0 taken 6222 times.
✓ Branch 1 taken 485 times.
6707 if (ost->enc_ctx)
686 6222 av_freep(&ost->enc_ctx->stats_in);
687 6707 avcodec_free_context(&ost->enc_ctx);
688
689 6707 av_freep(post);
690 }
691
692 6462 static void fc_close(AVFormatContext **pfc)
693 {
694 6462 AVFormatContext *fc = *pfc;
695
696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (!fc)
697 return;
698
699
2/2
✓ Branch 0 taken 6376 times.
✓ Branch 1 taken 86 times.
6462 if (!(fc->oformat->flags & AVFMT_NOFILE))
700 6376 avio_closep(&fc->pb);
701 6462 avformat_free_context(fc);
702
703 6462 *pfc = NULL;
704 }
705
706 6462 void of_close(OutputFile **pof)
707 {
708 6462 OutputFile *of = *pof;
709 Muxer *mux;
710
711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6462 times.
6462 if (!of)
712 return;
713 6462 mux = mux_from_of(of);
714
715 6462 thread_stop(mux);
716
717 6462 sq_free(&of->sq_encode);
718 6462 sq_free(&mux->sq_mux);
719
720
2/2
✓ Branch 0 taken 6707 times.
✓ Branch 1 taken 6462 times.
13169 for (int i = 0; i < of->nb_streams; i++)
721 6707 ost_free(&of->streams[i]);
722 6462 av_freep(&of->streams);
723
724 6462 av_dict_free(&mux->opts);
725
726 6462 av_packet_free(&mux->sq_pkt);
727
728 6462 fc_close(&mux->fc);
729
730 6462 av_freep(pof);
731 }
732
733 467417 int64_t of_filesize(OutputFile *of)
734 {
735 467417 Muxer *mux = mux_from_of(of);
736 467417 return atomic_load(&mux->last_filesize);
737 }
738