FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2025-04-25 22:50:00
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 16475 static void term_exit_sigsafe(void)
124 {
125 #if HAVE_TERMIOS_H
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16475 times.
16475 if(restore_tty)
127 tcsetattr (0, TCSANOW, &oldtty);
128 #endif
129 16475 }
130
131 16475 void term_exit(void)
132 {
133 16475 av_log(NULL, AV_LOG_QUIET, "%s", "");
134 16475 term_exit_sigsafe();
135 16475 }
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 8237 void term_init(void)
202 {
203 #if defined __linux__
204 8237 struct sigaction action = {0};
205 8237 action.sa_handler = sigterm_handler;
206
207 /* block other interrupts while processing this one */
208 8237 sigfillset(&action.sa_mask);
209
210 /* restart interruptible functions (i.e. don't fail with EINTR) */
211 8237 action.sa_flags = SA_RESTART;
212 #endif
213
214 #if HAVE_TERMIOS_H
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8237 times.
8237 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 8237 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
237 8237 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
238 #ifdef SIGXCPU
239 8237 SIGNAL(SIGXCPU, sigterm_handler);
240 #endif
241 #ifdef SIGPIPE
242 8237 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
243 #endif
244 #if HAVE_SETCONSOLECTRLHANDLER
245 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
246 #endif
247 8237 }
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 785183 static int decode_interrupt_cb(void *ctx)
303 {
304 785183 return received_nb_signals > atomic_load(&transcode_init_done);
305 }
306
307 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
308
309 8238 static void ffmpeg_cleanup(int ret)
310 {
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8238 times.
8238 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 1184 times.
✓ Branch 1 taken 8238 times.
9422 for (int i = 0; i < nb_filtergraphs; i++)
317 1184 fg_free(&filtergraphs[i]);
318 8238 av_freep(&filtergraphs);
319
320
2/2
✓ Branch 0 taken 8239 times.
✓ Branch 1 taken 8238 times.
16477 for (int i = 0; i < nb_output_files; i++)
321 8239 of_free(&output_files[i]);
322
323
2/2
✓ Branch 0 taken 7207 times.
✓ Branch 1 taken 8238 times.
15445 for (int i = 0; i < nb_input_files; i++)
324 7207 ifile_close(&input_files[i]);
325
326
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8238 times.
8239 for (int i = 0; i < nb_decoders; i++)
327 1 dec_free(&decoders[i]);
328 8238 av_freep(&decoders);
329
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8238 times.
8238 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 8238 av_freep(&vstats_filename);
337 8238 of_enc_stats_close();
338
339 8238 hw_device_free_all();
340
341 8238 av_freep(&filter_nbthreads);
342
343 8238 av_freep(&input_files);
344 8238 av_freep(&output_files);
345
346 8238 uninit_opts();
347
348 8238 avformat_network_deinit();
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8238 times.
8238 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 8237 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
8238 } else if (ret && atomic_load(&transcode_init_done)) {
354 1 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
355 }
356 8238 term_exit();
357 8238 ffmpeg_exited = 1;
358 8238 }
359
360 33953 OutputStream *ost_iter(OutputStream *prev)
361 {
362
2/2
✓ Branch 0 taken 17456 times.
✓ Branch 1 taken 16497 times.
33953 int of_idx = prev ? prev->file->index : 0;
363
2/2
✓ Branch 0 taken 17456 times.
✓ Branch 1 taken 16497 times.
33953 int ost_idx = prev ? prev->index + 1 : 0;
364
365
2/2
✓ Branch 0 taken 33957 times.
✓ Branch 1 taken 16497 times.
50454 for (; of_idx < nb_output_files; of_idx++) {
366 33957 OutputFile *of = output_files[of_idx];
367
2/2
✓ Branch 0 taken 17456 times.
✓ Branch 1 taken 16501 times.
33957 if (ost_idx < of->nb_streams)
368 17456 return of->streams[ost_idx];
369
370 16501 ost_idx = 0;
371 }
372
373 16497 return NULL;
374 }
375
376 16179 InputStream *ist_iter(InputStream *prev)
377 {
378
2/2
✓ Branch 0 taken 7819 times.
✓ Branch 1 taken 8360 times.
16179 int if_idx = prev ? prev->file->index : 0;
379
2/2
✓ Branch 0 taken 7819 times.
✓ Branch 1 taken 8360 times.
16179 int ist_idx = prev ? prev->index + 1 : 0;
380
381
2/2
✓ Branch 0 taken 15169 times.
✓ Branch 1 taken 8257 times.
23426 for (; if_idx < nb_input_files; if_idx++) {
382 15169 InputFile *f = input_files[if_idx];
383
2/2
✓ Branch 0 taken 7922 times.
✓ Branch 1 taken 7247 times.
15169 if (ist_idx < f->nb_streams)
384 7922 return f->streams[ist_idx];
385
386 7247 ist_idx = 0;
387 }
388
389 8257 return NULL;
390 }
391
392 1434838 static void frame_data_free(void *opaque, uint8_t *data)
393 {
394 1434838 FrameData *fd = (FrameData *)data;
395
396 1434838 avcodec_parameters_free(&fd->par_enc);
397
398 1434838 av_free(data);
399 1434838 }
400
401 2873298 static int frame_data_ensure(AVBufferRef **dst, int writable)
402 {
403 2873298 AVBufferRef *src = *dst;
404
405
6/6
✓ Branch 0 taken 2366881 times.
✓ Branch 1 taken 506417 times.
✓ Branch 2 taken 2360114 times.
✓ Branch 3 taken 6767 times.
✓ Branch 5 taken 928421 times.
✓ Branch 6 taken 1431693 times.
2873298 if (!src || (writable && !av_buffer_is_writable(src))) {
406 FrameData *fd;
407
408 1434838 fd = av_mallocz(sizeof(*fd));
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1434838 times.
1434838 if (!fd)
410 return AVERROR(ENOMEM);
411
412 1434838 *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 1434838 times.
1434838 if (!*dst) {
415 av_buffer_unref(&src);
416 av_freep(&fd);
417 return AVERROR(ENOMEM);
418 }
419
420
2/2
✓ Branch 0 taken 928421 times.
✓ Branch 1 taken 506417 times.
1434838 if (src) {
421 928421 const FrameData *fd_src = (const FrameData *)src->data;
422
423 928421 memcpy(fd, fd_src, sizeof(*fd));
424 928421 fd->par_enc = NULL;
425
426
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 928419 times.
928421 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 928421 av_buffer_unref(&src);
441 } else {
442 506417 fd->dec.frame_num = UINT64_MAX;
443 506417 fd->dec.pts = AV_NOPTS_VALUE;
444
445
2/2
✓ Branch 0 taken 3544919 times.
✓ Branch 1 taken 506417 times.
4051336 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
446 3544919 fd->wallclock[i] = INT64_MIN;
447 }
448 }
449
450 2873298 return 0;
451 }
452
453 1589291 FrameData *frame_data(AVFrame *frame)
454 {
455 1589291 int ret = frame_data_ensure(&frame->opaque_ref, 1);
456
1/2
✓ Branch 0 taken 1589291 times.
✗ Branch 1 not taken.
1589291 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
457 }
458
459 7979 const FrameData *frame_data_c(AVFrame *frame)
460 {
461 7979 int ret = frame_data_ensure(&frame->opaque_ref, 0);
462
1/2
✓ Branch 0 taken 7979 times.
✗ Branch 1 not taken.
7979 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
463 }
464
465 1276028 FrameData *packet_data(AVPacket *pkt)
466 {
467 1276028 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
468
1/2
✓ Branch 0 taken 1276028 times.
✗ Branch 1 not taken.
1276028 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 15446 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
478 void *logctx, int decode)
479 {
480 15446 const AVClass *class = avcodec_get_class();
481 15446 const AVClass *fclass = avformat_get_class();
482
483
2/2
✓ Branch 0 taken 7207 times.
✓ Branch 1 taken 8239 times.
15446 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
484 AV_OPT_FLAG_ENCODING_PARAM;
485 15446 const AVDictionaryEntry *e = NULL;
486
487
2/2
✓ Branch 1 taken 47856 times.
✓ Branch 2 taken 15446 times.
63302 while ((e = av_dict_iterate(opts, e))) {
488 const AVOption *option, *foption;
489 char *optname, *p;
490
491
2/2
✓ Branch 1 taken 47047 times.
✓ Branch 2 taken 809 times.
47856 if (av_dict_get(opts_used, e->key, NULL, 0))
492 47048 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 15446 return 0;
525 }
526
527 2857671 void update_benchmark(const char *fmt, ...)
528 {
529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2857671 times.
2857671 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 2857671 }
547
548 25762 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 25762 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 25762 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 25712 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 17502 times.
✓ Branch 3 taken 8210 times.
✓ Branch 4 taken 17502 times.
✗ Branch 5 not taken.
25762 if (!print_stats && !is_last_report && !progress_avio)
565 17502 return;
566
567
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 8237 times.
8260 if (!is_last_report) {
568
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
23 if (last_time == -1) {
569 12 last_time = cur_time;
570 }
571
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
23 if (((cur_time - last_time) < stats_period && !first_report) ||
572
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
23 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
573 return;
574 23 last_time = cur_time;
575 }
576
577 8260 t = (cur_time-timer_start) / 1000000.0;
578
579 8260 vid = 0;
580 8260 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
581 8260 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
582
2/2
✓ Branch 2 taken 8740 times.
✓ Branch 3 taken 8260 times.
17000 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
583
2/2
✓ Branch 0 taken 8044 times.
✓ Branch 1 taken 696 times.
8740 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 8473 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 196 times.
8740 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 8473 times.
✓ Branch 1 taken 267 times.
✓ Branch 2 taken 6940 times.
✓ Branch 3 taken 1533 times.
8740 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
591 float fps;
592 6940 uint64_t frame_number = atomic_load(&ost->packets_written);
593
594
2/2
✓ Branch 0 taken 1924 times.
✓ Branch 1 taken 5016 times.
6940 fps = t > 1 ? frame_number / t : 0;
595 6940 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
596 frame_number, fps < 9.95, fps, q);
597 6940 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
598 6940 av_bprintf(&buf_script, "fps=%.2f\n", fps);
599 6940 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
600 6940 ost->file->index, ost->index, q);
601
2/2
✓ Branch 0 taken 6939 times.
✓ Branch 1 taken 1 times.
6940 if (is_last_report)
602 6939 av_bprintf(&buf, "L");
603
604
2/2
✓ Branch 0 taken 6637 times.
✓ Branch 1 taken 303 times.
6940 if (ost->filter) {
605 6637 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
606 6637 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
607 }
608
609 6940 vid = 1;
610 }
611 }
612
613
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8247 times.
8260 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 125 times.
✓ Branch 1 taken 8135 times.
8260 us = FFABS64U(pts) % AV_TIME_BASE;
621
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 8135 times.
8260 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
622
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 8135 times.
8260 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
623
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 8135 times.
8260 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
624
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 8151 times.
8260 hours_sign = (pts < 0) ? "-" : "";
625
626
6/6
✓ Branch 0 taken 8151 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 8135 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 8022 times.
✓ Branch 5 taken 113 times.
8260 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
627
3/4
✓ Branch 0 taken 8151 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 8151 times.
✗ Branch 3 not taken.
8260 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
628
629
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 8145 times.
8260 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
630 8145 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
631
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 8151 times.
8260 if (pts == AV_NOPTS_VALUE) {
632 109 av_bprintf(&buf, "N/A ");
633 } else {
634 8151 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 238 times.
✓ Branch 1 taken 8022 times.
8260 if (bitrate < 0) {
639 238 av_bprintf(&buf, "bitrate=N/A");
640 238 av_bprintf(&buf_script, "bitrate=N/A\n");
641 }else{
642 8022 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
643 8022 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
644 }
645
646
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 8145 times.
8260 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
647 8145 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
648
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 8151 times.
8260 if (pts == AV_NOPTS_VALUE) {
649 109 av_bprintf(&buf_script, "out_time_us=N/A\n");
650 109 av_bprintf(&buf_script, "out_time_ms=N/A\n");
651 109 av_bprintf(&buf_script, "out_time=N/A\n");
652 } else {
653 8151 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
654 8151 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
655 8151 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 8244 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 8237 times.
8260 if (nb_frames_dup || nb_frames_drop)
660 23 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
661 8260 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
662 8260 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
663
664
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 8151 times.
8260 if (speed < 0) {
665 109 av_bprintf(&buf, " speed=N/A");
666 109 av_bprintf(&buf_script, "speed=N/A\n");
667 } else {
668 8151 av_bprintf(&buf, " speed=%4.3gx", speed);
669 8151 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
670 }
671
672
3/4
✓ Branch 0 taken 8210 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 8210 times.
✗ Branch 3 not taken.
8260 if (print_stats || is_last_report) {
673
2/2
✓ Branch 0 taken 8237 times.
✓ Branch 1 taken 23 times.
8260 const char end = is_last_report ? '\n' : '\r';
674
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8260 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8260 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
675 fprintf(stderr, "%s %c", buf.str, end);
676 } else
677 8260 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
678
679 8260 fflush(stderr);
680 }
681 8260 av_bprint_finalize(&buf, NULL);
682
683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8260 times.
8260 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 8260 first_report = 0;
698 }
699
700 8237 static void print_stream_maps(void)
701 {
702 8237 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
703
2/2
✓ Branch 2 taken 7766 times.
✓ Branch 3 taken 8237 times.
16003 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
704
2/2
✓ Branch 0 taken 6817 times.
✓ Branch 1 taken 7766 times.
14583 for (int j = 0; j < ist->nb_filters; j++) {
705
2/2
✓ Branch 1 taken 149 times.
✓ Branch 2 taken 6668 times.
6817 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 8716 times.
✓ Branch 3 taken 8237 times.
16953 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
717
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8715 times.
8716 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 7982 times.
✓ Branch 1 taken 733 times.
✓ Branch 3 taken 1314 times.
✓ Branch 4 taken 6668 times.
8715 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
725 /* output from a complex graph */
726 1314 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1314 times.
1314 if (nb_filtergraphs > 1)
728 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
729
730 1314 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
731 1314 ost->index, ost->enc->enc_ctx->codec->name);
732 1314 continue;
733 }
734
735 7401 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
736 7401 ost->ist->file->index,
737 7401 ost->ist->index,
738 7401 ost->file->index,
739 ost->index);
740
2/2
✓ Branch 0 taken 6706 times.
✓ Branch 1 taken 695 times.
7401 if (ost->enc) {
741 6706 const AVCodec *in_codec = ost->ist->dec;
742 6706 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
743 6706 const char *decoder_name = "?";
744 6706 const char *in_codec_name = "?";
745 6706 const char *encoder_name = "?";
746 6706 const char *out_codec_name = "?";
747 const AVCodecDescriptor *desc;
748
749
1/2
✓ Branch 0 taken 6706 times.
✗ Branch 1 not taken.
6706 if (in_codec) {
750 6706 decoder_name = in_codec->name;
751 6706 desc = avcodec_descriptor_get(in_codec->id);
752
1/2
✓ Branch 0 taken 6706 times.
✗ Branch 1 not taken.
6706 if (desc)
753 6706 in_codec_name = desc->name;
754
2/2
✓ Branch 0 taken 6540 times.
✓ Branch 1 taken 166 times.
6706 if (!strcmp(decoder_name, in_codec_name))
755 6540 decoder_name = "native";
756 }
757
758
1/2
✓ Branch 0 taken 6706 times.
✗ Branch 1 not taken.
6706 if (out_codec) {
759 6706 encoder_name = out_codec->name;
760 6706 desc = avcodec_descriptor_get(out_codec->id);
761
1/2
✓ Branch 0 taken 6706 times.
✗ Branch 1 not taken.
6706 if (desc)
762 6706 out_codec_name = desc->name;
763
2/2
✓ Branch 0 taken 6597 times.
✓ Branch 1 taken 109 times.
6706 if (!strcmp(encoder_name, out_codec_name))
764 6597 encoder_name = "native";
765 }
766
767 6706 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 695 av_log(NULL, AV_LOG_INFO, " (copy)");
772 7401 av_log(NULL, AV_LOG_INFO, "\n");
773 }
774 8237 }
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 8237 static int transcode(Scheduler *sch)
856 {
857 8237 int ret = 0;
858 8237 int64_t timer_start, transcode_ts = 0;
859
860 8237 print_stream_maps();
861
862 8237 atomic_store(&transcode_init_done, 1);
863
864 8237 ret = sch_start(sch);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8237 times.
8237 if (ret < 0)
866 return ret;
867
868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8237 times.
8237 if (stdin_interaction) {
869 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
870 }
871
872 8237 timer_start = av_gettime_relative();
873
874
2/2
✓ Branch 1 taken 17525 times.
✓ Branch 2 taken 8237 times.
25762 while (!sch_wait(sch, stats_period, &transcode_ts)) {
875 17525 int64_t cur_time= av_gettime_relative();
876
877 /* if 'q' pressed, exits */
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17525 times.
17525 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 17525 print_report(0, timer_start, cur_time, transcode_ts);
884 }
885
886 8237 ret = sch_stop(sch, &transcode_ts);
887
888 /* write the trailer if needed */
889
2/2
✓ Branch 0 taken 8239 times.
✓ Branch 1 taken 8237 times.
16476 for (int i = 0; i < nb_output_files; i++) {
890 8239 int err = of_write_trailer(output_files[i]);
891 8239 ret = err_merge(ret, err);
892 }
893
894 8237 term_exit();
895
896 /* dump report by using the first video and audio streams */
897 8237 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
898
899 8237 return ret;
900 }
901
902 8237 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
903 {
904 8237 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
905 #if HAVE_GETRUSAGE
906 struct rusage rusage;
907
908 8237 getrusage(RUSAGE_SELF, &rusage);
909 8237 time_stamps.user_usec =
910 8237 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
911 8237 time_stamps.sys_usec =
912 8237 (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 8237 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 8238 int main(int argc, char **argv)
947 {
948 8238 Scheduler *sch = NULL;
949
950 int ret;
951 BenchmarkTimeStamps ti;
952
953 8238 init_dynload();
954
955 8238 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
956
957 8238 av_log_set_flags(AV_LOG_SKIP_REPEATED);
958 8238 parse_loglevel(argc, argv, options);
959
960 #if CONFIG_AVDEVICE
961 8238 avdevice_register_all();
962 #endif
963 8238 avformat_network_init();
964
965 8238 show_banner(argc, argv, options);
966
967 8238 sch = sch_alloc();
968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8238 times.
8238 if (!sch) {
969 ret = AVERROR(ENOMEM);
970 goto finish;
971 }
972
973 /* parse options and open all input/output files */
974 8238 ret = ffmpeg_parse_options(argc, argv, sch);
975
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8237 times.
8238 if (ret < 0)
976 1 goto finish;
977
978
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8237 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8237 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 8237 times.
8237 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 8237 current_time = ti = get_benchmark_time_stamps();
992 8237 ret = transcode(sch);
993
3/4
✓ Branch 0 taken 8236 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8236 times.
8237 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 8237 times.
✗ Branch 1 not taken.
16474 ret = received_nb_signals ? 255 :
1005
2/2
✓ Branch 0 taken 8236 times.
✓ Branch 1 taken 1 times.
8237 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1006
1007 8238 finish:
1008
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8237 times.
8238 if (ret == AVERROR_EXIT)
1009 1 ret = 0;
1010
1011 8238 ffmpeg_cleanup(ret);
1012
1013 8238 sch_free(&sch);
1014
1015 8238 return ret;
1016 }
1017