FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2026-10-28 09:10:55
Exec Total Coverage
Lines: 349 485 72.0%
Functions: 20 25 80.0%
Branches: 212 324 65.4%

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