FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2025-01-20 09:27:23
Exec Total Coverage
Lines: 314 455 69.0%
Functions: 19 25 76.0%
Branches: 194 306 63.4%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2003 Fabrice Bellard
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * multimedia converter based on the FFmpeg libraries
24 */
25
26 #include "config.h"
27
28 #include <errno.h>
29 #include <limits.h>
30 #include <stdatomic.h>
31 #include <stdint.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35
36 #if HAVE_IO_H
37 #include <io.h>
38 #endif
39 #if HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 #if HAVE_SYS_RESOURCE_H
44 #include <sys/time.h>
45 #include <sys/types.h>
46 #include <sys/resource.h>
47 #elif HAVE_GETPROCESSTIMES
48 #include <windows.h>
49 #endif
50 #if HAVE_GETPROCESSMEMORYINFO
51 #include <windows.h>
52 #include <psapi.h>
53 #endif
54 #if HAVE_SETCONSOLECTRLHANDLER
55 #include <windows.h>
56 #endif
57
58 #if HAVE_SYS_SELECT_H
59 #include <sys/select.h>
60 #endif
61
62 #if HAVE_TERMIOS_H
63 #include <fcntl.h>
64 #include <sys/ioctl.h>
65 #include <sys/time.h>
66 #include <termios.h>
67 #elif HAVE_KBHIT
68 #include <conio.h>
69 #endif
70
71 #include "libavutil/bprint.h"
72 #include "libavutil/dict.h"
73 #include "libavutil/mem.h"
74 #include "libavutil/time.h"
75
76 #include "libavformat/avformat.h"
77
78 #include "libavdevice/avdevice.h"
79
80 #include "cmdutils.h"
81 #include "ffmpeg.h"
82 #include "ffmpeg_sched.h"
83 #include "ffmpeg_utils.h"
84
85 const char program_name[] = "ffmpeg";
86 const int program_birth_year = 2000;
87
88 FILE *vstats_file;
89
90 typedef struct BenchmarkTimeStamps {
91 int64_t real_usec;
92 int64_t user_usec;
93 int64_t sys_usec;
94 } BenchmarkTimeStamps;
95
96 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
97 static int64_t getmaxrss(void);
98
99 atomic_uint nb_output_dumped = 0;
100
101 static BenchmarkTimeStamps current_time;
102 AVIOContext *progress_avio = NULL;
103
104 InputFile **input_files = NULL;
105 int nb_input_files = 0;
106
107 OutputFile **output_files = NULL;
108 int nb_output_files = 0;
109
110 FilterGraph **filtergraphs;
111 int nb_filtergraphs;
112
113 Decoder **decoders;
114 int nb_decoders;
115
116 #if HAVE_TERMIOS_H
117
118 /* init terminal so that we can grab keys */
119 static struct termios oldtty;
120 static int restore_tty;
121 #endif
122
123 15847 static void term_exit_sigsafe(void)
124 {
125 #if HAVE_TERMIOS_H
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15847 times.
15847 if(restore_tty)
127 tcsetattr (0, TCSANOW, &oldtty);
128 #endif
129 15847 }
130
131 15847 void term_exit(void)
132 {
133 15847 av_log(NULL, AV_LOG_QUIET, "%s", "");
134 15847 term_exit_sigsafe();
135 15847 }
136
137 static volatile int received_sigterm = 0;
138 static volatile int received_nb_signals = 0;
139 static atomic_int transcode_init_done = 0;
140 static volatile int ffmpeg_exited = 0;
141 static int64_t copy_ts_first_pts = AV_NOPTS_VALUE;
142
143 static void
144 sigterm_handler(int sig)
145 {
146 int ret;
147 received_sigterm = sig;
148 received_nb_signals++;
149 term_exit_sigsafe();
150 if(received_nb_signals > 3) {
151 ret = write(2/*STDERR_FILENO*/, "Received > 3 system signals, hard exiting\n",
152 strlen("Received > 3 system signals, hard exiting\n"));
153 if (ret < 0) { /* Do nothing */ };
154 exit(123);
155 }
156 }
157
158 #if HAVE_SETCONSOLECTRLHANDLER
159 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
160 {
161 av_log(NULL, AV_LOG_DEBUG, "\nReceived windows signal %ld\n", fdwCtrlType);
162
163 switch (fdwCtrlType)
164 {
165 case CTRL_C_EVENT:
166 case CTRL_BREAK_EVENT:
167 sigterm_handler(SIGINT);
168 return TRUE;
169
170 case CTRL_CLOSE_EVENT:
171 case CTRL_LOGOFF_EVENT:
172 case CTRL_SHUTDOWN_EVENT:
173 sigterm_handler(SIGTERM);
174 /* Basically, with these 3 events, when we return from this method the
175 process is hard terminated, so stall as long as we need to
176 to try and let the main thread(s) clean up and gracefully terminate
177 (we have at most 5 seconds, but should be done far before that). */
178 while (!ffmpeg_exited) {
179 Sleep(0);
180 }
181 return TRUE;
182
183 default:
184 av_log(NULL, AV_LOG_ERROR, "Received unknown windows signal %ld\n", fdwCtrlType);
185 return FALSE;
186 }
187 }
188 #endif
189
190 #ifdef __linux__
191 #define SIGNAL(sig, func) \
192 do { \
193 action.sa_handler = func; \
194 sigaction(sig, &action, NULL); \
195 } while (0)
196 #else
197 #define SIGNAL(sig, func) \
198 signal(sig, func)
199 #endif
200
201 7923 void term_init(void)
202 {
203 #if defined __linux__
204 7923 struct sigaction action = {0};
205 7923 action.sa_handler = sigterm_handler;
206
207 /* block other interrupts while processing this one */
208 7923 sigfillset(&action.sa_mask);
209
210 /* restart interruptible functions (i.e. don't fail with EINTR) */
211 7923 action.sa_flags = SA_RESTART;
212 #endif
213
214 #if HAVE_TERMIOS_H
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7923 times.
7923 if (stdin_interaction) {
216 struct termios tty;
217 if (tcgetattr (0, &tty) == 0) {
218 oldtty = tty;
219 restore_tty = 1;
220
221 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
222 |INLCR|IGNCR|ICRNL|IXON);
223 tty.c_oflag |= OPOST;
224 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
225 tty.c_cflag &= ~(CSIZE|PARENB);
226 tty.c_cflag |= CS8;
227 tty.c_cc[VMIN] = 1;
228 tty.c_cc[VTIME] = 0;
229
230 tcsetattr (0, TCSANOW, &tty);
231 }
232 SIGNAL(SIGQUIT, sigterm_handler); /* Quit (POSIX). */
233 }
234 #endif
235
236 7923 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
237 7923 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
238 #ifdef SIGXCPU
239 7923 SIGNAL(SIGXCPU, sigterm_handler);
240 #endif
241 #ifdef SIGPIPE
242 7923 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
243 #endif
244 #if HAVE_SETCONSOLECTRLHANDLER
245 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
246 #endif
247 7923 }
248
249 /* read a key without blocking */
250 static int read_key(void)
251 {
252 unsigned char ch;
253 #if HAVE_TERMIOS_H
254 int n = 1;
255 struct timeval tv;
256 fd_set rfds;
257
258 FD_ZERO(&rfds);
259 FD_SET(0, &rfds);
260 tv.tv_sec = 0;
261 tv.tv_usec = 0;
262 n = select(1, &rfds, NULL, NULL, &tv);
263 if (n > 0) {
264 n = read(0, &ch, 1);
265 if (n == 1)
266 return ch;
267
268 return n;
269 }
270 #elif HAVE_KBHIT
271 # if HAVE_PEEKNAMEDPIPE && HAVE_GETSTDHANDLE
272 static int is_pipe;
273 static HANDLE input_handle;
274 DWORD dw, nchars;
275 if(!input_handle){
276 input_handle = GetStdHandle(STD_INPUT_HANDLE);
277 is_pipe = !GetConsoleMode(input_handle, &dw);
278 }
279
280 if (is_pipe) {
281 /* When running under a GUI, you will end here. */
282 if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL)) {
283 // input pipe may have been closed by the program that ran ffmpeg
284 return -1;
285 }
286 //Read it
287 if(nchars != 0) {
288 if (read(0, &ch, 1) == 1)
289 return ch;
290 return 0;
291 }else{
292 return -1;
293 }
294 }
295 # endif
296 if(kbhit())
297 return(getch());
298 #endif
299 return -1;
300 }
301
302 769418 static int decode_interrupt_cb(void *ctx)
303 {
304 769418 return received_nb_signals > atomic_load(&transcode_init_done);
305 }
306
307 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
308
309 7924 static void ffmpeg_cleanup(int ret)
310 {
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 if (do_benchmark) {
312 int64_t maxrss = getmaxrss() / 1024;
313 av_log(NULL, AV_LOG_INFO, "bench: maxrss=%"PRId64"KiB\n", maxrss);
314 }
315
316
2/2
✓ Branch 0 taken 904 times.
✓ Branch 1 taken 7924 times.
8828 for (int i = 0; i < nb_filtergraphs; i++)
317 904 fg_free(&filtergraphs[i]);
318 7924 av_freep(&filtergraphs);
319
320
2/2
✓ Branch 0 taken 7925 times.
✓ Branch 1 taken 7924 times.
15849 for (int i = 0; i < nb_output_files; i++)
321 7925 of_free(&output_files[i]);
322
323
2/2
✓ Branch 0 taken 7172 times.
✓ Branch 1 taken 7924 times.
15096 for (int i = 0; i < nb_input_files; i++)
324 7172 ifile_close(&input_files[i]);
325
326
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7924 times.
7925 for (int i = 0; i < nb_decoders; i++)
327 1 dec_free(&decoders[i]);
328 7924 av_freep(&decoders);
329
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 if (vstats_file) {
331 if (fclose(vstats_file))
332 av_log(NULL, AV_LOG_ERROR,
333 "Error closing vstats file, loss of information possible: %s\n",
334 av_err2str(AVERROR(errno)));
335 }
336 7924 av_freep(&vstats_filename);
337 7924 of_enc_stats_close();
338
339 7924 hw_device_free_all();
340
341 7924 av_freep(&filter_nbthreads);
342
343 7924 av_freep(&input_files);
344 7924 av_freep(&output_files);
345
346 7924 uninit_opts();
347
348 7924 avformat_network_deinit();
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 if (received_sigterm) {
351 av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n",
352 (int) received_sigterm);
353
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7923 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
7924 } else if (ret && atomic_load(&transcode_init_done)) {
354 1 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
355 }
356 7924 term_exit();
357 7924 ffmpeg_exited = 1;
358 7924 }
359
360 32695 OutputStream *ost_iter(OutputStream *prev)
361 {
362
2/2
✓ Branch 0 taken 16827 times.
✓ Branch 1 taken 15868 times.
32695 int of_idx = prev ? prev->file->index : 0;
363
2/2
✓ Branch 0 taken 16827 times.
✓ Branch 1 taken 15868 times.
32695 int ost_idx = prev ? prev->index + 1 : 0;
364
365
2/2
✓ Branch 0 taken 32699 times.
✓ Branch 1 taken 15868 times.
48567 for (; of_idx < nb_output_files; of_idx++) {
366 32699 OutputFile *of = output_files[of_idx];
367
2/2
✓ Branch 0 taken 16827 times.
✓ Branch 1 taken 15872 times.
32699 if (ost_idx < of->nb_streams)
368 16827 return of->streams[ost_idx];
369
370 15872 ost_idx = 0;
371 }
372
373 15868 return NULL;
374 }
375
376 15830 InputStream *ist_iter(InputStream *prev)
377 {
378
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 8046 times.
15830 int if_idx = prev ? prev->file->index : 0;
379
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 8046 times.
15830 int ist_idx = prev ? prev->index + 1 : 0;
380
381
2/2
✓ Branch 0 taken 15099 times.
✓ Branch 1 taken 7943 times.
23042 for (; if_idx < nb_input_files; if_idx++) {
382 15099 InputFile *f = input_files[if_idx];
383
2/2
✓ Branch 0 taken 7887 times.
✓ Branch 1 taken 7212 times.
15099 if (ist_idx < f->nb_streams)
384 7887 return f->streams[ist_idx];
385
386 7212 ist_idx = 0;
387 }
388
389 7943 return NULL;
390 }
391
392 1413362 static void frame_data_free(void *opaque, uint8_t *data)
393 {
394 1413362 FrameData *fd = (FrameData *)data;
395
396 1413362 avcodec_parameters_free(&fd->par_enc);
397
398 1413362 av_free(data);
399 1413362 }
400
401 2851600 static int frame_data_ensure(AVBufferRef **dst, int writable)
402 {
403 2851600 AVBufferRef *src = *dst;
404
405
6/6
✓ Branch 0 taken 2352288 times.
✓ Branch 1 taken 499312 times.
✓ Branch 2 taken 2345553 times.
✓ Branch 3 taken 6735 times.
✓ Branch 5 taken 914050 times.
✓ Branch 6 taken 1431503 times.
2851600 if (!src || (writable && !av_buffer_is_writable(src))) {
406 FrameData *fd;
407
408 1413362 fd = av_mallocz(sizeof(*fd));
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1413362 times.
1413362 if (!fd)
410 return AVERROR(ENOMEM);
411
412 1413362 *dst = av_buffer_create((uint8_t *)fd, sizeof(*fd),
413 frame_data_free, NULL, 0);
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1413362 times.
1413362 if (!*dst) {
415 av_buffer_unref(&src);
416 av_freep(&fd);
417 return AVERROR(ENOMEM);
418 }
419
420
2/2
✓ Branch 0 taken 914050 times.
✓ Branch 1 taken 499312 times.
1413362 if (src) {
421 914050 const FrameData *fd_src = (const FrameData *)src->data;
422
423 914050 memcpy(fd, fd_src, sizeof(*fd));
424 914050 fd->par_enc = NULL;
425
426
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 914049 times.
914050 if (fd_src->par_enc) {
427 1 int ret = 0;
428
429 1 fd->par_enc = avcodec_parameters_alloc();
430 2 ret = fd->par_enc ?
431
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 avcodec_parameters_copy(fd->par_enc, fd_src->par_enc) :
432 AVERROR(ENOMEM);
433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0) {
434 av_buffer_unref(dst);
435 av_buffer_unref(&src);
436 return ret;
437 }
438 }
439
440 914050 av_buffer_unref(&src);
441 } else {
442 499312 fd->dec.frame_num = UINT64_MAX;
443 499312 fd->dec.pts = AV_NOPTS_VALUE;
444
445
2/2
✓ Branch 0 taken 3495184 times.
✓ Branch 1 taken 499312 times.
3994496 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
446 3495184 fd->wallclock[i] = INT64_MIN;
447 }
448 }
449
450 2851600 return 0;
451 }
452
453 1575449 FrameData *frame_data(AVFrame *frame)
454 {
455 1575449 int ret = frame_data_ensure(&frame->opaque_ref, 1);
456
1/2
✓ Branch 0 taken 1575449 times.
✗ Branch 1 not taken.
1575449 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
457 }
458
459 7668 const FrameData *frame_data_c(AVFrame *frame)
460 {
461 7668 int ret = frame_data_ensure(&frame->opaque_ref, 0);
462
1/2
✓ Branch 0 taken 7668 times.
✗ Branch 1 not taken.
7668 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
463 }
464
465 1268483 FrameData *packet_data(AVPacket *pkt)
466 {
467 1268483 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
468
1/2
✓ Branch 0 taken 1268483 times.
✗ Branch 1 not taken.
1268483 return ret < 0 ? NULL : (FrameData*)pkt->opaque_ref->data;
469 }
470
471 const FrameData *packet_data_c(AVPacket *pkt)
472 {
473 int ret = frame_data_ensure(&pkt->opaque_ref, 0);
474 return ret < 0 ? NULL : (const FrameData*)pkt->opaque_ref->data;
475 }
476
477 15097 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
478 void *logctx, int decode)
479 {
480 15097 const AVClass *class = avcodec_get_class();
481 15097 const AVClass *fclass = avformat_get_class();
482
483
2/2
✓ Branch 0 taken 7172 times.
✓ Branch 1 taken 7925 times.
15097 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
484 AV_OPT_FLAG_ENCODING_PARAM;
485 15097 const AVDictionaryEntry *e = NULL;
486
487
2/2
✓ Branch 1 taken 46032 times.
✓ Branch 2 taken 15097 times.
61129 while ((e = av_dict_iterate(opts, e))) {
488 const AVOption *option, *foption;
489 char *optname, *p;
490
491
2/2
✓ Branch 1 taken 45223 times.
✓ Branch 2 taken 809 times.
46032 if (av_dict_get(opts_used, e->key, NULL, 0))
492 45224 continue;
493
494 809 optname = av_strdup(e->key);
495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 809 times.
809 if (!optname)
496 return AVERROR(ENOMEM);
497
498 809 p = strchr(optname, ':');
499
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 798 times.
809 if (p)
500 11 *p = 0;
501
502 809 option = av_opt_find(&class, optname, NULL, 0,
503 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
504 809 foption = av_opt_find(&fclass, optname, NULL, 0,
505 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
506 809 av_freep(&optname);
507
3/4
✓ Branch 0 taken 809 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 808 times.
809 if (!option || foption)
508 1 continue;
509
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 808 times.
808 if (!(option->flags & flag)) {
511 av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s "
512 "option.\n", e->key, option->help ? option->help : "",
513 decode ? "decoding" : "encoding");
514 return AVERROR(EINVAL);
515 }
516
517 808 av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
518 "for any stream. The most likely reason is either wrong type "
519 "(e.g. a video option with no video streams) or that it is a "
520 "private option of some decoder which was not actually used "
521
2/2
✓ Branch 0 taken 804 times.
✓ Branch 1 taken 4 times.
1616 "for any stream.\n", e->key, option->help ? option->help : "");
522 }
523
524 15097 return 0;
525 }
526
527 2836151 void update_benchmark(const char *fmt, ...)
528 {
529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2836151 times.
2836151 if (do_benchmark_all) {
530 BenchmarkTimeStamps t = get_benchmark_time_stamps();
531 va_list va;
532 char buf[1024];
533
534 if (fmt) {
535 va_start(va, fmt);
536 vsnprintf(buf, sizeof(buf), fmt, va);
537 va_end(va);
538 av_log(NULL, AV_LOG_INFO,
539 "bench: %8" PRIu64 " user %8" PRIu64 " sys %8" PRIu64 " real %s \n",
540 t.user_usec - current_time.user_usec,
541 t.sys_usec - current_time.sys_usec,
542 t.real_usec - current_time.real_usec, buf);
543 }
544 current_time = t;
545 }
546 2836151 }
547
548 24572 static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts)
549 {
550 AVBPrint buf, buf_script;
551 24572 int64_t total_size = of_filesize(output_files[0]);
552 int vid;
553 double bitrate;
554 double speed;
555 static int64_t last_time = -1;
556 static int first_report = 1;
557 24572 uint64_t nb_frames_dup = 0, nb_frames_drop = 0;
558 int mins, secs, us;
559 int64_t hours;
560 const char *hours_sign;
561 int ret;
562 float t;
563
564
5/6
✓ Branch 0 taken 24523 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 16627 times.
✓ Branch 3 taken 7896 times.
✓ Branch 4 taken 16627 times.
✗ Branch 5 not taken.
24572 if (!print_stats && !is_last_report && !progress_avio)
565 16627 return;
566
567
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 7923 times.
7945 if (!is_last_report) {
568
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (last_time == -1) {
569 11 last_time = cur_time;
570 }
571
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 if (((cur_time - last_time) < stats_period && !first_report) ||
572
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
22 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
573 return;
574 22 last_time = cur_time;
575 }
576
577 7945 t = (cur_time-timer_start) / 1000000.0;
578
579 7945 vid = 0;
580 7945 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
581 7945 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
582
2/2
✓ Branch 2 taken 8425 times.
✓ Branch 3 taken 7945 times.
16370 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
583
2/2
✓ Branch 0 taken 7732 times.
✓ Branch 1 taken 693 times.
8425 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
584
585
4/4
✓ Branch 0 taken 267 times.
✓ Branch 1 taken 8158 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 196 times.
8425 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
586 71 av_bprintf(&buf, "q=%2.1f ", q);
587 71 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
588 71 ost->file->index, ost->index, q);
589 }
590
4/4
✓ Branch 0 taken 8158 times.
✓ Branch 1 taken 267 times.
✓ Branch 2 taken 6625 times.
✓ Branch 3 taken 1533 times.
8425 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
591 float fps;
592 6625 uint64_t frame_number = atomic_load(&ost->packets_written);
593
594
2/2
✓ Branch 0 taken 1672 times.
✓ Branch 1 taken 4953 times.
6625 fps = t > 1 ? frame_number / t : 0;
595 6625 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
596 frame_number, fps < 9.95, fps, q);
597 6625 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
598 6625 av_bprintf(&buf_script, "fps=%.2f\n", fps);
599 6625 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
600 6625 ost->file->index, ost->index, q);
601
2/2
✓ Branch 0 taken 6624 times.
✓ Branch 1 taken 1 times.
6625 if (is_last_report)
602 6624 av_bprintf(&buf, "L");
603
604
2/2
✓ Branch 0 taken 6325 times.
✓ Branch 1 taken 300 times.
6625 if (ost->filter) {
605 6325 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
606 6325 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
607 }
608
609 6625 vid = 1;
610 }
611 }
612
613
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7932 times.
7945 if (copy_ts) {
614
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 if (copy_ts_first_pts == AV_NOPTS_VALUE && pts > 1)
615 13 copy_ts_first_pts = pts;
616
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (copy_ts_first_pts != AV_NOPTS_VALUE)
617 13 pts -= copy_ts_first_pts;
618 }
619
620
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7822 times.
7945 us = FFABS64U(pts) % AV_TIME_BASE;
621
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7822 times.
7945 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
622
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7822 times.
7945 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
623
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7822 times.
7945 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
624
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7837 times.
7945 hours_sign = (pts < 0) ? "-" : "";
625
626
6/6
✓ Branch 0 taken 7837 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 7822 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 7710 times.
✓ Branch 5 taken 112 times.
7945 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
627
3/4
✓ Branch 0 taken 7837 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 7837 times.
✗ Branch 3 not taken.
7945 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
628
629
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 7831 times.
7945 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
630 7831 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
631
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7837 times.
7945 if (pts == AV_NOPTS_VALUE) {
632 108 av_bprintf(&buf, "N/A ");
633 } else {
634 7837 av_bprintf(&buf, "%s%02"PRId64":%02d:%02d.%02d ",
635 hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
636 }
637
638
2/2
✓ Branch 0 taken 235 times.
✓ Branch 1 taken 7710 times.
7945 if (bitrate < 0) {
639 235 av_bprintf(&buf, "bitrate=N/A");
640 235 av_bprintf(&buf_script, "bitrate=N/A\n");
641 }else{
642 7710 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
643 7710 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
644 }
645
646
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 7831 times.
7945 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
647 7831 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
648
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7837 times.
7945 if (pts == AV_NOPTS_VALUE) {
649 108 av_bprintf(&buf_script, "out_time_us=N/A\n");
650 108 av_bprintf(&buf_script, "out_time_ms=N/A\n");
651 108 av_bprintf(&buf_script, "out_time=N/A\n");
652 } else {
653 7837 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
654 7837 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
655 7837 av_bprintf(&buf_script, "out_time=%s%02"PRId64":%02d:%02d.%06d\n",
656 hours_sign, hours, mins, secs, us);
657 }
658
659
4/4
✓ Branch 0 taken 7929 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 7922 times.
7945 if (nb_frames_dup || nb_frames_drop)
660 23 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
661 7945 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
662 7945 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
663
664
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7837 times.
7945 if (speed < 0) {
665 108 av_bprintf(&buf, " speed=N/A");
666 108 av_bprintf(&buf_script, "speed=N/A\n");
667 } else {
668 7837 av_bprintf(&buf, " speed=%4.3gx", speed);
669 7837 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
670 }
671
672
3/4
✓ Branch 0 taken 7896 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 7896 times.
✗ Branch 3 not taken.
7945 if (print_stats || is_last_report) {
673
2/2
✓ Branch 0 taken 7923 times.
✓ Branch 1 taken 22 times.
7945 const char end = is_last_report ? '\n' : '\r';
674
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7945 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
7945 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
675 fprintf(stderr, "%s %c", buf.str, end);
676 } else
677 7945 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
678
679 7945 fflush(stderr);
680 }
681 7945 av_bprint_finalize(&buf, NULL);
682
683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7945 times.
7945 if (progress_avio) {
684 av_bprintf(&buf_script, "progress=%s\n",
685 is_last_report ? "end" : "continue");
686 avio_write(progress_avio, buf_script.str,
687 FFMIN(buf_script.len, buf_script.size - 1));
688 avio_flush(progress_avio);
689 av_bprint_finalize(&buf_script, NULL);
690 if (is_last_report) {
691 if ((ret = avio_closep(&progress_avio)) < 0)
692 av_log(NULL, AV_LOG_ERROR,
693 "Error closing progress log, loss of information possible: %s\n", av_err2str(ret));
694 }
695 }
696
697 7945 first_report = 0;
698 }
699
700 7923 static void print_stream_maps(void)
701 {
702 7923 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
703
2/2
✓ Branch 2 taken 7731 times.
✓ Branch 3 taken 7923 times.
15654 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
704
2/2
✓ Branch 0 taken 6785 times.
✓ Branch 1 taken 7731 times.
14516 for (int j = 0; j < ist->nb_filters; j++) {
705
2/2
✓ Branch 1 taken 148 times.
✓ Branch 2 taken 6637 times.
6785 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
706 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
707 148 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
708
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 ist->filters[j]->name);
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
148 if (nb_filtergraphs > 1)
710 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
711 148 av_log(NULL, AV_LOG_INFO, "\n");
712 }
713 }
714 }
715
716
2/2
✓ Branch 2 taken 8402 times.
✓ Branch 3 taken 7923 times.
16325 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
717
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8401 times.
8402 if (ost->attachment_filename) {
718 /* an attached file */
719 1 av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
720 1 ost->attachment_filename, ost->file->index, ost->index);
721 1 continue;
722 }
723
724
4/4
✓ Branch 0 taken 7671 times.
✓ Branch 1 taken 730 times.
✓ Branch 3 taken 1034 times.
✓ Branch 4 taken 6637 times.
8401 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
725 /* output from a complex graph */
726 1034 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
1034 if (nb_filtergraphs > 1)
728 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
729
730 1034 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
731 1034 ost->index, ost->enc->enc_ctx->codec->name);
732 1034 continue;
733 }
734
735 7367 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
736 7367 ost->ist->file->index,
737 7367 ost->ist->index,
738 7367 ost->file->index,
739 ost->index);
740
2/2
✓ Branch 0 taken 6675 times.
✓ Branch 1 taken 692 times.
7367 if (ost->enc) {
741 6675 const AVCodec *in_codec = ost->ist->dec;
742 6675 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
743 6675 const char *decoder_name = "?";
744 6675 const char *in_codec_name = "?";
745 6675 const char *encoder_name = "?";
746 6675 const char *out_codec_name = "?";
747 const AVCodecDescriptor *desc;
748
749
1/2
✓ Branch 0 taken 6675 times.
✗ Branch 1 not taken.
6675 if (in_codec) {
750 6675 decoder_name = in_codec->name;
751 6675 desc = avcodec_descriptor_get(in_codec->id);
752
1/2
✓ Branch 0 taken 6675 times.
✗ Branch 1 not taken.
6675 if (desc)
753 6675 in_codec_name = desc->name;
754
2/2
✓ Branch 0 taken 6509 times.
✓ Branch 1 taken 166 times.
6675 if (!strcmp(decoder_name, in_codec_name))
755 6509 decoder_name = "native";
756 }
757
758
1/2
✓ Branch 0 taken 6675 times.
✗ Branch 1 not taken.
6675 if (out_codec) {
759 6675 encoder_name = out_codec->name;
760 6675 desc = avcodec_descriptor_get(out_codec->id);
761
1/2
✓ Branch 0 taken 6675 times.
✗ Branch 1 not taken.
6675 if (desc)
762 6675 out_codec_name = desc->name;
763
2/2
✓ Branch 0 taken 6566 times.
✓ Branch 1 taken 109 times.
6675 if (!strcmp(encoder_name, out_codec_name))
764 6566 encoder_name = "native";
765 }
766
767 6675 av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))",
768 in_codec_name, decoder_name,
769 out_codec_name, encoder_name);
770 } else
771 692 av_log(NULL, AV_LOG_INFO, " (copy)");
772 7367 av_log(NULL, AV_LOG_INFO, "\n");
773 }
774 7923 }
775
776 static void set_tty_echo(int on)
777 {
778 #if HAVE_TERMIOS_H
779 struct termios tty;
780 if (tcgetattr(0, &tty) == 0) {
781 if (on) tty.c_lflag |= ECHO;
782 else tty.c_lflag &= ~ECHO;
783 tcsetattr(0, TCSANOW, &tty);
784 }
785 #endif
786 }
787
788 static int check_keyboard_interaction(int64_t cur_time)
789 {
790 int i, key;
791 static int64_t last_time;
792 if (received_nb_signals)
793 return AVERROR_EXIT;
794 /* read_key() returns 0 on EOF */
795 if (cur_time - last_time >= 100000) {
796 key = read_key();
797 last_time = cur_time;
798 }else
799 key = -1;
800 if (key == 'q') {
801 av_log(NULL, AV_LOG_INFO, "\n\n[q] command received. Exiting.\n\n");
802 return AVERROR_EXIT;
803 }
804 if (key == '+') av_log_set_level(av_log_get_level()+10);
805 if (key == '-') av_log_set_level(av_log_get_level()-10);
806 if (key == 'c' || key == 'C'){
807 char buf[4096], target[64], command[256], arg[256] = {0};
808 double time;
809 int k, n = 0;
810 fprintf(stderr, "\nEnter command: <target>|all <time>|-1 <command>[ <argument>]\n");
811 i = 0;
812 set_tty_echo(1);
813 while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
814 if (k > 0)
815 buf[i++] = k;
816 buf[i] = 0;
817 set_tty_echo(0);
818 fprintf(stderr, "\n");
819 if (k > 0 &&
820 (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
821 av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
822 target, time, command, arg);
823 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
824 if (ost->fg_simple)
825 fg_send_command(ost->fg_simple, time, target, command, arg,
826 key == 'C');
827 }
828 for (i = 0; i < nb_filtergraphs; i++)
829 fg_send_command(filtergraphs[i], time, target, command, arg,
830 key == 'C');
831 } else {
832 av_log(NULL, AV_LOG_ERROR,
833 "Parse error, at least 3 arguments were expected, "
834 "only %d given in string '%s'\n", n, buf);
835 }
836 }
837 if (key == '?'){
838 fprintf(stderr, "key function\n"
839 "? show this help\n"
840 "+ increase verbosity\n"
841 "- decrease verbosity\n"
842 "c Send command to first matching filter supporting it\n"
843 "C Send/Queue command to all matching filters\n"
844 "h dump packets/hex press to cycle through the 3 states\n"
845 "q quit\n"
846 "s Show QP histogram\n"
847 );
848 }
849 return 0;
850 }
851
852 /*
853 * The following code is the main loop of the file converter
854 */
855 7923 static int transcode(Scheduler *sch)
856 {
857 7923 int ret = 0;
858 7923 int64_t timer_start, transcode_ts = 0;
859
860 7923 print_stream_maps();
861
862 7923 atomic_store(&transcode_init_done, 1);
863
864 7923 ret = sch_start(sch);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7923 times.
7923 if (ret < 0)
866 return ret;
867
868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7923 times.
7923 if (stdin_interaction) {
869 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
870 }
871
872 7923 timer_start = av_gettime_relative();
873
874
2/2
✓ Branch 1 taken 16649 times.
✓ Branch 2 taken 7923 times.
24572 while (!sch_wait(sch, stats_period, &transcode_ts)) {
875 16649 int64_t cur_time= av_gettime_relative();
876
877 /* if 'q' pressed, exits */
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16649 times.
16649 if (stdin_interaction)
879 if (check_keyboard_interaction(cur_time) < 0)
880 break;
881
882 /* dump report by using the output first video and audio streams */
883 16649 print_report(0, timer_start, cur_time, transcode_ts);
884 }
885
886 7923 ret = sch_stop(sch, &transcode_ts);
887
888 /* write the trailer if needed */
889
2/2
✓ Branch 0 taken 7925 times.
✓ Branch 1 taken 7923 times.
15848 for (int i = 0; i < nb_output_files; i++) {
890 7925 int err = of_write_trailer(output_files[i]);
891 7925 ret = err_merge(ret, err);
892 }
893
894 7923 term_exit();
895
896 /* dump report by using the first video and audio streams */
897 7923 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
898
899 7923 return ret;
900 }
901
902 7923 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
903 {
904 7923 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
905 #if HAVE_GETRUSAGE
906 struct rusage rusage;
907
908 7923 getrusage(RUSAGE_SELF, &rusage);
909 7923 time_stamps.user_usec =
910 7923 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
911 7923 time_stamps.sys_usec =
912 7923 (rusage.ru_stime.tv_sec * 1000000LL) + rusage.ru_stime.tv_usec;
913 #elif HAVE_GETPROCESSTIMES
914 HANDLE proc;
915 FILETIME c, e, k, u;
916 proc = GetCurrentProcess();
917 GetProcessTimes(proc, &c, &e, &k, &u);
918 time_stamps.user_usec =
919 ((int64_t)u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
920 time_stamps.sys_usec =
921 ((int64_t)k.dwHighDateTime << 32 | k.dwLowDateTime) / 10;
922 #else
923 time_stamps.user_usec = time_stamps.sys_usec = 0;
924 #endif
925 7923 return time_stamps;
926 }
927
928 static int64_t getmaxrss(void)
929 {
930 #if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
931 struct rusage rusage;
932 getrusage(RUSAGE_SELF, &rusage);
933 return (int64_t)rusage.ru_maxrss * 1024;
934 #elif HAVE_GETPROCESSMEMORYINFO
935 HANDLE proc;
936 PROCESS_MEMORY_COUNTERS memcounters;
937 proc = GetCurrentProcess();
938 memcounters.cb = sizeof(memcounters);
939 GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
940 return memcounters.PeakPagefileUsage;
941 #else
942 return 0;
943 #endif
944 }
945
946 7924 int main(int argc, char **argv)
947 {
948 7924 Scheduler *sch = NULL;
949
950 int ret;
951 BenchmarkTimeStamps ti;
952
953 7924 init_dynload();
954
955 7924 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
956
957 7924 av_log_set_flags(AV_LOG_SKIP_REPEATED);
958 7924 parse_loglevel(argc, argv, options);
959
960 #if CONFIG_AVDEVICE
961 7924 avdevice_register_all();
962 #endif
963 7924 avformat_network_init();
964
965 7924 show_banner(argc, argv, options);
966
967 7924 sch = sch_alloc();
968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 if (!sch) {
969 ret = AVERROR(ENOMEM);
970 goto finish;
971 }
972
973 /* parse options and open all input/output files */
974 7924 ret = ffmpeg_parse_options(argc, argv, sch);
975
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7923 times.
7924 if (ret < 0)
976 1 goto finish;
977
978
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7923 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7923 if (nb_output_files <= 0 && nb_input_files == 0) {
979 show_usage();
980 av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
981 ret = 1;
982 goto finish;
983 }
984
985
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7923 times.
7923 if (nb_output_files <= 0) {
986 av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
987 ret = 1;
988 goto finish;
989 }
990
991 7923 current_time = ti = get_benchmark_time_stamps();
992 7923 ret = transcode(sch);
993
3/4
✓ Branch 0 taken 7922 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7922 times.
7923 if (ret >= 0 && do_benchmark) {
994 int64_t utime, stime, rtime;
995 current_time = get_benchmark_time_stamps();
996 utime = current_time.user_usec - ti.user_usec;
997 stime = current_time.sys_usec - ti.sys_usec;
998 rtime = current_time.real_usec - ti.real_usec;
999 av_log(NULL, AV_LOG_INFO,
1000 "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
1001 utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
1002 }
1003
1004
1/2
✓ Branch 0 taken 7923 times.
✗ Branch 1 not taken.
15846 ret = received_nb_signals ? 255 :
1005
2/2
✓ Branch 0 taken 7922 times.
✓ Branch 1 taken 1 times.
7923 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1006
1007 7924 finish:
1008
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7923 times.
7924 if (ret == AVERROR_EXIT)
1009 1 ret = 0;
1010
1011 7924 ffmpeg_cleanup(ret);
1012
1013 7924 sch_free(&sch);
1014
1015 7924 return ret;
1016 }
1017