FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2026-04-30 23:37:26
Exec Total Coverage
Lines: 336 478 70.3%
Functions: 19 25 76.0%
Branches: 203 316 64.2%

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 17089 static void term_exit_sigsafe(void)
128 {
129 #if HAVE_TERMIOS_H
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17089 times.
17089 if(restore_tty)
131 tcsetattr (0, TCSANOW, &oldtty);
132 #endif
133 17089 }
134
135 17089 void term_exit(void)
136 {
137 17089 av_log(NULL, AV_LOG_QUIET, "%s", "");
138 17089 term_exit_sigsafe();
139 17089 }
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 sigterm_handler(int sig)
149 {
150 int ret;
151 received_sigterm = sig;
152 received_nb_signals++;
153 term_exit_sigsafe();
154 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 }
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 8544 void term_init(void)
206 {
207 #if defined __linux__
208 8544 struct sigaction action = {0};
209 8544 action.sa_handler = sigterm_handler;
210
211 /* block other interrupts while processing this one */
212 8544 sigfillset(&action.sa_mask);
213
214 /* restart interruptible functions (i.e. don't fail with EINTR) */
215 8544 action.sa_flags = SA_RESTART;
216 #endif
217
218 #if HAVE_TERMIOS_H
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8544 times.
8544 if (stdin_interaction) {
220 struct termios tty;
221 if (tcgetattr (0, &tty) == 0) {
222 oldtty = tty;
223 restore_tty = 1;
224
225 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
226 |INLCR|IGNCR|ICRNL|IXON);
227 tty.c_oflag |= OPOST;
228 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
229 tty.c_cflag &= ~(CSIZE|PARENB);
230 tty.c_cflag |= CS8;
231 tty.c_cc[VMIN] = 1;
232 tty.c_cc[VTIME] = 0;
233
234 tcsetattr (0, TCSANOW, &tty);
235 }
236 SIGNAL(SIGQUIT, sigterm_handler); /* Quit (POSIX). */
237 }
238 #endif
239
240 8544 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
241 8544 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
242 #ifdef SIGXCPU
243 8544 SIGNAL(SIGXCPU, sigterm_handler);
244 #endif
245 #ifdef SIGPIPE
246 8544 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
247 #endif
248 #if HAVE_SETCONSOLECTRLHANDLER
249 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
250 #endif
251 8544 }
252
253 /* read a key without blocking */
254 static int read_key(void)
255 {
256 #if HAVE_TERMIOS_H
257 int n = 1;
258 struct timeval tv;
259 fd_set rfds;
260
261 FD_ZERO(&rfds);
262 FD_SET(0, &rfds);
263 tv.tv_sec = 0;
264 tv.tv_usec = 0;
265 n = select(1, &rfds, NULL, NULL, &tv);
266 if (n > 0) {
267 unsigned char ch;
268 n = read(0, &ch, 1);
269 if (n == 1)
270 return ch;
271
272 return n;
273 }
274 #elif HAVE_KBHIT
275 # if HAVE_PEEKNAMEDPIPE && HAVE_GETSTDHANDLE
276 static int is_pipe;
277 static HANDLE input_handle;
278 DWORD dw, nchars;
279 if(!input_handle){
280 input_handle = GetStdHandle(STD_INPUT_HANDLE);
281 is_pipe = !GetConsoleMode(input_handle, &dw);
282 }
283
284 if (is_pipe) {
285 /* When running under a GUI, you will end here. */
286 if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL)) {
287 // input pipe may have been closed by the program that ran ffmpeg
288 return -1;
289 }
290 //Read it
291 if(nchars != 0) {
292 unsigned char ch;
293 if (read(0, &ch, 1) == 1)
294 return ch;
295 return 0;
296 }else{
297 return -1;
298 }
299 }
300 # endif
301 if(kbhit())
302 return(getch());
303 #endif
304 return -1;
305 }
306
307 800174 static int decode_interrupt_cb(void *ctx)
308 {
309 800174 return received_nb_signals > atomic_load(&transcode_init_done);
310 }
311
312 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
313
314 8546 static void ffmpeg_cleanup(int ret)
315 {
316
2/6
✓ Branch 0 taken 8546 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8546 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8546 if ((print_graphs || print_graphs_file) && nb_output_files > 0)
317 print_filtergraphs(filtergraphs, nb_filtergraphs, input_files, nb_input_files, output_files, nb_output_files);
318
319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8546 times.
8546 if (do_benchmark) {
320 int64_t maxrss = getmaxrss() / 1024;
321 av_log(NULL, AV_LOG_INFO, "bench: maxrss=%"PRId64"KiB\n", maxrss);
322 }
323
324
2/2
✓ Branch 0 taken 1260 times.
✓ Branch 1 taken 8546 times.
9806 for (int i = 0; i < nb_filtergraphs; i++)
325 1260 fg_free(&filtergraphs[i]);
326 8546 av_freep(&filtergraphs);
327
328
2/2
✓ Branch 0 taken 8547 times.
✓ Branch 1 taken 8546 times.
17093 for (int i = 0; i < nb_output_files; i++)
329 8547 of_free(&output_files[i]);
330
331
2/2
✓ Branch 0 taken 7455 times.
✓ Branch 1 taken 8546 times.
16001 for (int i = 0; i < nb_input_files; i++)
332 7455 ifile_close(&input_files[i]);
333
334
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8546 times.
8547 for (int i = 0; i < nb_decoders; i++)
335 1 dec_free(&decoders[i]);
336 8546 av_freep(&decoders);
337
338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8546 times.
8546 if (vstats_file) {
339 if (fclose(vstats_file))
340 av_log(NULL, AV_LOG_ERROR,
341 "Error closing vstats file, loss of information possible: %s\n",
342 av_err2str(AVERROR(errno)));
343 }
344 8546 av_freep(&vstats_filename);
345 8546 of_enc_stats_close();
346
347 8546 hw_device_free_all();
348
349 8546 av_freep(&filter_nbthreads);
350
351 8546 av_freep(&print_graphs_file);
352 8546 av_freep(&print_graphs_format);
353
354 8546 av_freep(&input_files);
355 8546 av_freep(&output_files);
356
357 8546 uninit_opts();
358
359 8546 avformat_network_deinit();
360
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8546 times.
8546 if (received_sigterm) {
362 av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n",
363 (int) received_sigterm);
364
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8543 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
8546 } else if (ret && atomic_load(&transcode_init_done)) {
365 2 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
366 }
367 8546 term_exit();
368 8546 ffmpeg_exited = 1;
369 8546 }
370
371 35259 OutputStream *ost_iter(OutputStream *prev)
372 {
373
2/2
✓ Branch 0 taken 18146 times.
✓ Branch 1 taken 17113 times.
35259 int of_idx = prev ? prev->file->index : 0;
374
2/2
✓ Branch 0 taken 18146 times.
✓ Branch 1 taken 17113 times.
35259 int ost_idx = prev ? prev->index + 1 : 0;
375
376
2/2
✓ Branch 0 taken 35267 times.
✓ Branch 1 taken 17113 times.
52380 for (; of_idx < nb_output_files; of_idx++) {
377 35267 OutputFile *of = output_files[of_idx];
378
2/2
✓ Branch 0 taken 18146 times.
✓ Branch 1 taken 17121 times.
35267 if (ost_idx < of->nb_streams)
379 18146 return of->streams[ost_idx];
380
381 17121 ost_idx = 0;
382 }
383
384 17113 return NULL;
385 }
386
387 16847 InputStream *ist_iter(InputStream *prev)
388 {
389
2/2
✓ Branch 0 taken 8120 times.
✓ Branch 1 taken 8727 times.
16847 int if_idx = prev ? prev->file->index : 0;
390
2/2
✓ Branch 0 taken 8120 times.
✓ Branch 1 taken 8727 times.
16847 int ist_idx = prev ? prev->index + 1 : 0;
391
392
2/2
✓ Branch 0 taken 15780 times.
✓ Branch 1 taken 8563 times.
24343 for (; if_idx < nb_input_files; if_idx++) {
393 15780 InputFile *f = input_files[if_idx];
394
2/2
✓ Branch 0 taken 8284 times.
✓ Branch 1 taken 7496 times.
15780 if (ist_idx < f->nb_streams)
395 8284 return f->streams[ist_idx];
396
397 7496 ist_idx = 0;
398 }
399
400 8563 return NULL;
401 }
402
403 1625493 static void frame_data_free(void *opaque, uint8_t *data)
404 {
405 1625493 FrameData *fd = (FrameData *)data;
406
407 1625493 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
408 1625493 avcodec_parameters_free(&fd->par_enc);
409
410 1625493 av_free(data);
411 1625493 }
412
413 3232226 static int frame_data_ensure(AVBufferRef **dst, int writable)
414 {
415 3232226 AVBufferRef *src = *dst;
416
417
6/6
✓ Branch 0 taken 2689764 times.
✓ Branch 1 taken 542462 times.
✓ Branch 2 taken 2682803 times.
✓ Branch 3 taken 6961 times.
✓ Branch 5 taken 1083031 times.
✓ Branch 6 taken 1599772 times.
3232226 if (!src || (writable && !av_buffer_is_writable(src))) {
418 FrameData *fd;
419
420 1625493 fd = av_mallocz(sizeof(*fd));
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1625493 times.
1625493 if (!fd)
422 return AVERROR(ENOMEM);
423
424 1625493 *dst = av_buffer_create((uint8_t *)fd, sizeof(*fd),
425 frame_data_free, NULL, 0);
426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1625493 times.
1625493 if (!*dst) {
427 av_buffer_unref(&src);
428 av_freep(&fd);
429 return AVERROR(ENOMEM);
430 }
431
432
2/2
✓ Branch 0 taken 1083031 times.
✓ Branch 1 taken 542462 times.
1625493 if (src) {
433 1083031 const FrameData *fd_src = (const FrameData *)src->data;
434
435 1083031 memcpy(fd, fd_src, sizeof(*fd));
436 1083031 fd->par_enc = NULL;
437 1083031 fd->side_data = NULL;
438 1083031 fd->nb_side_data = 0;
439
440
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1083030 times.
1083031 if (fd_src->par_enc) {
441 1 int ret = 0;
442
443 1 fd->par_enc = avcodec_parameters_alloc();
444 2 ret = fd->par_enc ?
445
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 avcodec_parameters_copy(fd->par_enc, fd_src->par_enc) :
446 AVERROR(ENOMEM);
447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0) {
448 av_buffer_unref(dst);
449 av_buffer_unref(&src);
450 return ret;
451 }
452 }
453
454
2/2
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 1082843 times.
1083031 if (fd_src->nb_side_data) {
455 188 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
456 188 fd_src->side_data, fd_src->nb_side_data, 0);
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 188 times.
188 if (ret < 0) {
458 av_buffer_unref(dst);
459 av_buffer_unref(&src);
460 return ret;
461 }
462 }
463
464 1083031 av_buffer_unref(&src);
465 } else {
466 542462 fd->dec.frame_num = UINT64_MAX;
467 542462 fd->dec.pts = AV_NOPTS_VALUE;
468
469
2/2
✓ Branch 0 taken 3797234 times.
✓ Branch 1 taken 542462 times.
4339696 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
470 3797234 fd->wallclock[i] = INT64_MIN;
471 }
472 }
473
474 3232226 return 0;
475 }
476
477 1801057 FrameData *frame_data(AVFrame *frame)
478 {
479 1801057 int ret = frame_data_ensure(&frame->opaque_ref, 1);
480
1/2
✓ Branch 0 taken 1801057 times.
✗ Branch 1 not taken.
1801057 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
481 }
482
483 8246 const FrameData *frame_data_c(AVFrame *frame)
484 {
485 8246 int ret = frame_data_ensure(&frame->opaque_ref, 0);
486
1/2
✓ Branch 0 taken 8246 times.
✗ Branch 1 not taken.
8246 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
487 }
488
489 1422923 FrameData *packet_data(AVPacket *pkt)
490 {
491 1422923 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
492
1/2
✓ Branch 0 taken 1422923 times.
✗ Branch 1 not taken.
1422923 return ret < 0 ? NULL : (FrameData*)pkt->opaque_ref->data;
493 }
494
495 const FrameData *packet_data_c(AVPacket *pkt)
496 {
497 int ret = frame_data_ensure(&pkt->opaque_ref, 0);
498 return ret < 0 ? NULL : (const FrameData*)pkt->opaque_ref->data;
499 }
500
501 16001 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
502 void *logctx, int decode)
503 {
504 16001 const AVClass *class = avcodec_get_class();
505 16001 const AVClass *fclass = avformat_get_class();
506
507
2/2
✓ Branch 0 taken 7454 times.
✓ Branch 1 taken 8547 times.
16001 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
508 AV_OPT_FLAG_ENCODING_PARAM;
509 16001 const AVDictionaryEntry *e = NULL;
510
511
2/2
✓ Branch 1 taken 49800 times.
✓ Branch 2 taken 16001 times.
65801 while ((e = av_dict_iterate(opts, e))) {
512 const AVOption *option, *foption;
513 char *optname, *p;
514
515
2/2
✓ Branch 1 taken 48842 times.
✓ Branch 2 taken 958 times.
49800 if (av_dict_get(opts_used, e->key, NULL, 0))
516 48843 continue;
517
518 958 optname = av_strdup(e->key);
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 958 times.
958 if (!optname)
520 return AVERROR(ENOMEM);
521
522 958 p = strchr(optname, ':');
523
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 946 times.
958 if (p)
524 12 *p = 0;
525
526 958 option = av_opt_find(&class, optname, NULL, 0,
527 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
528 958 foption = av_opt_find(&fclass, optname, NULL, 0,
529 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
530 958 av_freep(&optname);
531
3/4
✓ Branch 0 taken 958 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 957 times.
958 if (!option || foption)
532 1 continue;
533
534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 957 times.
957 if (!(option->flags & flag)) {
535 av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s "
536 "option.\n", e->key, option->help ? option->help : "",
537 decode ? "decoding" : "encoding");
538 return AVERROR(EINVAL);
539 }
540
541 957 av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
542 "for any stream. The most likely reason is either wrong type "
543 "(e.g. a video option with no video streams) or that it is a "
544 "private option of some decoder which was not actually used "
545
2/2
✓ Branch 0 taken 952 times.
✓ Branch 1 taken 5 times.
1914 "for any stream.\n", e->key, option->help ? option->help : "");
546 }
547
548 16001 return 0;
549 }
550
551 3227166 void update_benchmark(const char *fmt, ...)
552 {
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3227166 times.
3227166 if (do_benchmark_all) {
554 BenchmarkTimeStamps t = get_benchmark_time_stamps();
555 va_list va;
556 char buf[1024];
557
558 if (fmt) {
559 va_start(va, fmt);
560 vsnprintf(buf, sizeof(buf), fmt, va);
561 va_end(va);
562 av_log(NULL, AV_LOG_INFO,
563 "bench: %8" PRIu64 " user %8" PRIu64 " sys %8" PRIu64 " real %s \n",
564 t.user_usec - current_time.user_usec,
565 t.sys_usec - current_time.sys_usec,
566 t.real_usec - current_time.real_usec, buf);
567 }
568 current_time = t;
569 }
570 3227166 }
571
572 26527 static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts)
573 {
574 AVBPrint buf, buf_script;
575 26527 int64_t total_size = of_filesize(output_files[0]);
576 int vid;
577 double bitrate;
578 double speed;
579 static int64_t last_time = -1;
580 static int first_report = 1;
581 26527 uint64_t nb_frames_dup = 0, nb_frames_drop = 0;
582 int mins, secs, ms, us;
583 int64_t hours;
584 const char *hours_sign;
585 int ret;
586 float t;
587
588
5/6
✓ Branch 0 taken 26460 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 17957 times.
✓ Branch 3 taken 8503 times.
✓ Branch 4 taken 17957 times.
✗ Branch 5 not taken.
26527 if (!print_stats && !is_last_report && !progress_avio)
589 17957 return;
590
591
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 8543 times.
8570 if (!is_last_report) {
592
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 14 times.
27 if (last_time == -1) {
593 13 last_time = cur_time;
594 }
595
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
27 if (((cur_time - last_time) < stats_period && !first_report) ||
596
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
27 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
597 return;
598 27 last_time = cur_time;
599 }
600
601 8570 t = (cur_time-timer_start) / 1000000.0;
602
603 8570 vid = 0;
604 8570 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
605 8570 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
606
607
2/2
✓ Branch 2 taken 9090 times.
✓ Branch 3 taken 8570 times.
17660 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
608
2/2
✓ Branch 0 taken 8325 times.
✓ Branch 1 taken 765 times.
9090 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
609
610
4/4
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 8799 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 207 times.
9090 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
611 84 av_bprintf(&buf, "q=%2.1f ", q);
612 84 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
613 84 ost->file->index, ost->index, q);
614 }
615
4/4
✓ Branch 0 taken 8799 times.
✓ Branch 1 taken 291 times.
✓ Branch 2 taken 7189 times.
✓ Branch 3 taken 1610 times.
9090 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
616 float fps;
617 7189 uint64_t frame_number = atomic_load(&ost->packets_written);
618
619
2/2
✓ Branch 0 taken 1966 times.
✓ Branch 1 taken 5223 times.
7189 fps = t > 1 ? frame_number / t : 0;
620 7189 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
621 frame_number, fps < 9.95, fps, q);
622 7189 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
623 7189 av_bprintf(&buf_script, "fps=%.2f\n", fps);
624 7189 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
625 7189 ost->file->index, ost->index, q);
626
2/2
✓ Branch 0 taken 7188 times.
✓ Branch 1 taken 1 times.
7189 if (is_last_report)
627 7188 av_bprintf(&buf, "L");
628
629
2/2
✓ Branch 0 taken 6857 times.
✓ Branch 1 taken 332 times.
7189 if (ost->filter) {
630 6857 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
631 6857 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
632 }
633
634 7189 vid = 1;
635 }
636 }
637
638
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 8559 times.
8570 if (copy_ts) {
639
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)
640 11 copy_ts_first_pts = pts;
641
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (copy_ts_first_pts != AV_NOPTS_VALUE)
642 11 pts -= copy_ts_first_pts;
643 }
644
645
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 8454 times.
8570 us = FFABS64U(pts) % AV_TIME_BASE;
646
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 8454 times.
8570 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
647
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 8454 times.
8570 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
648
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 8454 times.
8570 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
649
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 8468 times.
8570 hours_sign = (pts < 0) ? "-" : "";
650
651
6/6
✓ Branch 0 taken 8468 times.
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 8454 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 8323 times.
✓ Branch 5 taken 131 times.
8570 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
652
3/4
✓ Branch 0 taken 8468 times.
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 8468 times.
✗ Branch 3 not taken.
8570 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
653
654
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 8439 times.
8570 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
655 8439 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
656
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 8468 times.
8570 if (pts == AV_NOPTS_VALUE) {
657 102 av_bprintf(&buf, "N/A ");
658 } else {
659 8468 av_bprintf(&buf, "%s%02"PRId64":%02d:%02d.%02d ",
660 hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
661 }
662
663
2/2
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 8323 times.
8570 if (bitrate < 0) {
664 247 av_bprintf(&buf, "bitrate=N/A");
665 247 av_bprintf(&buf_script, "bitrate=N/A\n");
666 }else{
667 8323 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
668 8323 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
669 }
670
671
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 8439 times.
8570 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
672 8439 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
673
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 8468 times.
8570 if (pts == AV_NOPTS_VALUE) {
674 102 av_bprintf(&buf_script, "out_time_us=N/A\n");
675 102 av_bprintf(&buf_script, "out_time_ms=N/A\n");
676 102 av_bprintf(&buf_script, "out_time=N/A\n");
677 } else {
678 8468 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
679 8468 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
680 8468 av_bprintf(&buf_script, "out_time=%s%02"PRId64":%02d:%02d.%06d\n",
681 hours_sign, hours, mins, secs, us);
682 }
683
684
4/4
✓ Branch 0 taken 8554 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8548 times.
8570 if (nb_frames_dup || nb_frames_drop)
685 22 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
686 8570 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
687 8570 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
688
689
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 8468 times.
8570 if (speed < 0) {
690 102 av_bprintf(&buf, " speed=N/A");
691 102 av_bprintf(&buf_script, "speed=N/A\n");
692 } else {
693 8468 av_bprintf(&buf, " speed=%4.3gx", speed);
694 8468 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
695 }
696
697 8570 secs = (int)t;
698 8570 ms = (int)((t - secs) * 1000);
699 8570 mins = secs / 60;
700 8570 secs %= 60;
701 8570 hours = mins / 60;
702 8570 mins %= 60;
703
704 8570 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
705
706
3/4
✓ Branch 0 taken 8503 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 8503 times.
✗ Branch 3 not taken.
8570 if (print_stats || is_last_report) {
707
2/2
✓ Branch 0 taken 8543 times.
✓ Branch 1 taken 27 times.
8570 const char end = is_last_report ? '\n' : '\r';
708
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8570 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8570 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
709 fprintf(stderr, "%s %c", buf.str, end);
710 } else
711 8570 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
712
713 8570 fflush(stderr);
714 }
715 8570 av_bprint_finalize(&buf, NULL);
716
717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8570 times.
8570 if (progress_avio) {
718 av_bprintf(&buf_script, "progress=%s\n",
719 is_last_report ? "end" : "continue");
720 avio_write(progress_avio, buf_script.str,
721 FFMIN(buf_script.len, buf_script.size - 1));
722 avio_flush(progress_avio);
723 av_bprint_finalize(&buf_script, NULL);
724 if (is_last_report) {
725 if ((ret = avio_closep(&progress_avio)) < 0)
726 av_log(NULL, AV_LOG_ERROR,
727 "Error closing progress log, loss of information possible: %s\n", av_err2str(ret));
728 }
729 }
730
731 8570 first_report = 0;
732 }
733
734 8543 static void print_stream_maps(void)
735 {
736 8543 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
737
2/2
✓ Branch 2 taken 8064 times.
✓ Branch 3 taken 8543 times.
16607 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
738
2/2
✓ Branch 0 taken 7028 times.
✓ Branch 1 taken 8064 times.
15092 for (int j = 0; j < ist->nb_filters; j++) {
739
2/2
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 6855 times.
7028 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
740 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
741 173 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
742
1/2
✓ Branch 0 taken 173 times.
✗ Branch 1 not taken.
173 ist->filters[j]->name);
743
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 169 times.
173 if (nb_filtergraphs > 1)
744 4 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
745 173 av_log(NULL, AV_LOG_INFO, "\n");
746 }
747 }
748 }
749
750
2/2
✓ Branch 2 taken 9056 times.
✓ Branch 3 taken 8543 times.
17599 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
751
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9055 times.
9056 if (ost->attachment_filename) {
752 /* an attached file */
753 1 av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
754 1 ost->attachment_filename, ost->file->index, ost->index);
755 1 continue;
756 }
757
758
4/4
✓ Branch 0 taken 8249 times.
✓ Branch 1 taken 806 times.
✓ Branch 3 taken 1394 times.
✓ Branch 4 taken 6855 times.
9055 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
759 /* output from a complex graph */
760 1394 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
761
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1393 times.
1394 if (nb_filtergraphs > 1)
762 1 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
763
764 1394 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
765 1394 ost->index, ost->enc->enc_ctx->codec->name);
766 1394 continue;
767 }
768
769 7661 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
770 7661 ost->ist->file->index,
771 7661 ost->ist->index,
772 7661 ost->file->index,
773 ost->index);
774
2/2
✓ Branch 0 taken 6897 times.
✓ Branch 1 taken 764 times.
7661 if (ost->enc) {
775 6897 const AVCodec *in_codec = ost->ist->dec;
776 6897 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
777 6897 const char *decoder_name = "?";
778 6897 const char *in_codec_name = "?";
779 6897 const char *encoder_name = "?";
780 6897 const char *out_codec_name = "?";
781 const AVCodecDescriptor *desc;
782
783
1/2
✓ Branch 0 taken 6897 times.
✗ Branch 1 not taken.
6897 if (in_codec) {
784 6897 decoder_name = in_codec->name;
785 6897 desc = avcodec_descriptor_get(in_codec->id);
786
1/2
✓ Branch 0 taken 6897 times.
✗ Branch 1 not taken.
6897 if (desc)
787 6897 in_codec_name = desc->name;
788
2/2
✓ Branch 0 taken 6729 times.
✓ Branch 1 taken 168 times.
6897 if (!strcmp(decoder_name, in_codec_name))
789 6729 decoder_name = "native";
790 }
791
792
1/2
✓ Branch 0 taken 6897 times.
✗ Branch 1 not taken.
6897 if (out_codec) {
793 6897 encoder_name = out_codec->name;
794 6897 desc = avcodec_descriptor_get(out_codec->id);
795
1/2
✓ Branch 0 taken 6897 times.
✗ Branch 1 not taken.
6897 if (desc)
796 6897 out_codec_name = desc->name;
797
2/2
✓ Branch 0 taken 6784 times.
✓ Branch 1 taken 113 times.
6897 if (!strcmp(encoder_name, out_codec_name))
798 6784 encoder_name = "native";
799 }
800
801 6897 av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))",
802 in_codec_name, decoder_name,
803 out_codec_name, encoder_name);
804 } else
805 764 av_log(NULL, AV_LOG_INFO, " (copy)");
806 7661 av_log(NULL, AV_LOG_INFO, "\n");
807 }
808 8543 }
809
810 static void set_tty_echo(int on)
811 {
812 #if HAVE_TERMIOS_H
813 struct termios tty;
814 if (tcgetattr(0, &tty) == 0) {
815 if (on) tty.c_lflag |= ECHO;
816 else tty.c_lflag &= ~ECHO;
817 tcsetattr(0, TCSANOW, &tty);
818 }
819 #endif
820 }
821
822 static int check_keyboard_interaction(int64_t cur_time)
823 {
824 int i, key;
825 static int64_t last_time;
826 /* read_key() returns 0 on EOF */
827 if (cur_time - last_time >= 100000) {
828 key = read_key();
829 last_time = cur_time;
830 }else
831 key = -1;
832 if (key == 'q') {
833 av_log(NULL, AV_LOG_INFO, "\n\n[q] command received. Exiting.\n\n");
834 return AVERROR_EXIT;
835 }
836 if (key == '+') av_log_set_level(av_log_get_level()+10);
837 if (key == '-') av_log_set_level(av_log_get_level()-10);
838 if (key == 'c' || key == 'C'){
839 char buf[4096], target[64], command[256], arg[256] = {0};
840 double time;
841 int k, n = 0;
842 fprintf(stderr, "\nEnter command: <target>|all <time>|-1 <command>[ <argument>]\n");
843 i = 0;
844 set_tty_echo(1);
845 while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
846 if (k > 0)
847 buf[i++] = k;
848 buf[i] = 0;
849 set_tty_echo(0);
850 fprintf(stderr, "\n");
851 if (k > 0 &&
852 (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
853 av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
854 target, time, command, arg);
855 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
856 if (ost->fg_simple)
857 fg_send_command(ost->fg_simple, time, target, command, arg,
858 key == 'C');
859 }
860 for (i = 0; i < nb_filtergraphs; i++)
861 fg_send_command(filtergraphs[i], time, target, command, arg,
862 key == 'C');
863 } else {
864 av_log(NULL, AV_LOG_ERROR,
865 "Parse error, at least 3 arguments were expected, "
866 "only %d given in string '%s'\n", n, buf);
867 }
868 }
869 if (key == '?'){
870 fprintf(stderr, "key function\n"
871 "? show this help\n"
872 "+ increase verbosity\n"
873 "- decrease verbosity\n"
874 "c Send command to first matching filter supporting it\n"
875 "C Send/Queue command to all matching filters\n"
876 "h dump packets/hex press to cycle through the 3 states\n"
877 "q quit\n"
878 "s Show QP histogram\n"
879 );
880 }
881 return 0;
882 }
883
884 /*
885 * The following code is the main loop of the file converter
886 */
887 8543 static int transcode(Scheduler *sch)
888 {
889 8543 int ret = 0;
890 8543 int64_t timer_start, transcode_ts = 0;
891
892 8543 print_stream_maps();
893
894 8543 atomic_store(&transcode_init_done, 1);
895
896 8543 ret = sch_start(sch);
897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8543 times.
8543 if (ret < 0)
898 return ret;
899
900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8543 times.
8543 if (stdin_interaction) {
901 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
902 }
903
904 8543 timer_start = av_gettime_relative();
905
906
2/2
✓ Branch 1 taken 17984 times.
✓ Branch 2 taken 8543 times.
26527 while (!sch_wait(sch, stats_period, &transcode_ts)) {
907 17984 int64_t cur_time= av_gettime_relative();
908
909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17984 times.
17984 if (received_nb_signals)
910 break;
911
912 /* if 'q' pressed, exits */
913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17984 times.
17984 if (stdin_interaction)
914 if (check_keyboard_interaction(cur_time) < 0)
915 break;
916
917 /* dump report by using the output first video and audio streams */
918 17984 print_report(0, timer_start, cur_time, transcode_ts);
919 }
920
921 8543 ret = sch_stop(sch, &transcode_ts);
922
923 /* write the trailer if needed */
924
2/2
✓ Branch 0 taken 8547 times.
✓ Branch 1 taken 8543 times.
17090 for (int i = 0; i < nb_output_files; i++) {
925 8547 int err = of_write_trailer(output_files[i]);
926 8547 ret = err_merge(ret, err);
927 }
928
929 8543 term_exit();
930
931 /* dump report by using the first video and audio streams */
932 8543 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
933
934 8543 return ret;
935 }
936
937 8543 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
938 {
939 8543 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
940 #if HAVE_GETRUSAGE
941 struct rusage rusage;
942
943 8543 getrusage(RUSAGE_SELF, &rusage);
944 8543 time_stamps.user_usec =
945 8543 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
946 8543 time_stamps.sys_usec =
947 8543 (rusage.ru_stime.tv_sec * 1000000LL) + rusage.ru_stime.tv_usec;
948 #elif HAVE_GETPROCESSTIMES
949 HANDLE proc;
950 FILETIME c, e, k, u;
951 proc = GetCurrentProcess();
952 GetProcessTimes(proc, &c, &e, &k, &u);
953 time_stamps.user_usec =
954 ((int64_t)u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
955 time_stamps.sys_usec =
956 ((int64_t)k.dwHighDateTime << 32 | k.dwLowDateTime) / 10;
957 #else
958 time_stamps.user_usec = time_stamps.sys_usec = 0;
959 #endif
960 8543 return time_stamps;
961 }
962
963 static int64_t getmaxrss(void)
964 {
965 #if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
966 struct rusage rusage;
967 getrusage(RUSAGE_SELF, &rusage);
968 return (int64_t)rusage.ru_maxrss * 1024;
969 #elif HAVE_GETPROCESSMEMORYINFO
970 HANDLE proc;
971 PROCESS_MEMORY_COUNTERS memcounters;
972 proc = GetCurrentProcess();
973 memcounters.cb = sizeof(memcounters);
974 GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
975 return memcounters.PeakPagefileUsage;
976 #else
977 return 0;
978 #endif
979 }
980
981 8546 int main(int argc, char **argv)
982 {
983 8546 Scheduler *sch = NULL;
984
985 int ret;
986 BenchmarkTimeStamps ti;
987
988 8546 init_dynload();
989
990 8546 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
991
992 8546 av_log_set_flags(AV_LOG_SKIP_REPEATED);
993 8546 parse_loglevel(argc, argv, options);
994
995 #if CONFIG_AVDEVICE
996 8546 avdevice_register_all();
997 #endif
998 8546 avformat_network_init();
999
1000 8546 show_banner(argc, argv, options);
1001
1002 8546 sch = sch_alloc();
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8546 times.
8546 if (!sch) {
1004 ret = AVERROR(ENOMEM);
1005 goto finish;
1006 }
1007
1008 /* parse options and open all input/output files */
1009 8546 ret = ffmpeg_parse_options(argc, argv, sch);
1010
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8543 times.
8546 if (ret < 0)
1011 3 goto finish;
1012
1013
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8543 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8543 if (nb_output_files <= 0 && nb_input_files == 0) {
1014 show_usage();
1015 av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
1016 ret = 1;
1017 goto finish;
1018 }
1019
1020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8543 times.
8543 if (nb_output_files <= 0) {
1021 av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
1022 ret = 1;
1023 goto finish;
1024 }
1025
1026 #if CONFIG_MEDIACODEC
1027 android_binder_threadpool_init_if_required();
1028 #endif
1029
1030 8543 current_time = ti = get_benchmark_time_stamps();
1031 8543 ret = transcode(sch);
1032
3/4
✓ Branch 0 taken 8541 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8541 times.
8543 if (ret >= 0 && do_benchmark) {
1033 int64_t utime, stime, rtime;
1034 current_time = get_benchmark_time_stamps();
1035 utime = current_time.user_usec - ti.user_usec;
1036 stime = current_time.sys_usec - ti.sys_usec;
1037 rtime = current_time.real_usec - ti.real_usec;
1038 av_log(NULL, AV_LOG_INFO,
1039 "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
1040 utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
1041 }
1042
1043
1/2
✓ Branch 0 taken 8543 times.
✗ Branch 1 not taken.
17086 ret = received_nb_signals ? 255 :
1044
2/2
✓ Branch 0 taken 8542 times.
✓ Branch 1 taken 1 times.
8543 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1045
1046 8546 finish:
1047
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8544 times.
8546 if (ret == AVERROR_EXIT)
1048 2 ret = 0;
1049
1050 8546 ffmpeg_cleanup(ret);
1051
1052 8546 sch_free(&sch);
1053
1054 8546 av_log(NULL, AV_LOG_VERBOSE, "\n");
1055 8546 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1056
1057 8546 return ret;
1058 }
1059