FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 314 455 69.0%
Functions: 19 25 76.0%
Branches: 193 306 63.1%

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 15829 static void term_exit_sigsafe(void)
124 {
125 #if HAVE_TERMIOS_H
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15829 times.
15829 if(restore_tty)
127 tcsetattr (0, TCSANOW, &oldtty);
128 #endif
129 15829 }
130
131 15829 void term_exit(void)
132 {
133 15829 av_log(NULL, AV_LOG_QUIET, "%s", "");
134 15829 term_exit_sigsafe();
135 15829 }
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 7914 void term_init(void)
202 {
203 #if defined __linux__
204 7914 struct sigaction action = {0};
205 7914 action.sa_handler = sigterm_handler;
206
207 /* block other interrupts while processing this one */
208 7914 sigfillset(&action.sa_mask);
209
210 /* restart interruptible functions (i.e. don't fail with EINTR) */
211 7914 action.sa_flags = SA_RESTART;
212 #endif
213
214 #if HAVE_TERMIOS_H
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7914 times.
7914 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 7914 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
237 7914 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
238 #ifdef SIGXCPU
239 7914 SIGNAL(SIGXCPU, sigterm_handler);
240 #endif
241 #ifdef SIGPIPE
242 7914 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
243 #endif
244 #if HAVE_SETCONSOLECTRLHANDLER
245 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
246 #endif
247 7914 }
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 768041 static int decode_interrupt_cb(void *ctx)
303 {
304 768041 return received_nb_signals > atomic_load(&transcode_init_done);
305 }
306
307 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
308
309 7915 static void ffmpeg_cleanup(int ret)
310 {
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7915 times.
7915 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 902 times.
✓ Branch 1 taken 7915 times.
8817 for (int i = 0; i < nb_filtergraphs; i++)
317 902 fg_free(&filtergraphs[i]);
318 7915 av_freep(&filtergraphs);
319
320
2/2
✓ Branch 0 taken 7916 times.
✓ Branch 1 taken 7915 times.
15831 for (int i = 0; i < nb_output_files; i++)
321 7916 of_free(&output_files[i]);
322
323
2/2
✓ Branch 0 taken 7164 times.
✓ Branch 1 taken 7915 times.
15079 for (int i = 0; i < nb_input_files; i++)
324 7164 ifile_close(&input_files[i]);
325
326
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7915 times.
7916 for (int i = 0; i < nb_decoders; i++)
327 1 dec_free(&decoders[i]);
328 7915 av_freep(&decoders);
329
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7915 times.
7915 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 7915 av_freep(&vstats_filename);
337 7915 of_enc_stats_close();
338
339 7915 hw_device_free_all();
340
341 7915 av_freep(&filter_nbthreads);
342
343 7915 av_freep(&input_files);
344 7915 av_freep(&output_files);
345
346 7915 uninit_opts();
347
348 7915 avformat_network_deinit();
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7915 times.
7915 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 7914 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
7915 } else if (ret && atomic_load(&transcode_init_done)) {
354 1 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
355 }
356 7915 term_exit();
357 7915 ffmpeg_exited = 1;
358 7915 }
359
360 32586 OutputStream *ost_iter(OutputStream *prev)
361 {
362
2/2
✓ Branch 0 taken 16736 times.
✓ Branch 1 taken 15850 times.
32586 int of_idx = prev ? prev->file->index : 0;
363
2/2
✓ Branch 0 taken 16736 times.
✓ Branch 1 taken 15850 times.
32586 int ost_idx = prev ? prev->index + 1 : 0;
364
365
2/2
✓ Branch 0 taken 32590 times.
✓ Branch 1 taken 15850 times.
48440 for (; of_idx < nb_output_files; of_idx++) {
366 32590 OutputFile *of = output_files[of_idx];
367
2/2
✓ Branch 0 taken 16736 times.
✓ Branch 1 taken 15854 times.
32590 if (ost_idx < of->nb_streams)
368 16736 return of->streams[ost_idx];
369
370 15854 ost_idx = 0;
371 }
372
373 15850 return NULL;
374 }
375
376 15784 InputStream *ist_iter(InputStream *prev)
377 {
378
2/2
✓ Branch 0 taken 7748 times.
✓ Branch 1 taken 8036 times.
15784 int if_idx = prev ? prev->file->index : 0;
379
2/2
✓ Branch 0 taken 7748 times.
✓ Branch 1 taken 8036 times.
15784 int ist_idx = prev ? prev->index + 1 : 0;
380
381
2/2
✓ Branch 0 taken 15054 times.
✓ Branch 1 taken 7933 times.
22987 for (; if_idx < nb_input_files; if_idx++) {
382 15054 InputFile *f = input_files[if_idx];
383
2/2
✓ Branch 0 taken 7851 times.
✓ Branch 1 taken 7203 times.
15054 if (ist_idx < f->nb_streams)
384 7851 return f->streams[ist_idx];
385
386 7203 ist_idx = 0;
387 }
388
389 7933 return NULL;
390 }
391
392 1412157 static void frame_data_free(void *opaque, uint8_t *data)
393 {
394 1412157 FrameData *fd = (FrameData *)data;
395
396 1412157 avcodec_parameters_free(&fd->par_enc);
397
398 1412157 av_free(data);
399 1412157 }
400
401 2849516 static int frame_data_ensure(AVBufferRef **dst, int writable)
402 {
403 2849516 AVBufferRef *src = *dst;
404
405
6/6
✓ Branch 0 taken 2351445 times.
✓ Branch 1 taken 498071 times.
✓ Branch 2 taken 2344722 times.
✓ Branch 3 taken 6723 times.
✓ Branch 5 taken 914086 times.
✓ Branch 6 taken 1430636 times.
2849516 if (!src || (writable && !av_buffer_is_writable(src))) {
406 FrameData *fd;
407
408 1412157 fd = av_mallocz(sizeof(*fd));
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1412157 times.
1412157 if (!fd)
410 return AVERROR(ENOMEM);
411
412 1412157 *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 1412157 times.
1412157 if (!*dst) {
415 av_buffer_unref(&src);
416 av_freep(&fd);
417 return AVERROR(ENOMEM);
418 }
419
420
2/2
✓ Branch 0 taken 914086 times.
✓ Branch 1 taken 498071 times.
1412157 if (src) {
421 914086 const FrameData *fd_src = (const FrameData *)src->data;
422
423 914086 memcpy(fd, fd_src, sizeof(*fd));
424 914086 fd->par_enc = NULL;
425
426
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 914085 times.
914086 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 914086 av_buffer_unref(&src);
441 } else {
442 498071 fd->dec.frame_num = UINT64_MAX;
443 498071 fd->dec.pts = AV_NOPTS_VALUE;
444
445
2/2
✓ Branch 0 taken 3486497 times.
✓ Branch 1 taken 498071 times.
3984568 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
446 3486497 fd->wallclock[i] = INT64_MIN;
447 }
448 }
449
450 2849516 return 0;
451 }
452
453 1574874 FrameData *frame_data(AVFrame *frame)
454 {
455 1574874 int ret = frame_data_ensure(&frame->opaque_ref, 1);
456
1/2
✓ Branch 0 taken 1574874 times.
✗ Branch 1 not taken.
1574874 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
457 }
458
459 7655 const FrameData *frame_data_c(AVFrame *frame)
460 {
461 7655 int ret = frame_data_ensure(&frame->opaque_ref, 0);
462
1/2
✓ Branch 0 taken 7655 times.
✗ Branch 1 not taken.
7655 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
463 }
464
465 1266987 FrameData *packet_data(AVPacket *pkt)
466 {
467 1266987 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
468
1/2
✓ Branch 0 taken 1266987 times.
✗ Branch 1 not taken.
1266987 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 15080 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
478 void *logctx, int decode)
479 {
480 15080 const AVClass *class = avcodec_get_class();
481 15080 const AVClass *fclass = avformat_get_class();
482
483
2/2
✓ Branch 0 taken 7164 times.
✓ Branch 1 taken 7916 times.
15080 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
484 AV_OPT_FLAG_ENCODING_PARAM;
485 15080 const AVDictionaryEntry *e = NULL;
486
487
2/2
✓ Branch 1 taken 45992 times.
✓ Branch 2 taken 15080 times.
61072 while ((e = av_dict_iterate(opts, e))) {
488 const AVOption *option, *foption;
489 char *optname, *p;
490
491
2/2
✓ Branch 1 taken 45187 times.
✓ Branch 2 taken 805 times.
45992 if (av_dict_get(opts_used, e->key, NULL, 0))
492 45188 continue;
493
494 805 optname = av_strdup(e->key);
495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 805 times.
805 if (!optname)
496 return AVERROR(ENOMEM);
497
498 805 p = strchr(optname, ':');
499
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 794 times.
805 if (p)
500 11 *p = 0;
501
502 805 option = av_opt_find(&class, optname, NULL, 0,
503 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
504 805 foption = av_opt_find(&fclass, optname, NULL, 0,
505 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
506 805 av_freep(&optname);
507
3/4
✓ Branch 0 taken 805 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 804 times.
805 if (!option || foption)
508 1 continue;
509
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 804 times.
804 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 804 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 800 times.
✓ Branch 1 taken 4 times.
1608 "for any stream.\n", e->key, option->help ? option->help : "");
522 }
523
524 15080 return 0;
525 }
526
527 2835305 void update_benchmark(const char *fmt, ...)
528 {
529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2835305 times.
2835305 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 2835305 }
547
548 24293 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 24293 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 24293 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 24244 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 16357 times.
✓ Branch 3 taken 7887 times.
✓ Branch 4 taken 16357 times.
✗ Branch 5 not taken.
24293 if (!print_stats && !is_last_report && !progress_avio)
565 16357 return;
566
567
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 7914 times.
7936 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 7936 t = (cur_time-timer_start) / 1000000.0;
578
579 7936 vid = 0;
580 7936 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
581 7936 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
582
2/2
✓ Branch 2 taken 8379 times.
✓ Branch 3 taken 7936 times.
16315 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
583
2/2
✓ Branch 0 taken 7718 times.
✓ Branch 1 taken 661 times.
8379 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
584
585
4/4
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 8131 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 185 times.
8379 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
586 63 av_bprintf(&buf, "q=%2.1f ", q);
587 63 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
588 63 ost->file->index, ost->index, q);
589 }
590
4/4
✓ Branch 0 taken 8131 times.
✓ Branch 1 taken 248 times.
✓ Branch 2 taken 6618 times.
✓ Branch 3 taken 1513 times.
8379 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
591 float fps;
592 6618 uint64_t frame_number = atomic_load(&ost->packets_written);
593
594
2/2
✓ Branch 0 taken 1621 times.
✓ Branch 1 taken 4997 times.
6618 fps = t > 1 ? frame_number / t : 0;
595 6618 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
596 frame_number, fps < 9.95, fps, q);
597 6618 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
598 6618 av_bprintf(&buf_script, "fps=%.2f\n", fps);
599 6618 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
600 6618 ost->file->index, ost->index, q);
601
1/2
✓ Branch 0 taken 6618 times.
✗ Branch 1 not taken.
6618 if (is_last_report)
602 6618 av_bprintf(&buf, "L");
603
604
2/2
✓ Branch 0 taken 6322 times.
✓ Branch 1 taken 296 times.
6618 if (ost->filter) {
605 6322 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
606 6322 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
607 }
608
609 6618 vid = 1;
610 }
611 }
612
613
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7923 times.
7936 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 7811 times.
7936 us = FFABS64U(pts) % AV_TIME_BASE;
621
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 7811 times.
7936 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
622
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 7811 times.
7936 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
623
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 7811 times.
7936 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
624
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 7827 times.
7936 hours_sign = (pts < 0) ? "-" : "";
625
626
6/6
✓ Branch 0 taken 7827 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 7811 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 7698 times.
✓ Branch 5 taken 113 times.
7936 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
627
3/4
✓ Branch 0 taken 7827 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 7827 times.
✗ Branch 3 not taken.
7936 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 7821 times.
7936 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
630 7821 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
631
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 7827 times.
7936 if (pts == AV_NOPTS_VALUE) {
632 109 av_bprintf(&buf, "N/A ");
633 } else {
634 7827 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 7698 times.
7936 if (bitrate < 0) {
639 238 av_bprintf(&buf, "bitrate=N/A");
640 238 av_bprintf(&buf_script, "bitrate=N/A\n");
641 }else{
642 7698 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
643 7698 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
644 }
645
646
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 7821 times.
7936 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
647 7821 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
648
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 7827 times.
7936 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 7827 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
654 7827 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
655 7827 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 7920 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 7913 times.
7936 if (nb_frames_dup || nb_frames_drop)
660 23 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
661 7936 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
662 7936 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
663
664
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 7827 times.
7936 if (speed < 0) {
665 109 av_bprintf(&buf, " speed=N/A");
666 109 av_bprintf(&buf_script, "speed=N/A\n");
667 } else {
668 7827 av_bprintf(&buf, " speed=%4.3gx", speed);
669 7827 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
670 }
671
672
3/4
✓ Branch 0 taken 7887 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 7887 times.
✗ Branch 3 not taken.
7936 if (print_stats || is_last_report) {
673
2/2
✓ Branch 0 taken 7914 times.
✓ Branch 1 taken 22 times.
7936 const char end = is_last_report ? '\n' : '\r';
674
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7936 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
7936 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
675 fprintf(stderr, "%s %c", buf.str, end);
676 } else
677 7936 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
678
679 7936 fflush(stderr);
680 }
681 7936 av_bprint_finalize(&buf, NULL);
682
683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7936 times.
7936 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 7936 first_report = 0;
698 }
699
700 7914 static void print_stream_maps(void)
701 {
702 7914 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
703
2/2
✓ Branch 2 taken 7696 times.
✓ Branch 3 taken 7914 times.
15610 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
704
2/2
✓ Branch 0 taken 6773 times.
✓ Branch 1 taken 7696 times.
14469 for (int j = 0; j < ist->nb_filters; j++) {
705
2/2
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 6635 times.
6773 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
706 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
707 138 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
708
1/2
✓ Branch 0 taken 138 times.
✗ Branch 1 not taken.
138 ist->filters[j]->name);
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138 times.
138 if (nb_filtergraphs > 1)
710 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
711 138 av_log(NULL, AV_LOG_INFO, "\n");
712 }
713 }
714 }
715
716
2/2
✓ Branch 2 taken 8357 times.
✓ Branch 3 taken 7914 times.
16271 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
717
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8356 times.
8357 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 7658 times.
✓ Branch 1 taken 698 times.
✓ Branch 3 taken 1023 times.
✓ Branch 4 taken 6635 times.
8356 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
725 /* output from a complex graph */
726 1023 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1023 times.
1023 if (nb_filtergraphs > 1)
728 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
729
730 1023 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
731 1023 ost->index, ost->enc->enc_ctx->codec->name);
732 1023 continue;
733 }
734
735 7333 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
736 7333 ost->ist->file->index,
737 7333 ost->ist->index,
738 7333 ost->file->index,
739 ost->index);
740
2/2
✓ Branch 0 taken 6673 times.
✓ Branch 1 taken 660 times.
7333 if (ost->enc) {
741 6673 const AVCodec *in_codec = ost->ist->dec;
742 6673 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
743 6673 const char *decoder_name = "?";
744 6673 const char *in_codec_name = "?";
745 6673 const char *encoder_name = "?";
746 6673 const char *out_codec_name = "?";
747 const AVCodecDescriptor *desc;
748
749
1/2
✓ Branch 0 taken 6673 times.
✗ Branch 1 not taken.
6673 if (in_codec) {
750 6673 decoder_name = in_codec->name;
751 6673 desc = avcodec_descriptor_get(in_codec->id);
752
1/2
✓ Branch 0 taken 6673 times.
✗ Branch 1 not taken.
6673 if (desc)
753 6673 in_codec_name = desc->name;
754
2/2
✓ Branch 0 taken 6507 times.
✓ Branch 1 taken 166 times.
6673 if (!strcmp(decoder_name, in_codec_name))
755 6507 decoder_name = "native";
756 }
757
758
1/2
✓ Branch 0 taken 6673 times.
✗ Branch 1 not taken.
6673 if (out_codec) {
759 6673 encoder_name = out_codec->name;
760 6673 desc = avcodec_descriptor_get(out_codec->id);
761
1/2
✓ Branch 0 taken 6673 times.
✗ Branch 1 not taken.
6673 if (desc)
762 6673 out_codec_name = desc->name;
763
2/2
✓ Branch 0 taken 6564 times.
✓ Branch 1 taken 109 times.
6673 if (!strcmp(encoder_name, out_codec_name))
764 6564 encoder_name = "native";
765 }
766
767 6673 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 660 av_log(NULL, AV_LOG_INFO, " (copy)");
772 7333 av_log(NULL, AV_LOG_INFO, "\n");
773 }
774 7914 }
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 7914 static int transcode(Scheduler *sch)
856 {
857 7914 int ret = 0;
858 7914 int64_t timer_start, transcode_ts = 0;
859
860 7914 print_stream_maps();
861
862 7914 atomic_store(&transcode_init_done, 1);
863
864 7914 ret = sch_start(sch);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7914 times.
7914 if (ret < 0)
866 return ret;
867
868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7914 times.
7914 if (stdin_interaction) {
869 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
870 }
871
872 7914 timer_start = av_gettime_relative();
873
874
2/2
✓ Branch 1 taken 16379 times.
✓ Branch 2 taken 7914 times.
24293 while (!sch_wait(sch, stats_period, &transcode_ts)) {
875 16379 int64_t cur_time= av_gettime_relative();
876
877 /* if 'q' pressed, exits */
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16379 times.
16379 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 16379 print_report(0, timer_start, cur_time, transcode_ts);
884 }
885
886 7914 ret = sch_stop(sch, &transcode_ts);
887
888 /* write the trailer if needed */
889
2/2
✓ Branch 0 taken 7916 times.
✓ Branch 1 taken 7914 times.
15830 for (int i = 0; i < nb_output_files; i++) {
890 7916 int err = of_write_trailer(output_files[i]);
891 7916 ret = err_merge(ret, err);
892 }
893
894 7914 term_exit();
895
896 /* dump report by using the first video and audio streams */
897 7914 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
898
899 7914 return ret;
900 }
901
902 7914 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
903 {
904 7914 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
905 #if HAVE_GETRUSAGE
906 struct rusage rusage;
907
908 7914 getrusage(RUSAGE_SELF, &rusage);
909 7914 time_stamps.user_usec =
910 7914 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
911 7914 time_stamps.sys_usec =
912 7914 (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 7914 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 7915 int main(int argc, char **argv)
947 {
948 7915 Scheduler *sch = NULL;
949
950 int ret;
951 BenchmarkTimeStamps ti;
952
953 7915 init_dynload();
954
955 7915 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
956
957 7915 av_log_set_flags(AV_LOG_SKIP_REPEATED);
958 7915 parse_loglevel(argc, argv, options);
959
960 #if CONFIG_AVDEVICE
961 7915 avdevice_register_all();
962 #endif
963 7915 avformat_network_init();
964
965 7915 show_banner(argc, argv, options);
966
967 7915 sch = sch_alloc();
968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7915 times.
7915 if (!sch) {
969 ret = AVERROR(ENOMEM);
970 goto finish;
971 }
972
973 /* parse options and open all input/output files */
974 7915 ret = ffmpeg_parse_options(argc, argv, sch);
975
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7914 times.
7915 if (ret < 0)
976 1 goto finish;
977
978
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7914 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7914 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 7914 times.
7914 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 7914 current_time = ti = get_benchmark_time_stamps();
992 7914 ret = transcode(sch);
993
3/4
✓ Branch 0 taken 7913 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7913 times.
7914 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 7914 times.
✗ Branch 1 not taken.
15828 ret = received_nb_signals ? 255 :
1005
2/2
✓ Branch 0 taken 7913 times.
✓ Branch 1 taken 1 times.
7914 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1006
1007 7915 finish:
1008
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7914 times.
7915 if (ret == AVERROR_EXIT)
1009 1 ret = 0;
1010
1011 7915 ffmpeg_cleanup(ret);
1012
1013 7915 sch_free(&sch);
1014
1015 7915 return ret;
1016 }
1017