FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2025-11-15 09:35:08
Exec Total Coverage
Lines: 336 479 70.1%
Functions: 19 25 76.0%
Branches: 202 316 63.9%

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 16913 static void term_exit_sigsafe(void)
125 {
126 #if HAVE_TERMIOS_H
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16913 times.
16913 if(restore_tty)
128 tcsetattr (0, TCSANOW, &oldtty);
129 #endif
130 16913 }
131
132 16913 void term_exit(void)
133 {
134 16913 av_log(NULL, AV_LOG_QUIET, "%s", "");
135 16913 term_exit_sigsafe();
136 16913 }
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 8456 void term_init(void)
203 {
204 #if defined __linux__
205 8456 struct sigaction action = {0};
206 8456 action.sa_handler = sigterm_handler;
207
208 /* block other interrupts while processing this one */
209 8456 sigfillset(&action.sa_mask);
210
211 /* restart interruptible functions (i.e. don't fail with EINTR) */
212 8456 action.sa_flags = SA_RESTART;
213 #endif
214
215 #if HAVE_TERMIOS_H
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8456 times.
8456 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 8456 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
238 8456 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
239 #ifdef SIGXCPU
240 8456 SIGNAL(SIGXCPU, sigterm_handler);
241 #endif
242 #ifdef SIGPIPE
243 8456 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
244 #endif
245 #if HAVE_SETCONSOLECTRLHANDLER
246 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
247 #endif
248 8456 }
249
250 /* read a key without blocking */
251 static int read_key(void)
252 {
253 unsigned char ch = -1;
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 ch;
301 }
302
303 796961 static int decode_interrupt_cb(void *ctx)
304 {
305 796961 return received_nb_signals > atomic_load(&transcode_init_done);
306 }
307
308 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
309
310 8457 static void ffmpeg_cleanup(int ret)
311 {
312
2/6
✓ Branch 0 taken 8457 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8457 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8457 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 8457 times.
8457 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 1253 times.
✓ Branch 1 taken 8457 times.
9710 for (int i = 0; i < nb_filtergraphs; i++)
321 1253 fg_free(&filtergraphs[i]);
322 8457 av_freep(&filtergraphs);
323
324
2/2
✓ Branch 0 taken 8460 times.
✓ Branch 1 taken 8457 times.
16917 for (int i = 0; i < nb_output_files; i++)
325 8460 of_free(&output_files[i]);
326
327
2/2
✓ Branch 0 taken 7366 times.
✓ Branch 1 taken 8457 times.
15823 for (int i = 0; i < nb_input_files; i++)
328 7366 ifile_close(&input_files[i]);
329
330
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8457 times.
8458 for (int i = 0; i < nb_decoders; i++)
331 1 dec_free(&decoders[i]);
332 8457 av_freep(&decoders);
333
334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 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 8457 av_freep(&vstats_filename);
341 8457 of_enc_stats_close();
342
343 8457 hw_device_free_all();
344
345 8457 av_freep(&filter_nbthreads);
346
347 8457 av_freep(&print_graphs_file);
348 8457 av_freep(&print_graphs_format);
349
350 8457 av_freep(&input_files);
351 8457 av_freep(&output_files);
352
353 8457 uninit_opts();
354
355 8457 avformat_network_deinit();
356
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 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 8456 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
8457 } else if (ret && atomic_load(&transcode_init_done)) {
361 1 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
362 }
363 8457 term_exit();
364 8457 ffmpeg_exited = 1;
365 8457 }
366
367 34861 OutputStream *ost_iter(OutputStream *prev)
368 {
369
2/2
✓ Branch 0 taken 17925 times.
✓ Branch 1 taken 16936 times.
34861 int of_idx = prev ? prev->file->index : 0;
370
2/2
✓ Branch 0 taken 17925 times.
✓ Branch 1 taken 16936 times.
34861 int ost_idx = prev ? prev->index + 1 : 0;
371
372
2/2
✓ Branch 0 taken 34869 times.
✓ Branch 1 taken 16936 times.
51805 for (; of_idx < nb_output_files; of_idx++) {
373 34869 OutputFile *of = output_files[of_idx];
374
2/2
✓ Branch 0 taken 17925 times.
✓ Branch 1 taken 16944 times.
34869 if (ost_idx < of->nb_streams)
375 17925 return of->streams[ost_idx];
376
377 16944 ost_idx = 0;
378 }
379
380 16936 return NULL;
381 }
382
383 16642 InputStream *ist_iter(InputStream *prev)
384 {
385
2/2
✓ Branch 0 taken 8002 times.
✓ Branch 1 taken 8640 times.
16642 int if_idx = prev ? prev->file->index : 0;
386
2/2
✓ Branch 0 taken 8002 times.
✓ Branch 1 taken 8640 times.
16642 int ist_idx = prev ? prev->index + 1 : 0;
387
388
2/2
✓ Branch 0 taken 15574 times.
✓ Branch 1 taken 8476 times.
24050 for (; if_idx < nb_input_files; if_idx++) {
389 15574 InputFile *f = input_files[if_idx];
390
2/2
✓ Branch 0 taken 8166 times.
✓ Branch 1 taken 7408 times.
15574 if (ist_idx < f->nb_streams)
391 8166 return f->streams[ist_idx];
392
393 7408 ist_idx = 0;
394 }
395
396 8476 return NULL;
397 }
398
399 1445470 static void frame_data_free(void *opaque, uint8_t *data)
400 {
401 1445470 FrameData *fd = (FrameData *)data;
402
403 1445470 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
404 1445470 avcodec_parameters_free(&fd->par_enc);
405
406 1445470 av_free(data);
407 1445470 }
408
409 2906477 static int frame_data_ensure(AVBufferRef **dst, int writable)
410 {
411 2906477 AVBufferRef *src = *dst;
412
413
6/6
✓ Branch 0 taken 2402821 times.
✓ Branch 1 taken 503656 times.
✓ Branch 2 taken 2395924 times.
✓ Branch 3 taken 6897 times.
✓ Branch 5 taken 941814 times.
✓ Branch 6 taken 1454110 times.
2906477 if (!src || (writable && !av_buffer_is_writable(src))) {
414 FrameData *fd;
415
416 1445470 fd = av_mallocz(sizeof(*fd));
417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1445470 times.
1445470 if (!fd)
418 return AVERROR(ENOMEM);
419
420 1445470 *dst = av_buffer_create((uint8_t *)fd, sizeof(*fd),
421 frame_data_free, NULL, 0);
422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1445470 times.
1445470 if (!*dst) {
423 av_buffer_unref(&src);
424 av_freep(&fd);
425 return AVERROR(ENOMEM);
426 }
427
428
2/2
✓ Branch 0 taken 941814 times.
✓ Branch 1 taken 503656 times.
1445470 if (src) {
429 941814 const FrameData *fd_src = (const FrameData *)src->data;
430
431 941814 memcpy(fd, fd_src, sizeof(*fd));
432 941814 fd->par_enc = NULL;
433 941814 fd->side_data = NULL;
434 941814 fd->nb_side_data = 0;
435
436
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 941813 times.
941814 if (fd_src->par_enc) {
437 1 int ret = 0;
438
439 1 fd->par_enc = avcodec_parameters_alloc();
440 2 ret = fd->par_enc ?
441
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 avcodec_parameters_copy(fd->par_enc, fd_src->par_enc) :
442 AVERROR(ENOMEM);
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0) {
444 av_buffer_unref(dst);
445 av_buffer_unref(&src);
446 return ret;
447 }
448 }
449
450
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 941634 times.
941814 if (fd_src->nb_side_data) {
451 180 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
452 180 fd_src->side_data, fd_src->nb_side_data, 0);
453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 180 times.
180 if (ret < 0) {
454 av_buffer_unref(dst);
455 av_buffer_unref(&src);
456 return ret;
457 }
458 }
459
460 941814 av_buffer_unref(&src);
461 } else {
462 503656 fd->dec.frame_num = UINT64_MAX;
463 503656 fd->dec.pts = AV_NOPTS_VALUE;
464
465
2/2
✓ Branch 0 taken 3525592 times.
✓ Branch 1 taken 503656 times.
4029248 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
466 3525592 fd->wallclock[i] = INT64_MIN;
467 }
468 }
469
470 2906477 return 0;
471 }
472
473 1620888 FrameData *frame_data(AVFrame *frame)
474 {
475 1620888 int ret = frame_data_ensure(&frame->opaque_ref, 1);
476
1/2
✓ Branch 0 taken 1620888 times.
✗ Branch 1 not taken.
1620888 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
477 }
478
479 8176 const FrameData *frame_data_c(AVFrame *frame)
480 {
481 8176 int ret = frame_data_ensure(&frame->opaque_ref, 0);
482
1/2
✓ Branch 0 taken 8176 times.
✗ Branch 1 not taken.
8176 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
483 }
484
485 1277413 FrameData *packet_data(AVPacket *pkt)
486 {
487 1277413 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
488
1/2
✓ Branch 0 taken 1277413 times.
✗ Branch 1 not taken.
1277413 return ret < 0 ? NULL : (FrameData*)pkt->opaque_ref->data;
489 }
490
491 const FrameData *packet_data_c(AVPacket *pkt)
492 {
493 int ret = frame_data_ensure(&pkt->opaque_ref, 0);
494 return ret < 0 ? NULL : (const FrameData*)pkt->opaque_ref->data;
495 }
496
497 15826 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
498 void *logctx, int decode)
499 {
500 15826 const AVClass *class = avcodec_get_class();
501 15826 const AVClass *fclass = avformat_get_class();
502
503
2/2
✓ Branch 0 taken 7366 times.
✓ Branch 1 taken 8460 times.
15826 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
504 AV_OPT_FLAG_ENCODING_PARAM;
505 15826 const AVDictionaryEntry *e = NULL;
506
507
2/2
✓ Branch 1 taken 49212 times.
✓ Branch 2 taken 15826 times.
65038 while ((e = av_dict_iterate(opts, e))) {
508 const AVOption *option, *foption;
509 char *optname, *p;
510
511
2/2
✓ Branch 1 taken 48385 times.
✓ Branch 2 taken 827 times.
49212 if (av_dict_get(opts_used, e->key, NULL, 0))
512 48386 continue;
513
514 827 optname = av_strdup(e->key);
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 827 times.
827 if (!optname)
516 return AVERROR(ENOMEM);
517
518 827 p = strchr(optname, ':');
519
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 816 times.
827 if (p)
520 11 *p = 0;
521
522 827 option = av_opt_find(&class, optname, NULL, 0,
523 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
524 827 foption = av_opt_find(&fclass, optname, NULL, 0,
525 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
526 827 av_freep(&optname);
527
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)
528 1 continue;
529
530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
826 if (!(option->flags & flag)) {
531 av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s "
532 "option.\n", e->key, option->help ? option->help : "",
533 decode ? "decoding" : "encoding");
534 return AVERROR(EINVAL);
535 }
536
537 826 av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
538 "for any stream. The most likely reason is either wrong type "
539 "(e.g. a video option with no video streams) or that it is a "
540 "private option of some decoder which was not actually used "
541
2/2
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 4 times.
1652 "for any stream.\n", e->key, option->help ? option->help : "");
542 }
543
544 15826 return 0;
545 }
546
547 2869627 void update_benchmark(const char *fmt, ...)
548 {
549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2869627 times.
2869627 if (do_benchmark_all) {
550 BenchmarkTimeStamps t = get_benchmark_time_stamps();
551 va_list va;
552 char buf[1024];
553
554 if (fmt) {
555 va_start(va, fmt);
556 vsnprintf(buf, sizeof(buf), fmt, va);
557 va_end(va);
558 av_log(NULL, AV_LOG_INFO,
559 "bench: %8" PRIu64 " user %8" PRIu64 " sys %8" PRIu64 " real %s \n",
560 t.user_usec - current_time.user_usec,
561 t.sys_usec - current_time.sys_usec,
562 t.real_usec - current_time.real_usec, buf);
563 }
564 current_time = t;
565 }
566 2869627 }
567
568 26433 static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts)
569 {
570 AVBPrint buf, buf_script;
571 26433 int64_t total_size = of_filesize(output_files[0]);
572 int vid;
573 double bitrate;
574 double speed;
575 static int64_t last_time = -1;
576 static int first_report = 1;
577 26433 uint64_t nb_frames_dup = 0, nb_frames_drop = 0;
578 int mins, secs, ms, us;
579 int64_t hours;
580 const char *hours_sign;
581 int ret;
582 float t;
583
584
5/6
✓ Branch 0 taken 26381 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 17953 times.
✓ Branch 3 taken 8428 times.
✓ Branch 4 taken 17953 times.
✗ Branch 5 not taken.
26433 if (!print_stats && !is_last_report && !progress_avio)
585 17953 return;
586
587
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8456 times.
8480 if (!is_last_report) {
588
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (last_time == -1) {
589 12 last_time = cur_time;
590 }
591
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) ||
592
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))
593 return;
594 24 last_time = cur_time;
595 }
596
597 8480 t = (cur_time-timer_start) / 1000000.0;
598
599 8480 vid = 0;
600 8480 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
601 8480 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
602
603
2/2
✓ Branch 2 taken 8975 times.
✓ Branch 3 taken 8480 times.
17455 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
604
2/2
✓ Branch 0 taken 8245 times.
✓ Branch 1 taken 730 times.
8975 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
605
606
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 8693 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 201 times.
8975 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
607 81 av_bprintf(&buf, "q=%2.1f ", q);
608 81 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
609 81 ost->file->index, ost->index, q);
610 }
611
4/4
✓ Branch 0 taken 8693 times.
✓ Branch 1 taken 282 times.
✓ Branch 2 taken 7142 times.
✓ Branch 3 taken 1551 times.
8975 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
612 float fps;
613 7142 uint64_t frame_number = atomic_load(&ost->packets_written);
614
615
2/2
✓ Branch 0 taken 1966 times.
✓ Branch 1 taken 5176 times.
7142 fps = t > 1 ? frame_number / t : 0;
616 7142 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
617 frame_number, fps < 9.95, fps, q);
618 7142 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
619 7142 av_bprintf(&buf_script, "fps=%.2f\n", fps);
620 7142 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
621 7142 ost->file->index, ost->index, q);
622
2/2
✓ Branch 0 taken 7141 times.
✓ Branch 1 taken 1 times.
7142 if (is_last_report)
623 7141 av_bprintf(&buf, "L");
624
625
2/2
✓ Branch 0 taken 6820 times.
✓ Branch 1 taken 322 times.
7142 if (ost->filter) {
626 6820 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
627 6820 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
628 }
629
630 7142 vid = 1;
631 }
632 }
633
634
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8467 times.
8480 if (copy_ts) {
635
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)
636 13 copy_ts_first_pts = pts;
637
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (copy_ts_first_pts != AV_NOPTS_VALUE)
638 13 pts -= copy_ts_first_pts;
639 }
640
641
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8351 times.
8480 us = FFABS64U(pts) % AV_TIME_BASE;
642
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8351 times.
8480 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
643
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8351 times.
8480 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
644
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8351 times.
8480 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
645
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8367 times.
8480 hours_sign = (pts < 0) ? "-" : "";
646
647
6/6
✓ Branch 0 taken 8367 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 8351 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 8232 times.
✓ Branch 5 taken 119 times.
8480 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
648
3/4
✓ Branch 0 taken 8367 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 8367 times.
✗ Branch 3 not taken.
8480 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
649
650
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 8359 times.
8480 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
651 8359 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
652
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8367 times.
8480 if (pts == AV_NOPTS_VALUE) {
653 113 av_bprintf(&buf, "N/A ");
654 } else {
655 8367 av_bprintf(&buf, "%s%02"PRId64":%02d:%02d.%02d ",
656 hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
657 }
658
659
2/2
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 8232 times.
8480 if (bitrate < 0) {
660 248 av_bprintf(&buf, "bitrate=N/A");
661 248 av_bprintf(&buf_script, "bitrate=N/A\n");
662 }else{
663 8232 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
664 8232 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
665 }
666
667
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 8359 times.
8480 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
668 8359 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
669
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8367 times.
8480 if (pts == AV_NOPTS_VALUE) {
670 113 av_bprintf(&buf_script, "out_time_us=N/A\n");
671 113 av_bprintf(&buf_script, "out_time_ms=N/A\n");
672 113 av_bprintf(&buf_script, "out_time=N/A\n");
673 } else {
674 8367 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
675 8367 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
676 8367 av_bprintf(&buf_script, "out_time=%s%02"PRId64":%02d:%02d.%06d\n",
677 hours_sign, hours, mins, secs, us);
678 }
679
680
4/4
✓ Branch 0 taken 8464 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8458 times.
8480 if (nb_frames_dup || nb_frames_drop)
681 22 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
682 8480 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
683 8480 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
684
685
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8367 times.
8480 if (speed < 0) {
686 113 av_bprintf(&buf, " speed=N/A");
687 113 av_bprintf(&buf_script, "speed=N/A\n");
688 } else {
689 8367 av_bprintf(&buf, " speed=%4.3gx", speed);
690 8367 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
691 }
692
693 8480 secs = (int)t;
694 8480 ms = (int)((t - secs) * 1000);
695 8480 mins = secs / 60;
696 8480 secs %= 60;
697 8480 hours = mins / 60;
698 8480 mins %= 60;
699
700 8480 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
701
702
3/4
✓ Branch 0 taken 8428 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 8428 times.
✗ Branch 3 not taken.
8480 if (print_stats || is_last_report) {
703
2/2
✓ Branch 0 taken 8456 times.
✓ Branch 1 taken 24 times.
8480 const char end = is_last_report ? '\n' : '\r';
704
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8480 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8480 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
705 fprintf(stderr, "%s %c", buf.str, end);
706 } else
707 8480 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
708
709 8480 fflush(stderr);
710 }
711 8480 av_bprint_finalize(&buf, NULL);
712
713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8480 times.
8480 if (progress_avio) {
714 av_bprintf(&buf_script, "progress=%s\n",
715 is_last_report ? "end" : "continue");
716 avio_write(progress_avio, buf_script.str,
717 FFMIN(buf_script.len, buf_script.size - 1));
718 avio_flush(progress_avio);
719 av_bprint_finalize(&buf_script, NULL);
720 if (is_last_report) {
721 if ((ret = avio_closep(&progress_avio)) < 0)
722 av_log(NULL, AV_LOG_ERROR,
723 "Error closing progress log, loss of information possible: %s\n", av_err2str(ret));
724 }
725 }
726
727 8480 first_report = 0;
728 }
729
730 8456 static void print_stream_maps(void)
731 {
732 8456 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
733
2/2
✓ Branch 2 taken 7946 times.
✓ Branch 3 taken 8456 times.
16402 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
734
2/2
✓ Branch 0 taken 6957 times.
✓ Branch 1 taken 7946 times.
14903 for (int j = 0; j < ist->nb_filters; j++) {
735
2/2
✓ Branch 1 taken 163 times.
✓ Branch 2 taken 6794 times.
6957 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
736 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
737 163 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
738
1/2
✓ Branch 0 taken 163 times.
✗ Branch 1 not taken.
163 ist->filters[j]->name);
739
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 159 times.
163 if (nb_filtergraphs > 1)
740 4 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
741 163 av_log(NULL, AV_LOG_INFO, "\n");
742 }
743 }
744 }
745
746
2/2
✓ Branch 2 taken 8950 times.
✓ Branch 3 taken 8456 times.
17406 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
747
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8949 times.
8950 if (ost->attachment_filename) {
748 /* an attached file */
749 1 av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
750 1 ost->attachment_filename, ost->file->index, ost->index);
751 1 continue;
752 }
753
754
4/4
✓ Branch 0 taken 8178 times.
✓ Branch 1 taken 771 times.
✓ Branch 3 taken 1384 times.
✓ Branch 4 taken 6794 times.
8949 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
755 /* output from a complex graph */
756 1384 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
757
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1383 times.
1384 if (nb_filtergraphs > 1)
758 1 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
759
760 1384 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
761 1384 ost->index, ost->enc->enc_ctx->codec->name);
762 1384 continue;
763 }
764
765 7565 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
766 7565 ost->ist->file->index,
767 7565 ost->ist->index,
768 7565 ost->file->index,
769 ost->index);
770
2/2
✓ Branch 0 taken 6836 times.
✓ Branch 1 taken 729 times.
7565 if (ost->enc) {
771 6836 const AVCodec *in_codec = ost->ist->dec;
772 6836 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
773 6836 const char *decoder_name = "?";
774 6836 const char *in_codec_name = "?";
775 6836 const char *encoder_name = "?";
776 6836 const char *out_codec_name = "?";
777 const AVCodecDescriptor *desc;
778
779
1/2
✓ Branch 0 taken 6836 times.
✗ Branch 1 not taken.
6836 if (in_codec) {
780 6836 decoder_name = in_codec->name;
781 6836 desc = avcodec_descriptor_get(in_codec->id);
782
1/2
✓ Branch 0 taken 6836 times.
✗ Branch 1 not taken.
6836 if (desc)
783 6836 in_codec_name = desc->name;
784
2/2
✓ Branch 0 taken 6668 times.
✓ Branch 1 taken 168 times.
6836 if (!strcmp(decoder_name, in_codec_name))
785 6668 decoder_name = "native";
786 }
787
788
1/2
✓ Branch 0 taken 6836 times.
✗ Branch 1 not taken.
6836 if (out_codec) {
789 6836 encoder_name = out_codec->name;
790 6836 desc = avcodec_descriptor_get(out_codec->id);
791
1/2
✓ Branch 0 taken 6836 times.
✗ Branch 1 not taken.
6836 if (desc)
792 6836 out_codec_name = desc->name;
793
2/2
✓ Branch 0 taken 6724 times.
✓ Branch 1 taken 112 times.
6836 if (!strcmp(encoder_name, out_codec_name))
794 6724 encoder_name = "native";
795 }
796
797 6836 av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))",
798 in_codec_name, decoder_name,
799 out_codec_name, encoder_name);
800 } else
801 729 av_log(NULL, AV_LOG_INFO, " (copy)");
802 7565 av_log(NULL, AV_LOG_INFO, "\n");
803 }
804 8456 }
805
806 static void set_tty_echo(int on)
807 {
808 #if HAVE_TERMIOS_H
809 struct termios tty;
810 if (tcgetattr(0, &tty) == 0) {
811 if (on) tty.c_lflag |= ECHO;
812 else tty.c_lflag &= ~ECHO;
813 tcsetattr(0, TCSANOW, &tty);
814 }
815 #endif
816 }
817
818 static int check_keyboard_interaction(int64_t cur_time)
819 {
820 int i, key;
821 static int64_t last_time;
822 /* read_key() returns 0 on EOF */
823 if (cur_time - last_time >= 100000) {
824 key = read_key();
825 last_time = cur_time;
826 }else
827 key = -1;
828 if (key == 'q') {
829 av_log(NULL, AV_LOG_INFO, "\n\n[q] command received. Exiting.\n\n");
830 return AVERROR_EXIT;
831 }
832 if (key == '+') av_log_set_level(av_log_get_level()+10);
833 if (key == '-') av_log_set_level(av_log_get_level()-10);
834 if (key == 'c' || key == 'C'){
835 char buf[4096], target[64], command[256], arg[256] = {0};
836 double time;
837 int k, n = 0;
838 fprintf(stderr, "\nEnter command: <target>|all <time>|-1 <command>[ <argument>]\n");
839 i = 0;
840 set_tty_echo(1);
841 while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
842 if (k > 0)
843 buf[i++] = k;
844 buf[i] = 0;
845 set_tty_echo(0);
846 fprintf(stderr, "\n");
847 if (k > 0 &&
848 (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
849 av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
850 target, time, command, arg);
851 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
852 if (ost->fg_simple)
853 fg_send_command(ost->fg_simple, time, target, command, arg,
854 key == 'C');
855 }
856 for (i = 0; i < nb_filtergraphs; i++)
857 fg_send_command(filtergraphs[i], time, target, command, arg,
858 key == 'C');
859 } else {
860 av_log(NULL, AV_LOG_ERROR,
861 "Parse error, at least 3 arguments were expected, "
862 "only %d given in string '%s'\n", n, buf);
863 }
864 }
865 if (key == '?'){
866 fprintf(stderr, "key function\n"
867 "? show this help\n"
868 "+ increase verbosity\n"
869 "- decrease verbosity\n"
870 "c Send command to first matching filter supporting it\n"
871 "C Send/Queue command to all matching filters\n"
872 "h dump packets/hex press to cycle through the 3 states\n"
873 "q quit\n"
874 "s Show QP histogram\n"
875 );
876 }
877 return 0;
878 }
879
880 /*
881 * The following code is the main loop of the file converter
882 */
883 8456 static int transcode(Scheduler *sch)
884 {
885 8456 int ret = 0;
886 8456 int64_t timer_start, transcode_ts = 0;
887
888 8456 print_stream_maps();
889
890 8456 atomic_store(&transcode_init_done, 1);
891
892 8456 ret = sch_start(sch);
893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8456 times.
8456 if (ret < 0)
894 return ret;
895
896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8456 times.
8456 if (stdin_interaction) {
897 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
898 }
899
900 8456 timer_start = av_gettime_relative();
901
902
2/2
✓ Branch 1 taken 17977 times.
✓ Branch 2 taken 8456 times.
26433 while (!sch_wait(sch, stats_period, &transcode_ts)) {
903 17977 int64_t cur_time= av_gettime_relative();
904
905
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17977 times.
17977 if (received_nb_signals)
906 break;
907
908 /* if 'q' pressed, exits */
909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17977 times.
17977 if (stdin_interaction)
910 if (check_keyboard_interaction(cur_time) < 0)
911 break;
912
913 /* dump report by using the output first video and audio streams */
914 17977 print_report(0, timer_start, cur_time, transcode_ts);
915 }
916
917 8456 ret = sch_stop(sch, &transcode_ts);
918
919 /* write the trailer if needed */
920
2/2
✓ Branch 0 taken 8460 times.
✓ Branch 1 taken 8456 times.
16916 for (int i = 0; i < nb_output_files; i++) {
921 8460 int err = of_write_trailer(output_files[i]);
922 8460 ret = err_merge(ret, err);
923 }
924
925 8456 term_exit();
926
927 /* dump report by using the first video and audio streams */
928 8456 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
929
930 8456 return ret;
931 }
932
933 8456 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
934 {
935 8456 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
936 #if HAVE_GETRUSAGE
937 struct rusage rusage;
938
939 8456 getrusage(RUSAGE_SELF, &rusage);
940 8456 time_stamps.user_usec =
941 8456 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
942 8456 time_stamps.sys_usec =
943 8456 (rusage.ru_stime.tv_sec * 1000000LL) + rusage.ru_stime.tv_usec;
944 #elif HAVE_GETPROCESSTIMES
945 HANDLE proc;
946 FILETIME c, e, k, u;
947 proc = GetCurrentProcess();
948 GetProcessTimes(proc, &c, &e, &k, &u);
949 time_stamps.user_usec =
950 ((int64_t)u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
951 time_stamps.sys_usec =
952 ((int64_t)k.dwHighDateTime << 32 | k.dwLowDateTime) / 10;
953 #else
954 time_stamps.user_usec = time_stamps.sys_usec = 0;
955 #endif
956 8456 return time_stamps;
957 }
958
959 static int64_t getmaxrss(void)
960 {
961 #if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
962 struct rusage rusage;
963 getrusage(RUSAGE_SELF, &rusage);
964 return (int64_t)rusage.ru_maxrss * 1024;
965 #elif HAVE_GETPROCESSMEMORYINFO
966 HANDLE proc;
967 PROCESS_MEMORY_COUNTERS memcounters;
968 proc = GetCurrentProcess();
969 memcounters.cb = sizeof(memcounters);
970 GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
971 return memcounters.PeakPagefileUsage;
972 #else
973 return 0;
974 #endif
975 }
976
977 8457 int main(int argc, char **argv)
978 {
979 8457 Scheduler *sch = NULL;
980
981 int ret;
982 BenchmarkTimeStamps ti;
983
984 8457 init_dynload();
985
986 8457 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
987
988 8457 av_log_set_flags(AV_LOG_SKIP_REPEATED);
989 8457 parse_loglevel(argc, argv, options);
990
991 #if CONFIG_AVDEVICE
992 8457 avdevice_register_all();
993 #endif
994 8457 avformat_network_init();
995
996 8457 show_banner(argc, argv, options);
997
998 8457 sch = sch_alloc();
999
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 if (!sch) {
1000 ret = AVERROR(ENOMEM);
1001 goto finish;
1002 }
1003
1004 /* parse options and open all input/output files */
1005 8457 ret = ffmpeg_parse_options(argc, argv, sch);
1006
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8456 times.
8457 if (ret < 0)
1007 1 goto finish;
1008
1009
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8456 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8456 if (nb_output_files <= 0 && nb_input_files == 0) {
1010 show_usage();
1011 av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
1012 ret = 1;
1013 goto finish;
1014 }
1015
1016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8456 times.
8456 if (nb_output_files <= 0) {
1017 av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
1018 ret = 1;
1019 goto finish;
1020 }
1021
1022 8456 current_time = ti = get_benchmark_time_stamps();
1023 8456 ret = transcode(sch);
1024
3/4
✓ Branch 0 taken 8455 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8455 times.
8456 if (ret >= 0 && do_benchmark) {
1025 int64_t utime, stime, rtime;
1026 current_time = get_benchmark_time_stamps();
1027 utime = current_time.user_usec - ti.user_usec;
1028 stime = current_time.sys_usec - ti.sys_usec;
1029 rtime = current_time.real_usec - ti.real_usec;
1030 av_log(NULL, AV_LOG_INFO,
1031 "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
1032 utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
1033 }
1034
1035
1/2
✓ Branch 0 taken 8456 times.
✗ Branch 1 not taken.
16912 ret = received_nb_signals ? 255 :
1036
2/2
✓ Branch 0 taken 8455 times.
✓ Branch 1 taken 1 times.
8456 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1037
1038 8457 finish:
1039
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8456 times.
8457 if (ret == AVERROR_EXIT)
1040 1 ret = 0;
1041
1042 8457 ffmpeg_cleanup(ret);
1043
1044 8457 sch_free(&sch);
1045
1046 8457 av_log(NULL, AV_LOG_VERBOSE, "\n");
1047 8457 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1048
1049 8457 return ret;
1050 }
1051