FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2025-03-08 20:38:41
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 15849 static void term_exit_sigsafe(void)
124 {
125 #if HAVE_TERMIOS_H
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15849 times.
15849 if(restore_tty)
127 tcsetattr (0, TCSANOW, &oldtty);
128 #endif
129 15849 }
130
131 15849 void term_exit(void)
132 {
133 15849 av_log(NULL, AV_LOG_QUIET, "%s", "");
134 15849 term_exit_sigsafe();
135 15849 }
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 7924 void term_init(void)
202 {
203 #if defined __linux__
204 7924 struct sigaction action = {0};
205 7924 action.sa_handler = sigterm_handler;
206
207 /* block other interrupts while processing this one */
208 7924 sigfillset(&action.sa_mask);
209
210 /* restart interruptible functions (i.e. don't fail with EINTR) */
211 7924 action.sa_flags = SA_RESTART;
212 #endif
213
214 #if HAVE_TERMIOS_H
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 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 7924 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
237 7924 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
238 #ifdef SIGXCPU
239 7924 SIGNAL(SIGXCPU, sigterm_handler);
240 #endif
241 #ifdef SIGPIPE
242 7924 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
243 #endif
244 #if HAVE_SETCONSOLECTRLHANDLER
245 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
246 #endif
247 7924 }
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 769206 static int decode_interrupt_cb(void *ctx)
303 {
304 769206 return received_nb_signals > atomic_load(&transcode_init_done);
305 }
306
307 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
308
309 7925 static void ffmpeg_cleanup(int ret)
310 {
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7925 times.
7925 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 905 times.
✓ Branch 1 taken 7925 times.
8830 for (int i = 0; i < nb_filtergraphs; i++)
317 905 fg_free(&filtergraphs[i]);
318 7925 av_freep(&filtergraphs);
319
320
2/2
✓ Branch 0 taken 7926 times.
✓ Branch 1 taken 7925 times.
15851 for (int i = 0; i < nb_output_files; i++)
321 7926 of_free(&output_files[i]);
322
323
2/2
✓ Branch 0 taken 7173 times.
✓ Branch 1 taken 7925 times.
15098 for (int i = 0; i < nb_input_files; i++)
324 7173 ifile_close(&input_files[i]);
325
326
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7925 times.
7926 for (int i = 0; i < nb_decoders; i++)
327 1 dec_free(&decoders[i]);
328 7925 av_freep(&decoders);
329
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7925 times.
7925 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 7925 av_freep(&vstats_filename);
337 7925 of_enc_stats_close();
338
339 7925 hw_device_free_all();
340
341 7925 av_freep(&filter_nbthreads);
342
343 7925 av_freep(&input_files);
344 7925 av_freep(&output_files);
345
346 7925 uninit_opts();
347
348 7925 avformat_network_deinit();
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7925 times.
7925 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 7924 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
7925 } else if (ret && atomic_load(&transcode_init_done)) {
354 1 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
355 }
356 7925 term_exit();
357 7925 ffmpeg_exited = 1;
358 7925 }
359
360 32707 OutputStream *ost_iter(OutputStream *prev)
361 {
362
2/2
✓ Branch 0 taken 16833 times.
✓ Branch 1 taken 15874 times.
32707 int of_idx = prev ? prev->file->index : 0;
363
2/2
✓ Branch 0 taken 16833 times.
✓ Branch 1 taken 15874 times.
32707 int ost_idx = prev ? prev->index + 1 : 0;
364
365
2/2
✓ Branch 0 taken 32711 times.
✓ Branch 1 taken 15874 times.
48585 for (; of_idx < nb_output_files; of_idx++) {
366 32711 OutputFile *of = output_files[of_idx];
367
2/2
✓ Branch 0 taken 16833 times.
✓ Branch 1 taken 15878 times.
32711 if (ost_idx < of->nb_streams)
368 16833 return of->streams[ost_idx];
369
370 15878 ost_idx = 0;
371 }
372
373 15874 return NULL;
374 }
375
376 15832 InputStream *ist_iter(InputStream *prev)
377 {
378
2/2
✓ Branch 0 taken 7785 times.
✓ Branch 1 taken 8047 times.
15832 int if_idx = prev ? prev->file->index : 0;
379
2/2
✓ Branch 0 taken 7785 times.
✓ Branch 1 taken 8047 times.
15832 int ist_idx = prev ? prev->index + 1 : 0;
380
381
2/2
✓ Branch 0 taken 15101 times.
✓ Branch 1 taken 7944 times.
23045 for (; if_idx < nb_input_files; if_idx++) {
382 15101 InputFile *f = input_files[if_idx];
383
2/2
✓ Branch 0 taken 7888 times.
✓ Branch 1 taken 7213 times.
15101 if (ist_idx < f->nb_streams)
384 7888 return f->streams[ist_idx];
385
386 7213 ist_idx = 0;
387 }
388
389 7944 return NULL;
390 }
391
392 1412344 static void frame_data_free(void *opaque, uint8_t *data)
393 {
394 1412344 FrameData *fd = (FrameData *)data;
395
396 1412344 avcodec_parameters_free(&fd->par_enc);
397
398 1412344 av_free(data);
399 1412344 }
400
401 2848633 static int frame_data_ensure(AVBufferRef **dst, int writable)
402 {
403 2848633 AVBufferRef *src = *dst;
404
405
6/6
✓ Branch 0 taken 2349876 times.
✓ Branch 1 taken 498757 times.
✓ Branch 2 taken 2343141 times.
✓ Branch 3 taken 6735 times.
✓ Branch 5 taken 913587 times.
✓ Branch 6 taken 1429554 times.
2848633 if (!src || (writable && !av_buffer_is_writable(src))) {
406 FrameData *fd;
407
408 1412344 fd = av_mallocz(sizeof(*fd));
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1412344 times.
1412344 if (!fd)
410 return AVERROR(ENOMEM);
411
412 1412344 *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 1412344 times.
1412344 if (!*dst) {
415 av_buffer_unref(&src);
416 av_freep(&fd);
417 return AVERROR(ENOMEM);
418 }
419
420
2/2
✓ Branch 0 taken 913587 times.
✓ Branch 1 taken 498757 times.
1412344 if (src) {
421 913587 const FrameData *fd_src = (const FrameData *)src->data;
422
423 913587 memcpy(fd, fd_src, sizeof(*fd));
424 913587 fd->par_enc = NULL;
425
426
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 913585 times.
913587 if (fd_src->par_enc) {
427 2 int ret = 0;
428
429 2 fd->par_enc = avcodec_parameters_alloc();
430 4 ret = fd->par_enc ?
431
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 avcodec_parameters_copy(fd->par_enc, fd_src->par_enc) :
432 AVERROR(ENOMEM);
433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0) {
434 av_buffer_unref(dst);
435 av_buffer_unref(&src);
436 return ret;
437 }
438 }
439
440 913587 av_buffer_unref(&src);
441 } else {
442 498757 fd->dec.frame_num = UINT64_MAX;
443 498757 fd->dec.pts = AV_NOPTS_VALUE;
444
445
2/2
✓ Branch 0 taken 3491299 times.
✓ Branch 1 taken 498757 times.
3990056 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
446 3491299 fd->wallclock[i] = INT64_MIN;
447 }
448 }
449
450 2848633 return 0;
451 }
452
453 1573686 FrameData *frame_data(AVFrame *frame)
454 {
455 1573686 int ret = frame_data_ensure(&frame->opaque_ref, 1);
456
1/2
✓ Branch 0 taken 1573686 times.
✗ Branch 1 not taken.
1573686 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 1267279 FrameData *packet_data(AVPacket *pkt)
466 {
467 1267279 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
468
1/2
✓ Branch 0 taken 1267279 times.
✗ Branch 1 not taken.
1267279 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 15099 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
478 void *logctx, int decode)
479 {
480 15099 const AVClass *class = avcodec_get_class();
481 15099 const AVClass *fclass = avformat_get_class();
482
483
2/2
✓ Branch 0 taken 7173 times.
✓ Branch 1 taken 7926 times.
15099 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
484 AV_OPT_FLAG_ENCODING_PARAM;
485 15099 const AVDictionaryEntry *e = NULL;
486
487
2/2
✓ Branch 1 taken 46193 times.
✓ Branch 2 taken 15099 times.
61292 while ((e = av_dict_iterate(opts, e))) {
488 const AVOption *option, *foption;
489 char *optname, *p;
490
491
2/2
✓ Branch 1 taken 45384 times.
✓ Branch 2 taken 809 times.
46193 if (av_dict_get(opts_used, e->key, NULL, 0))
492 45385 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 15099 return 0;
525 }
526
527 2832666 void update_benchmark(const char *fmt, ...)
528 {
529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2832666 times.
2832666 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 2832666 }
547
548 24526 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 24526 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 24526 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 24473 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 16576 times.
✓ Branch 3 taken 7897 times.
✓ Branch 4 taken 16576 times.
✗ Branch 5 not taken.
24526 if (!print_stats && !is_last_report && !progress_avio)
565 16576 return;
566
567
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 7924 times.
7950 if (!is_last_report) {
568
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
26 if (last_time == -1) {
569 12 last_time = cur_time;
570 }
571
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
26 if (((cur_time - last_time) < stats_period && !first_report) ||
572
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
26 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
573 return;
574 26 last_time = cur_time;
575 }
576
577 7950 t = (cur_time-timer_start) / 1000000.0;
578
579 7950 vid = 0;
580 7950 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
581 7950 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
582
2/2
✓ Branch 2 taken 8430 times.
✓ Branch 3 taken 7950 times.
16380 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
583
2/2
✓ Branch 0 taken 7736 times.
✓ Branch 1 taken 694 times.
8430 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 8163 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 196 times.
8430 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 8163 times.
✓ Branch 1 taken 267 times.
✓ Branch 2 taken 6627 times.
✓ Branch 3 taken 1536 times.
8430 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
591 float fps;
592 6627 uint64_t frame_number = atomic_load(&ost->packets_written);
593
594
2/2
✓ Branch 0 taken 1650 times.
✓ Branch 1 taken 4977 times.
6627 fps = t > 1 ? frame_number / t : 0;
595 6627 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
596 frame_number, fps < 9.95, fps, q);
597 6627 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
598 6627 av_bprintf(&buf_script, "fps=%.2f\n", fps);
599 6627 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
600 6627 ost->file->index, ost->index, q);
601
2/2
✓ Branch 0 taken 6626 times.
✓ Branch 1 taken 1 times.
6627 if (is_last_report)
602 6626 av_bprintf(&buf, "L");
603
604
2/2
✓ Branch 0 taken 6326 times.
✓ Branch 1 taken 301 times.
6627 if (ost->filter) {
605 6326 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
606 6326 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
607 }
608
609 6627 vid = 1;
610 }
611 }
612
613
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7937 times.
7950 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 7827 times.
7950 us = FFABS64U(pts) % AV_TIME_BASE;
621
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7827 times.
7950 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
622
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7827 times.
7950 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
623
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 7827 times.
7950 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
624
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7842 times.
7950 hours_sign = (pts < 0) ? "-" : "";
625
626
6/6
✓ Branch 0 taken 7842 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 7827 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 7711 times.
✓ Branch 5 taken 116 times.
7950 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
627
3/4
✓ Branch 0 taken 7842 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 7842 times.
✗ Branch 3 not taken.
7950 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
628
629
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 7832 times.
7950 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
630 7832 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
631
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7842 times.
7950 if (pts == AV_NOPTS_VALUE) {
632 108 av_bprintf(&buf, "N/A ");
633 } else {
634 7842 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 239 times.
✓ Branch 1 taken 7711 times.
7950 if (bitrate < 0) {
639 239 av_bprintf(&buf, "bitrate=N/A");
640 239 av_bprintf(&buf_script, "bitrate=N/A\n");
641 }else{
642 7711 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
643 7711 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
644 }
645
646
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 7832 times.
7950 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
647 7832 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
648
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7842 times.
7950 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 7842 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
654 7842 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
655 7842 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 7934 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 7927 times.
7950 if (nb_frames_dup || nb_frames_drop)
660 23 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
661 7950 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
662 7950 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
663
664
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 7842 times.
7950 if (speed < 0) {
665 108 av_bprintf(&buf, " speed=N/A");
666 108 av_bprintf(&buf_script, "speed=N/A\n");
667 } else {
668 7842 av_bprintf(&buf, " speed=%4.3gx", speed);
669 7842 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
670 }
671
672
3/4
✓ Branch 0 taken 7897 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 7897 times.
✗ Branch 3 not taken.
7950 if (print_stats || is_last_report) {
673
2/2
✓ Branch 0 taken 7924 times.
✓ Branch 1 taken 26 times.
7950 const char end = is_last_report ? '\n' : '\r';
674
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7950 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
7950 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
675 fprintf(stderr, "%s %c", buf.str, end);
676 } else
677 7950 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
678
679 7950 fflush(stderr);
680 }
681 7950 av_bprint_finalize(&buf, NULL);
682
683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7950 times.
7950 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 7950 first_report = 0;
698 }
699
700 7924 static void print_stream_maps(void)
701 {
702 7924 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
703
2/2
✓ Branch 2 taken 7732 times.
✓ Branch 3 taken 7924 times.
15656 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
704
2/2
✓ Branch 0 taken 6785 times.
✓ Branch 1 taken 7732 times.
14517 for (int j = 0; j < ist->nb_filters; j++) {
705
2/2
✓ Branch 1 taken 149 times.
✓ Branch 2 taken 6636 times.
6785 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
706 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
707 149 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
708
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 ist->filters[j]->name);
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
149 if (nb_filtergraphs > 1)
710 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
711 149 av_log(NULL, AV_LOG_INFO, "\n");
712 }
713 }
714 }
715
716
2/2
✓ Branch 2 taken 8403 times.
✓ Branch 3 taken 7924 times.
16327 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
717
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8402 times.
8403 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 731 times.
✓ Branch 3 taken 1035 times.
✓ Branch 4 taken 6636 times.
8402 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
725 /* output from a complex graph */
726 1035 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1035 times.
1035 if (nb_filtergraphs > 1)
728 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
729
730 1035 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
731 1035 ost->index, ost->enc->enc_ctx->codec->name);
732 1035 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 6674 times.
✓ Branch 1 taken 693 times.
7367 if (ost->enc) {
741 6674 const AVCodec *in_codec = ost->ist->dec;
742 6674 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
743 6674 const char *decoder_name = "?";
744 6674 const char *in_codec_name = "?";
745 6674 const char *encoder_name = "?";
746 6674 const char *out_codec_name = "?";
747 const AVCodecDescriptor *desc;
748
749
1/2
✓ Branch 0 taken 6674 times.
✗ Branch 1 not taken.
6674 if (in_codec) {
750 6674 decoder_name = in_codec->name;
751 6674 desc = avcodec_descriptor_get(in_codec->id);
752
1/2
✓ Branch 0 taken 6674 times.
✗ Branch 1 not taken.
6674 if (desc)
753 6674 in_codec_name = desc->name;
754
2/2
✓ Branch 0 taken 6508 times.
✓ Branch 1 taken 166 times.
6674 if (!strcmp(decoder_name, in_codec_name))
755 6508 decoder_name = "native";
756 }
757
758
1/2
✓ Branch 0 taken 6674 times.
✗ Branch 1 not taken.
6674 if (out_codec) {
759 6674 encoder_name = out_codec->name;
760 6674 desc = avcodec_descriptor_get(out_codec->id);
761
1/2
✓ Branch 0 taken 6674 times.
✗ Branch 1 not taken.
6674 if (desc)
762 6674 out_codec_name = desc->name;
763
2/2
✓ Branch 0 taken 6565 times.
✓ Branch 1 taken 109 times.
6674 if (!strcmp(encoder_name, out_codec_name))
764 6565 encoder_name = "native";
765 }
766
767 6674 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 693 av_log(NULL, AV_LOG_INFO, " (copy)");
772 7367 av_log(NULL, AV_LOG_INFO, "\n");
773 }
774 7924 }
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 7924 static int transcode(Scheduler *sch)
856 {
857 7924 int ret = 0;
858 7924 int64_t timer_start, transcode_ts = 0;
859
860 7924 print_stream_maps();
861
862 7924 atomic_store(&transcode_init_done, 1);
863
864 7924 ret = sch_start(sch);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 if (ret < 0)
866 return ret;
867
868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
7924 if (stdin_interaction) {
869 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
870 }
871
872 7924 timer_start = av_gettime_relative();
873
874
2/2
✓ Branch 1 taken 16602 times.
✓ Branch 2 taken 7924 times.
24526 while (!sch_wait(sch, stats_period, &transcode_ts)) {
875 16602 int64_t cur_time= av_gettime_relative();
876
877 /* if 'q' pressed, exits */
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16602 times.
16602 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 16602 print_report(0, timer_start, cur_time, transcode_ts);
884 }
885
886 7924 ret = sch_stop(sch, &transcode_ts);
887
888 /* write the trailer if needed */
889
2/2
✓ Branch 0 taken 7926 times.
✓ Branch 1 taken 7924 times.
15850 for (int i = 0; i < nb_output_files; i++) {
890 7926 int err = of_write_trailer(output_files[i]);
891 7926 ret = err_merge(ret, err);
892 }
893
894 7924 term_exit();
895
896 /* dump report by using the first video and audio streams */
897 7924 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
898
899 7924 return ret;
900 }
901
902 7924 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
903 {
904 7924 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
905 #if HAVE_GETRUSAGE
906 struct rusage rusage;
907
908 7924 getrusage(RUSAGE_SELF, &rusage);
909 7924 time_stamps.user_usec =
910 7924 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
911 7924 time_stamps.sys_usec =
912 7924 (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 7924 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 7925 int main(int argc, char **argv)
947 {
948 7925 Scheduler *sch = NULL;
949
950 int ret;
951 BenchmarkTimeStamps ti;
952
953 7925 init_dynload();
954
955 7925 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
956
957 7925 av_log_set_flags(AV_LOG_SKIP_REPEATED);
958 7925 parse_loglevel(argc, argv, options);
959
960 #if CONFIG_AVDEVICE
961 7925 avdevice_register_all();
962 #endif
963 7925 avformat_network_init();
964
965 7925 show_banner(argc, argv, options);
966
967 7925 sch = sch_alloc();
968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7925 times.
7925 if (!sch) {
969 ret = AVERROR(ENOMEM);
970 goto finish;
971 }
972
973 /* parse options and open all input/output files */
974 7925 ret = ffmpeg_parse_options(argc, argv, sch);
975
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7924 times.
7925 if (ret < 0)
976 1 goto finish;
977
978
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7924 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7924 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 7924 times.
7924 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 7924 current_time = ti = get_benchmark_time_stamps();
992 7924 ret = transcode(sch);
993
3/4
✓ Branch 0 taken 7923 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7923 times.
7924 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 7924 times.
✗ Branch 1 not taken.
15848 ret = received_nb_signals ? 255 :
1005
2/2
✓ Branch 0 taken 7923 times.
✓ Branch 1 taken 1 times.
7924 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1006
1007 7925 finish:
1008
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7924 times.
7925 if (ret == AVERROR_EXIT)
1009 1 ret = 0;
1010
1011 7925 ffmpeg_cleanup(ret);
1012
1013 7925 sch_free(&sch);
1014
1015 7925 return ret;
1016 }
1017