FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2026-05-14 01:12:21
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 17115 static void term_exit_sigsafe(void)
128 {
129 #if HAVE_TERMIOS_H
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17115 times.
17115 if(restore_tty)
131 tcsetattr (0, TCSANOW, &oldtty);
132 #endif
133 17115 }
134
135 17115 void term_exit(void)
136 {
137 17115 av_log(NULL, AV_LOG_QUIET, "%s", "");
138 17115 term_exit_sigsafe();
139 17115 }
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 8557 void term_init(void)
206 {
207 #if defined __linux__
208 8557 struct sigaction action = {0};
209 8557 action.sa_handler = sigterm_handler;
210
211 /* block other interrupts while processing this one */
212 8557 sigfillset(&action.sa_mask);
213
214 /* restart interruptible functions (i.e. don't fail with EINTR) */
215 8557 action.sa_flags = SA_RESTART;
216 #endif
217
218 #if HAVE_TERMIOS_H
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8557 times.
8557 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 8557 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
241 8557 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
242 #ifdef SIGXCPU
243 8557 SIGNAL(SIGXCPU, sigterm_handler);
244 #endif
245 #ifdef SIGPIPE
246 8557 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
247 #endif
248 #if HAVE_SETCONSOLECTRLHANDLER
249 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
250 #endif
251 8557 }
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 800808 static int decode_interrupt_cb(void *ctx)
308 {
309 800808 return received_nb_signals > atomic_load(&transcode_init_done);
310 }
311
312 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
313
314 8559 static void ffmpeg_cleanup(int ret)
315 {
316
2/6
✓ Branch 0 taken 8559 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8559 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8559 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 8559 times.
8559 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 8559 times.
9819 for (int i = 0; i < nb_filtergraphs; i++)
325 1260 fg_free(&filtergraphs[i]);
326 8559 av_freep(&filtergraphs);
327
328
2/2
✓ Branch 0 taken 8560 times.
✓ Branch 1 taken 8559 times.
17119 for (int i = 0; i < nb_output_files; i++)
329 8560 of_free(&output_files[i]);
330
331
2/2
✓ Branch 0 taken 7468 times.
✓ Branch 1 taken 8559 times.
16027 for (int i = 0; i < nb_input_files; i++)
332 7468 ifile_close(&input_files[i]);
333
334
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8559 times.
8560 for (int i = 0; i < nb_decoders; i++)
335 1 dec_free(&decoders[i]);
336 8559 av_freep(&decoders);
337
338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8559 times.
8559 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 8559 av_freep(&vstats_filename);
345 8559 of_enc_stats_close();
346
347 8559 hw_device_free_all();
348
349 8559 av_freep(&filter_nbthreads);
350
351 8559 av_freep(&print_graphs_file);
352 8559 av_freep(&print_graphs_format);
353
354 8559 av_freep(&input_files);
355 8559 av_freep(&output_files);
356
357 8559 uninit_opts();
358
359 8559 avformat_network_deinit();
360
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8559 times.
8559 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 8556 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
8559 } else if (ret && atomic_load(&transcode_init_done)) {
365 2 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
366 }
367 8559 term_exit();
368 8559 ffmpeg_exited = 1;
369 8559 }
370
371 35305 OutputStream *ost_iter(OutputStream *prev)
372 {
373
2/2
✓ Branch 0 taken 18166 times.
✓ Branch 1 taken 17139 times.
35305 int of_idx = prev ? prev->file->index : 0;
374
2/2
✓ Branch 0 taken 18166 times.
✓ Branch 1 taken 17139 times.
35305 int ost_idx = prev ? prev->index + 1 : 0;
375
376
2/2
✓ Branch 0 taken 35313 times.
✓ Branch 1 taken 17139 times.
52452 for (; of_idx < nb_output_files; of_idx++) {
377 35313 OutputFile *of = output_files[of_idx];
378
2/2
✓ Branch 0 taken 18166 times.
✓ Branch 1 taken 17147 times.
35313 if (ost_idx < of->nb_streams)
379 18166 return of->streams[ost_idx];
380
381 17147 ost_idx = 0;
382 }
383
384 17139 return NULL;
385 }
386
387 16873 InputStream *ist_iter(InputStream *prev)
388 {
389
2/2
✓ Branch 0 taken 8133 times.
✓ Branch 1 taken 8740 times.
16873 int if_idx = prev ? prev->file->index : 0;
390
2/2
✓ Branch 0 taken 8133 times.
✓ Branch 1 taken 8740 times.
16873 int ist_idx = prev ? prev->index + 1 : 0;
391
392
2/2
✓ Branch 0 taken 15806 times.
✓ Branch 1 taken 8576 times.
24382 for (; if_idx < nb_input_files; if_idx++) {
393 15806 InputFile *f = input_files[if_idx];
394
2/2
✓ Branch 0 taken 8297 times.
✓ Branch 1 taken 7509 times.
15806 if (ist_idx < f->nb_streams)
395 8297 return f->streams[ist_idx];
396
397 7509 ist_idx = 0;
398 }
399
400 8576 return NULL;
401 }
402
403 1625984 static void frame_data_free(void *opaque, uint8_t *data)
404 {
405 1625984 FrameData *fd = (FrameData *)data;
406
407 1625984 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
408 1625984 avcodec_parameters_free(&fd->par_enc);
409
410 1625984 av_free(data);
411 1625984 }
412
413 3232924 static int frame_data_ensure(AVBufferRef **dst, int writable)
414 {
415 3232924 AVBufferRef *src = *dst;
416
417
6/6
✓ Branch 0 taken 2689884 times.
✓ Branch 1 taken 543040 times.
✓ Branch 2 taken 2682923 times.
✓ Branch 3 taken 6961 times.
✓ Branch 5 taken 1082944 times.
✓ Branch 6 taken 1599979 times.
3232924 if (!src || (writable && !av_buffer_is_writable(src))) {
418 FrameData *fd;
419
420 1625984 fd = av_mallocz(sizeof(*fd));
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1625984 times.
1625984 if (!fd)
422 return AVERROR(ENOMEM);
423
424 1625984 *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 1625984 times.
1625984 if (!*dst) {
427 av_buffer_unref(&src);
428 av_freep(&fd);
429 return AVERROR(ENOMEM);
430 }
431
432
2/2
✓ Branch 0 taken 1082944 times.
✓ Branch 1 taken 543040 times.
1625984 if (src) {
433 1082944 const FrameData *fd_src = (const FrameData *)src->data;
434
435 1082944 memcpy(fd, fd_src, sizeof(*fd));
436 1082944 fd->par_enc = NULL;
437 1082944 fd->side_data = NULL;
438 1082944 fd->nb_side_data = 0;
439
440
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1082942 times.
1082944 if (fd_src->par_enc) {
441 2 int ret = 0;
442
443 2 fd->par_enc = avcodec_parameters_alloc();
444 4 ret = fd->par_enc ?
445
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 avcodec_parameters_copy(fd->par_enc, fd_src->par_enc) :
446 AVERROR(ENOMEM);
447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 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 176 times.
✓ Branch 1 taken 1082768 times.
1082944 if (fd_src->nb_side_data) {
455 176 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
456 176 fd_src->side_data, fd_src->nb_side_data, 0);
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 if (ret < 0) {
458 av_buffer_unref(dst);
459 av_buffer_unref(&src);
460 return ret;
461 }
462 }
463
464 1082944 av_buffer_unref(&src);
465 } else {
466 543040 fd->dec.frame_num = UINT64_MAX;
467 543040 fd->dec.pts = AV_NOPTS_VALUE;
468
469
2/2
✓ Branch 0 taken 3801280 times.
✓ Branch 1 taken 543040 times.
4344320 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
470 3801280 fd->wallclock[i] = INT64_MIN;
471 }
472 }
473
474 3232924 return 0;
475 }
476
477 1801130 FrameData *frame_data(AVFrame *frame)
478 {
479 1801130 int ret = frame_data_ensure(&frame->opaque_ref, 1);
480
1/2
✓ Branch 0 taken 1801130 times.
✗ Branch 1 not taken.
1801130 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 1423548 FrameData *packet_data(AVPacket *pkt)
490 {
491 1423548 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
492
1/2
✓ Branch 0 taken 1423548 times.
✗ Branch 1 not taken.
1423548 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 16027 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
502 void *logctx, int decode)
503 {
504 16027 const AVClass *class = avcodec_get_class();
505 16027 const AVClass *fclass = avformat_get_class();
506
507
2/2
✓ Branch 0 taken 7467 times.
✓ Branch 1 taken 8560 times.
16027 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
508 AV_OPT_FLAG_ENCODING_PARAM;
509 16027 const AVDictionaryEntry *e = NULL;
510
511
2/2
✓ Branch 1 taken 49798 times.
✓ Branch 2 taken 16027 times.
65825 while ((e = av_dict_iterate(opts, e))) {
512 const AVOption *option, *foption;
513 char *optname, *p;
514
515
2/2
✓ Branch 1 taken 48840 times.
✓ Branch 2 taken 958 times.
49798 if (av_dict_get(opts_used, e->key, NULL, 0))
516 48841 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 16027 return 0;
549 }
550
551 3227372 void update_benchmark(const char *fmt, ...)
552 {
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3227372 times.
3227372 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 3227372 }
571
572 26809 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 26809 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 26809 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 26728 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 18226 times.
✓ Branch 3 taken 8502 times.
✓ Branch 4 taken 18226 times.
✗ Branch 5 not taken.
26809 if (!print_stats && !is_last_report && !progress_avio)
589 18226 return;
590
591
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 8556 times.
8583 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 8583 t = (cur_time-timer_start) / 1000000.0;
602
603 8583 vid = 0;
604 8583 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
605 8583 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
606
607
2/2
✓ Branch 2 taken 9097 times.
✓ Branch 3 taken 8583 times.
17680 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
608
2/2
✓ Branch 0 taken 8319 times.
✓ Branch 1 taken 778 times.
9097 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
609
610
4/4
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 8812 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 201 times.
9097 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 8812 times.
✓ Branch 1 taken 285 times.
✓ Branch 2 taken 7189 times.
✓ Branch 3 taken 1623 times.
9097 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 2001 times.
✓ Branch 1 taken 5188 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 8572 times.
8583 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 117 times.
✓ Branch 1 taken 8466 times.
8583 us = FFABS64U(pts) % AV_TIME_BASE;
646
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8466 times.
8583 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
647
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8466 times.
8583 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
648
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8466 times.
8583 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
649
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 8480 times.
8583 hours_sign = (pts < 0) ? "-" : "";
650
651
6/6
✓ Branch 0 taken 8480 times.
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 8466 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 8336 times.
✓ Branch 5 taken 130 times.
8583 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
652
3/4
✓ Branch 0 taken 8480 times.
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 8480 times.
✗ Branch 3 not taken.
8583 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 8452 times.
8583 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
655 8452 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
656
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 8480 times.
8583 if (pts == AV_NOPTS_VALUE) {
657 103 av_bprintf(&buf, "N/A ");
658 } else {
659 8480 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 8336 times.
8583 if (bitrate < 0) {
664 247 av_bprintf(&buf, "bitrate=N/A");
665 247 av_bprintf(&buf_script, "bitrate=N/A\n");
666 }else{
667 8336 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
668 8336 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
669 }
670
671
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 8452 times.
8583 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
672 8452 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
673
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 8480 times.
8583 if (pts == AV_NOPTS_VALUE) {
674 103 av_bprintf(&buf_script, "out_time_us=N/A\n");
675 103 av_bprintf(&buf_script, "out_time_ms=N/A\n");
676 103 av_bprintf(&buf_script, "out_time=N/A\n");
677 } else {
678 8480 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
679 8480 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
680 8480 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 8567 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8561 times.
8583 if (nb_frames_dup || nb_frames_drop)
685 22 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
686 8583 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
687 8583 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
688
689
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 8480 times.
8583 if (speed < 0) {
690 103 av_bprintf(&buf, " speed=N/A");
691 103 av_bprintf(&buf_script, "speed=N/A\n");
692 } else {
693 8480 av_bprintf(&buf, " speed=%4.3gx", speed);
694 8480 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
695 }
696
697 8583 secs = (int)t;
698 8583 ms = (int)((t - secs) * 1000);
699 8583 mins = secs / 60;
700 8583 secs %= 60;
701 8583 hours = mins / 60;
702 8583 mins %= 60;
703
704 8583 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
705
706
3/4
✓ Branch 0 taken 8502 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 8502 times.
✗ Branch 3 not taken.
8583 if (print_stats || is_last_report) {
707
2/2
✓ Branch 0 taken 8556 times.
✓ Branch 1 taken 27 times.
8583 const char end = is_last_report ? '\n' : '\r';
708
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8583 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8583 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
709 fprintf(stderr, "%s %c", buf.str, end);
710 } else
711 8583 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
712
713 8583 fflush(stderr);
714 }
715 8583 av_bprint_finalize(&buf, NULL);
716
717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8583 times.
8583 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 8583 first_report = 0;
732 }
733
734 8556 static void print_stream_maps(void)
735 {
736 8556 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
737
2/2
✓ Branch 2 taken 8077 times.
✓ Branch 3 taken 8556 times.
16633 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
738
2/2
✓ Branch 0 taken 7028 times.
✓ Branch 1 taken 8077 times.
15105 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 9069 times.
✓ Branch 3 taken 8556 times.
17625 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
751
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9068 times.
9069 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 819 times.
✓ Branch 3 taken 1394 times.
✓ Branch 4 taken 6855 times.
9068 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 7674 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
770 7674 ost->ist->file->index,
771 7674 ost->ist->index,
772 7674 ost->file->index,
773 ost->index);
774
2/2
✓ Branch 0 taken 6897 times.
✓ Branch 1 taken 777 times.
7674 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 777 av_log(NULL, AV_LOG_INFO, " (copy)");
806 7674 av_log(NULL, AV_LOG_INFO, "\n");
807 }
808 8556 }
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 8556 static int transcode(Scheduler *sch)
888 {
889 8556 int ret = 0;
890 8556 int64_t timer_start, transcode_ts = 0;
891
892 8556 print_stream_maps();
893
894 8556 atomic_store(&transcode_init_done, 1);
895
896 8556 ret = sch_start(sch);
897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8556 times.
8556 if (ret < 0)
898 return ret;
899
900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8556 times.
8556 if (stdin_interaction) {
901 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
902 }
903
904 8556 timer_start = av_gettime_relative();
905
906
2/2
✓ Branch 1 taken 18253 times.
✓ Branch 2 taken 8556 times.
26809 while (!sch_wait(sch, stats_period, &transcode_ts)) {
907 18253 int64_t cur_time= av_gettime_relative();
908
909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18253 times.
18253 if (received_nb_signals)
910 break;
911
912 /* if 'q' pressed, exits */
913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18253 times.
18253 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 18253 print_report(0, timer_start, cur_time, transcode_ts);
919 }
920
921 8556 ret = sch_stop(sch, &transcode_ts);
922
923 /* write the trailer if needed */
924
2/2
✓ Branch 0 taken 8560 times.
✓ Branch 1 taken 8556 times.
17116 for (int i = 0; i < nb_output_files; i++) {
925 8560 int err = of_write_trailer(output_files[i]);
926 8560 ret = err_merge(ret, err);
927 }
928
929 8556 term_exit();
930
931 /* dump report by using the first video and audio streams */
932 8556 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
933
934 8556 return ret;
935 }
936
937 8556 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
938 {
939 8556 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
940 #if HAVE_GETRUSAGE
941 struct rusage rusage;
942
943 8556 getrusage(RUSAGE_SELF, &rusage);
944 8556 time_stamps.user_usec =
945 8556 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
946 8556 time_stamps.sys_usec =
947 8556 (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 8556 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 8559 int main(int argc, char **argv)
982 {
983 8559 Scheduler *sch = NULL;
984
985 int ret;
986 BenchmarkTimeStamps ti;
987
988 8559 init_dynload();
989
990 8559 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
991
992 8559 av_log_set_flags(AV_LOG_SKIP_REPEATED);
993 8559 parse_loglevel(argc, argv, options);
994
995 #if CONFIG_AVDEVICE
996 8559 avdevice_register_all();
997 #endif
998 8559 avformat_network_init();
999
1000 8559 show_banner(argc, argv, options);
1001
1002 8559 sch = sch_alloc();
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8559 times.
8559 if (!sch) {
1004 ret = AVERROR(ENOMEM);
1005 goto finish;
1006 }
1007
1008 /* parse options and open all input/output files */
1009 8559 ret = ffmpeg_parse_options(argc, argv, sch);
1010
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8556 times.
8559 if (ret < 0)
1011 3 goto finish;
1012
1013
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8556 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8556 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 8556 times.
8556 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 8556 current_time = ti = get_benchmark_time_stamps();
1031 8556 ret = transcode(sch);
1032
3/4
✓ Branch 0 taken 8554 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8554 times.
8556 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 8556 times.
✗ Branch 1 not taken.
17112 ret = received_nb_signals ? 255 :
1044
2/2
✓ Branch 0 taken 8555 times.
✓ Branch 1 taken 1 times.
8556 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1045
1046 8559 finish:
1047
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8557 times.
8559 if (ret == AVERROR_EXIT)
1048 2 ret = 0;
1049
1050 8559 ffmpeg_cleanup(ret);
1051
1052 8559 sch_free(&sch);
1053
1054 8559 av_log(NULL, AV_LOG_VERBOSE, "\n");
1055 8559 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1056
1057 8559 return ret;
1058 }
1059