FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2026-08-25 19:43:55
Exec Total Coverage
Lines: 348 485 71.8%
Functions: 20 25 80.0%
Branches: 210 324 64.8%

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 17454 static void term_exit_sigsafe(void)
128 {
129 #if HAVE_TERMIOS_H
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17454 times.
17454 if(restore_tty)
131 tcsetattr (0, TCSANOW, &oldtty);
132 #endif
133 17454 }
134
135 17453 void term_exit(void)
136 {
137 17453 av_log(NULL, AV_LOG_QUIET, "%s", "");
138 17453 term_exit_sigsafe();
139 17453 }
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 8729 void term_init(void)
206 {
207 #if defined __linux__
208 8729 struct sigaction action = {0};
209 8729 action.sa_handler = sigterm_handler;
210
211 /* block other interrupts while processing this one */
212 8729 sigfillset(&action.sa_mask);
213
214 /* restart interruptible functions (i.e. don't fail with EINTR) */
215 8729 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 8729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8729 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 8729 times.
8729 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 8729 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
251 8729 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
252 #ifdef SIGXCPU
253 8729 SIGNAL(SIGXCPU, sigterm_handler);
254 #endif
255 #ifdef SIGPIPE
256 8729 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
257 #endif
258 #if HAVE_SETCONSOLECTRLHANDLER
259 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
260 #endif
261 8729 }
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 813491 static int decode_interrupt_cb(void *ctx)
318 {
319 813491 return received_nb_signals > atomic_load(&transcode_init_done);
320 }
321
322 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
323
324 8731 static void ffmpeg_cleanup(int ret)
325 {
326
2/6
✓ Branch 0 taken 8731 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8731 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8731 if ((print_graphs || print_graphs_file) && nb_output_files > 0)
327 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 8731 times.
8731 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 1271 times.
✓ Branch 1 taken 8731 times.
10002 for (int i = 0; i < nb_filtergraphs; i++)
335 1271 fg_free(&filtergraphs[i]);
336 8731 av_freep(&filtergraphs);
337
338
2/2
✓ Branch 0 taken 8731 times.
✓ Branch 1 taken 8731 times.
17462 for (int i = 0; i < nb_output_files; i++)
339 8731 of_free(&output_files[i]);
340
341
2/2
✓ Branch 0 taken 7634 times.
✓ Branch 1 taken 8731 times.
16365 for (int i = 0; i < nb_input_files; i++)
342 7634 ifile_close(&input_files[i]);
343
344
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8731 times.
8732 for (int i = 0; i < nb_decoders; i++)
345 1 dec_free(&decoders[i]);
346 8731 av_freep(&decoders);
347
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8731 times.
8731 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 8731 av_freep(&vstats_filename);
355 8731 of_enc_stats_close();
356
357 8731 hw_device_free_all();
358
359 8731 av_freep(&filter_nbthreads);
360
361 8731 av_freep(&print_graphs_file);
362 8731 av_freep(&print_graphs_format);
363
364 8731 av_freep(&input_files);
365 8731 av_freep(&output_files);
366
367 8731 uninit_opts();
368
369 8731 avformat_network_deinit();
370
371
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8730 times.
8731 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 9 times.
✓ Branch 1 taken 8721 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 7 times.
8730 } else if (ret && atomic_load(&transcode_init_done)) {
375 2 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
376 }
377 8731 term_exit();
378 8731 ffmpeg_exited = 1;
379 8731 }
380
381 35980 OutputStream *ost_iter(OutputStream *prev)
382 {
383
2/2
✓ Branch 0 taken 18506 times.
✓ Branch 1 taken 17474 times.
35980 int of_idx = prev ? prev->file->index : 0;
384
2/2
✓ Branch 0 taken 18506 times.
✓ Branch 1 taken 17474 times.
35980 int ost_idx = prev ? prev->index + 1 : 0;
385
386
2/2
✓ Branch 0 taken 35988 times.
✓ Branch 1 taken 17474 times.
53462 for (; of_idx < nb_output_files; of_idx++) {
387 35988 OutputFile *of = output_files[of_idx];
388
2/2
✓ Branch 0 taken 18506 times.
✓ Branch 1 taken 17482 times.
35988 if (ost_idx < of->nb_streams)
389 18506 return of->streams[ost_idx];
390
391 17482 ost_idx = 0;
392 }
393
394 17474 return NULL;
395 }
396
397 17213 InputStream *ist_iter(InputStream *prev)
398 {
399
2/2
✓ Branch 0 taken 8306 times.
✓ Branch 1 taken 8907 times.
17213 int if_idx = prev ? prev->file->index : 0;
400
2/2
✓ Branch 0 taken 8306 times.
✓ Branch 1 taken 8907 times.
17213 int ist_idx = prev ? prev->index + 1 : 0;
401
402
2/2
✓ Branch 0 taken 16140 times.
✓ Branch 1 taken 8742 times.
24882 for (; if_idx < nb_input_files; if_idx++) {
403 16140 InputFile *f = input_files[if_idx];
404
2/2
✓ Branch 0 taken 8471 times.
✓ Branch 1 taken 7669 times.
16140 if (ist_idx < f->nb_streams)
405 8471 return f->streams[ist_idx];
406
407 7669 ist_idx = 0;
408 }
409
410 8742 return NULL;
411 }
412
413 1668429 static void frame_data_free(void *opaque, uint8_t *data)
414 {
415 1668429 FrameData *fd = (FrameData *)data;
416
417 1668429 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
418 1668429 avcodec_parameters_free(&fd->par_enc);
419 1668429 av_dict_free(&fd->reinit_opts);
420
421 1668429 av_free(data);
422 1668429 }
423
424 3847649 static int frame_data_ensure(AVBufferRef **dst, int writable)
425 {
426 3847649 AVBufferRef *src = *dst;
427
428
6/6
✓ Branch 0 taken 3278596 times.
✓ Branch 1 taken 569053 times.
✓ Branch 2 taken 2738464 times.
✓ Branch 3 taken 540132 times.
✓ Branch 5 taken 1099376 times.
✓ Branch 6 taken 1639088 times.
3847649 if (!src || (writable && !av_buffer_is_writable(src))) {
429 FrameData *fd;
430
431 1668429 fd = av_mallocz(sizeof(*fd));
432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1668429 times.
1668429 if (!fd)
433 return AVERROR(ENOMEM);
434
435 1668429 *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 1668429 times.
1668429 if (!*dst) {
438 av_buffer_unref(&src);
439 av_freep(&fd);
440 return AVERROR(ENOMEM);
441 }
442
443
2/2
✓ Branch 0 taken 1099376 times.
✓ Branch 1 taken 569053 times.
1668429 if (src) {
444 1099376 const FrameData *fd_src = (const FrameData *)src->data;
445
446 1099376 memcpy(fd, fd_src, sizeof(*fd));
447 1099376 fd->par_enc = NULL;
448 1099376 fd->side_data = NULL;
449 1099376 fd->nb_side_data = 0;
450 1099376 fd->reinit_opts = NULL;
451
452
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1099374 times.
1099376 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 221 times.
✓ Branch 1 taken 1099155 times.
1099376 if (fd_src->nb_side_data) {
469 221 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
470 221 fd_src->side_data, fd_src->nb_side_data, 0);
471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (ret < 0) {
472 av_buffer_unref(dst);
473 av_buffer_unref(&src);
474 return ret;
475 }
476 }
477
478 1099376 av_buffer_unref(&src);
479 } else {
480 569053 fd->dec.frame_num = UINT64_MAX;
481 569053 fd->dec.pts = AV_NOPTS_VALUE;
482
483
2/2
✓ Branch 0 taken 3983371 times.
✓ Branch 1 taken 569053 times.
4552424 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
484 3983371 fd->wallclock[i] = INT64_MIN;
485 }
486 }
487
488 3847649 return 0;
489 }
490
491 1839260 FrameData *frame_data(AVFrame *frame)
492 {
493 1839260 int ret = frame_data_ensure(&frame->opaque_ref, 1);
494
1/2
✓ Branch 0 taken 1839260 times.
✗ Branch 1 not taken.
1839260 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
495 }
496
497 542469 const FrameData *frame_data_c(AVFrame *frame)
498 {
499 542469 int ret = frame_data_ensure(&frame->opaque_ref, 0);
500
1/2
✓ Branch 0 taken 542469 times.
✗ Branch 1 not taken.
542469 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
501 }
502
503 1465920 FrameData *packet_data(AVPacket *pkt)
504 {
505 1465920 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
506
1/2
✓ Branch 0 taken 1465920 times.
✗ Branch 1 not taken.
1465920 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 16361 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
516 void *logctx, int decode)
517 {
518 16361 const AVClass *class = avcodec_get_class();
519 16361 const AVClass *fclass = avformat_get_class();
520
521
2/2
✓ Branch 0 taken 7632 times.
✓ Branch 1 taken 8729 times.
16361 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
522 AV_OPT_FLAG_ENCODING_PARAM;
523 16361 const AVDictionaryEntry *e = NULL;
524
525
2/2
✓ Branch 1 taken 50323 times.
✓ Branch 2 taken 16361 times.
66684 while ((e = av_dict_iterate(opts, e))) {
526 const AVOption *option, *foption;
527 char *optname, *p;
528
529
2/2
✓ Branch 1 taken 49302 times.
✓ Branch 2 taken 1021 times.
50323 if (av_dict_get(opts_used, e->key, NULL, 0))
530 49304 continue;
531
532 1021 optname = av_strdup(e->key);
533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1021 times.
1021 if (!optname)
534 return AVERROR(ENOMEM);
535
536 1021 p = strchr(optname, ':');
537
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1009 times.
1021 if (p)
538 12 *p = 0;
539
540 1021 option = av_opt_find(&class, optname, NULL, 0,
541 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
542 1021 foption = av_opt_find(&fclass, optname, NULL, 0,
543 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
544 1021 av_freep(&optname);
545
3/4
✓ Branch 0 taken 1021 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1019 times.
1021 if (!option || foption)
546 2 continue;
547
548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1019 times.
1019 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 1019 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 1014 times.
✓ Branch 1 taken 5 times.
2038 "for any stream.\n", e->key, option->help ? option->help : "");
560 }
561
562 16361 return 0;
563 }
564
565 3293932 void update_benchmark(const char *fmt, ...)
566 {
567
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3293932 times.
3293932 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 3293932 }
585
586 27533 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 27533 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 27533 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 27412 times.
✓ Branch 1 taken 121 times.
✓ Branch 2 taken 18781 times.
✓ Branch 3 taken 8631 times.
✓ Branch 4 taken 18781 times.
✗ Branch 5 not taken.
27533 if (!print_stats && !is_last_report && !progress_avio)
603 18781 return;
604
605
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 8722 times.
8752 if (!is_last_report) {
606
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13 times.
30 if (last_time == -1) {
607 17 last_time = cur_time;
608 }
609
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
30 if (((cur_time - last_time) < stats_period && !first_report) ||
610
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
30 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
611 return;
612 30 last_time = cur_time;
613 }
614
615 8752 t = (cur_time-timer_start) / 1000000.0;
616
617 8752 vid = 0;
618 8752 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
619 8752 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
620
621
2/2
✓ Branch 2 taken 9272 times.
✓ Branch 3 taken 8752 times.
18024 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
622
2/2
✓ Branch 0 taken 8431 times.
✓ Branch 1 taken 841 times.
9272 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
623
624
4/4
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 8983 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 208 times.
9272 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
625 81 av_bprintf(&buf, "q=%2.1f ", q);
626 81 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
627 81 ost->file->index, ost->index, q);
628 }
629
4/4
✓ Branch 0 taken 8983 times.
✓ Branch 1 taken 289 times.
✓ Branch 2 taken 7251 times.
✓ Branch 3 taken 1732 times.
9272 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
630 float fps;
631 7251 uint64_t frame_number = atomic_load(&ost->packets_written);
632
633
2/2
✓ Branch 0 taken 2015 times.
✓ Branch 1 taken 5236 times.
7251 fps = t > 1 ? frame_number / t : 0;
634 7251 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
635 frame_number, fps < 9.95, fps, q);
636 7251 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
637 7251 av_bprintf(&buf_script, "fps=%.2f\n", fps);
638 7251 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
639 7251 ost->file->index, ost->index, q);
640
2/2
✓ Branch 0 taken 7249 times.
✓ Branch 1 taken 2 times.
7251 if (is_last_report)
641 7249 av_bprintf(&buf, "L");
642
643
2/2
✓ Branch 0 taken 6894 times.
✓ Branch 1 taken 357 times.
7251 if (ost->filter) {
644 6894 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
645 6894 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
646 }
647
648 7251 vid = 1;
649 }
650 }
651
652
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 8741 times.
8752 if (copy_ts) {
653
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 if (copy_ts_first_pts == AV_NOPTS_VALUE && pts > 1)
654 11 copy_ts_first_pts = pts;
655
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (copy_ts_first_pts != AV_NOPTS_VALUE)
656 11 pts -= copy_ts_first_pts;
657 }
658
659
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 8616 times.
8752 us = FFABS64U(pts) % AV_TIME_BASE;
660
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 8616 times.
8752 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
661
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 8616 times.
8752 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
662
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 8616 times.
8752 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
663
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 8631 times.
8752 hours_sign = (pts < 0) ? "-" : "";
664
665
6/6
✓ Branch 0 taken 8635 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 8620 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 8462 times.
✓ Branch 5 taken 158 times.
8752 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
666
3/4
✓ Branch 0 taken 8635 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 8635 times.
✗ Branch 3 not taken.
8752 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
667
668
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 8594 times.
8752 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
669 8594 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
670
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8635 times.
8752 if (pts == AV_NOPTS_VALUE) {
671 117 av_bprintf(&buf, "N/A ");
672 } else {
673 8635 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 294 times.
✓ Branch 1 taken 8458 times.
8752 if (bitrate < 0) {
678 294 av_bprintf(&buf, "bitrate=N/A");
679 294 av_bprintf(&buf_script, "bitrate=N/A\n");
680 }else{
681 8458 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
682 8458 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
683 }
684
685
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 8594 times.
8752 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
686 8594 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
687
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8635 times.
8752 if (pts == AV_NOPTS_VALUE) {
688 117 av_bprintf(&buf_script, "out_time_us=N/A\n");
689 117 av_bprintf(&buf_script, "out_time_ms=N/A\n");
690 117 av_bprintf(&buf_script, "out_time=N/A\n");
691 } else {
692 8635 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
693 8635 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
694 8635 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 8736 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8730 times.
8752 if (nb_frames_dup || nb_frames_drop)
699 22 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
700 8752 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
701 8752 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
702
703
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 8631 times.
8752 if (speed < 0) {
704 121 av_bprintf(&buf, " speed=N/A");
705 121 av_bprintf(&buf_script, "speed=N/A\n");
706 } else {
707 8631 av_bprintf(&buf, " speed=%4.3gx", speed);
708 8631 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
709 }
710
711 8752 secs = (int)t;
712 8752 ms = (int)((t - secs) * 1000);
713 8752 mins = secs / 60;
714 8752 secs %= 60;
715 8752 hours = mins / 60;
716 8752 mins %= 60;
717
718 8752 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
719
720
3/4
✓ Branch 0 taken 8631 times.
✓ Branch 1 taken 121 times.
✓ Branch 2 taken 8631 times.
✗ Branch 3 not taken.
8752 if (print_stats || is_last_report) {
721
2/2
✓ Branch 0 taken 8722 times.
✓ Branch 1 taken 30 times.
8752 const char end = is_last_report ? '\n' : '\r';
722
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8752 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8752 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
723 fprintf(stderr, "%s %c", buf.str, end);
724 } else
725 8752 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
726
727 8752 fflush(stderr);
728 }
729 8752 av_bprint_finalize(&buf, NULL);
730
731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8752 times.
8752 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 8752 first_report = 0;
746 }
747
748 8722 static void print_stream_maps(void)
749 {
750 8722 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
751
2/2
✓ Branch 2 taken 8250 times.
✓ Branch 3 taken 8722 times.
16972 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
752
2/2
✓ Branch 0 taken 7122 times.
✓ Branch 1 taken 8250 times.
15372 for (int j = 0; j < ist->nb_filters; j++) {
753
2/2
✓ Branch 1 taken 176 times.
✓ Branch 2 taken 6946 times.
7122 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
754 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
755 176 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
756
1/2
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
176 ist->filters[j]->name);
757
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 172 times.
176 if (nb_filtergraphs > 1)
758 4 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
759 176 av_log(NULL, AV_LOG_INFO, "\n");
760 }
761 }
762 }
763
764
2/2
✓ Branch 2 taken 9234 times.
✓ Branch 3 taken 8722 times.
17956 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
765
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9233 times.
9234 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 8351 times.
✓ Branch 1 taken 882 times.
✓ Branch 3 taken 1405 times.
✓ Branch 4 taken 6946 times.
9233 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
773 /* output from a complex graph */
774 1405 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
775
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1404 times.
1405 if (nb_filtergraphs > 1)
776 1 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
777
778 1405 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
779 1405 ost->index, ost->enc->enc_ctx->codec->name);
780 1405 continue;
781 }
782
783 7828 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
784 7828 ost->ist->file->index,
785 7828 ost->ist->index,
786 7828 ost->file->index,
787 ost->index);
788
2/2
✓ Branch 0 taken 6988 times.
✓ Branch 1 taken 840 times.
7828 if (ost->enc) {
789 6988 const AVCodec *in_codec = ost->ist->dec;
790 6988 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
791 6988 const char *decoder_name = "?";
792 6988 const char *in_codec_name = "?";
793 6988 const char *encoder_name = "?";
794 6988 const char *out_codec_name = "?";
795 const AVCodecDescriptor *desc;
796
797
1/2
✓ Branch 0 taken 6988 times.
✗ Branch 1 not taken.
6988 if (in_codec) {
798 6988 decoder_name = in_codec->name;
799 6988 desc = avcodec_descriptor_get(in_codec->id);
800
1/2
✓ Branch 0 taken 6988 times.
✗ Branch 1 not taken.
6988 if (desc)
801 6988 in_codec_name = desc->name;
802
2/2
✓ Branch 0 taken 6803 times.
✓ Branch 1 taken 185 times.
6988 if (!strcmp(decoder_name, in_codec_name))
803 6803 decoder_name = "native";
804 }
805
806
1/2
✓ Branch 0 taken 6988 times.
✗ Branch 1 not taken.
6988 if (out_codec) {
807 6988 encoder_name = out_codec->name;
808 6988 desc = avcodec_descriptor_get(out_codec->id);
809
1/2
✓ Branch 0 taken 6988 times.
✗ Branch 1 not taken.
6988 if (desc)
810 6988 out_codec_name = desc->name;
811
2/2
✓ Branch 0 taken 6871 times.
✓ Branch 1 taken 117 times.
6988 if (!strcmp(encoder_name, out_codec_name))
812 6871 encoder_name = "native";
813 }
814
815 6988 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 840 av_log(NULL, AV_LOG_INFO, " (copy)");
820 7828 av_log(NULL, AV_LOG_INFO, "\n");
821 }
822 8722 }
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 8722 static int transcode(Scheduler *sch)
902 {
903 8722 int ret = 0;
904 8722 int64_t timer_start, transcode_ts = 0;
905
906 8722 print_stream_maps();
907
908 8722 atomic_store(&transcode_init_done, 1);
909
910 8722 ret = sch_start(sch);
911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8722 times.
8722 if (ret < 0)
912 return ret;
913
914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8722 times.
8722 if (stdin_interaction) {
915 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
916 }
917
918 8722 timer_start = av_gettime_relative();
919
920
2/2
✓ Branch 1 taken 18812 times.
✓ Branch 2 taken 8721 times.
27533 while (!sch_wait(sch, stats_period, &transcode_ts)) {
921 18812 int64_t cur_time= av_gettime_relative();
922
923
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18811 times.
18812 if (received_nb_signals)
924 1 break;
925
926 /* if 'q' pressed, exits */
927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18811 times.
18811 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 18811 print_report(0, timer_start, cur_time, transcode_ts);
933 }
934
935 8722 ret = sch_stop(sch, &transcode_ts);
936
937 /* write the trailer if needed */
938
2/2
✓ Branch 0 taken 8726 times.
✓ Branch 1 taken 8722 times.
17448 for (int i = 0; i < nb_output_files; i++) {
939 8726 int err = of_write_trailer(output_files[i]);
940 8726 ret = err_merge(ret, err);
941 }
942
943 8722 term_exit();
944
945 /* dump report by using the first video and audio streams */
946 8722 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
947
948 8722 return ret;
949 }
950
951 8722 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
952 {
953 8722 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
954 #if HAVE_GETRUSAGE
955 struct rusage rusage;
956
957 8722 getrusage(RUSAGE_SELF, &rusage);
958 8722 time_stamps.user_usec =
959 8722 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
960 8722 time_stamps.sys_usec =
961 8722 (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 8722 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 8731 int main(int argc, char **argv)
996 {
997 8731 Scheduler *sch = NULL;
998
999 int ret;
1000 BenchmarkTimeStamps ti;
1001
1002 8731 init_dynload();
1003
1004 8731 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
1005
1006 8731 av_log_set_flags(AV_LOG_SKIP_REPEATED);
1007 8731 parse_loglevel(argc, argv, options);
1008
1009 #if CONFIG_AVDEVICE
1010 8731 avdevice_register_all();
1011 #endif
1012 8731 avformat_network_init();
1013
1014 8731 show_banner(argc, argv, options);
1015
1016 8731 sch = sch_alloc();
1017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8731 times.
8731 if (!sch) {
1018 ret = AVERROR(ENOMEM);
1019 goto finish;
1020 }
1021
1022 /* parse options and open all input/output files */
1023 8731 ret = ffmpeg_parse_options(argc, argv, sch);
1024
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8722 times.
8731 if (ret < 0)
1025 9 goto finish;
1026
1027
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8722 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8722 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 8722 times.
8722 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 8722 current_time = ti = get_benchmark_time_stamps();
1045 8722 ret = transcode(sch);
1046
3/4
✓ Branch 0 taken 8720 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8720 times.
8722 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 8721 times.
✓ Branch 1 taken 1 times.
17443 ret = received_nb_signals ? 255 :
1058
2/2
✓ Branch 0 taken 8720 times.
✓ Branch 1 taken 1 times.
8721 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1059
1060 8731 finish:
1061
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8729 times.
8731 if (ret == AVERROR_EXIT)
1062 2 ret = 0;
1063
1064 8731 ffmpeg_cleanup(ret);
1065
1066 8731 sch_free(&sch);
1067
1068 8731 av_log(NULL, AV_LOG_VERBOSE, "\n");
1069 8731 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1070
1071 8731 return ret;
1072 }
1073