FFmpeg coverage


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