FFmpeg coverage


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

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2003 Fabrice Bellard
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * multimedia converter based on the FFmpeg libraries
24 */
25
26 #include "config.h"
27
28 #include <errno.h>
29 #include <limits.h>
30 #include <stdatomic.h>
31 #include <stdint.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35
36 #if HAVE_IO_H
37 #include <io.h>
38 #endif
39 #if HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 #if HAVE_SYS_RESOURCE_H
44 #include <sys/time.h>
45 #include <sys/types.h>
46 #include <sys/resource.h>
47 #elif HAVE_GETPROCESSTIMES
48 #include <windows.h>
49 #endif
50 #if HAVE_GETPROCESSMEMORYINFO
51 #include <windows.h>
52 #include <psapi.h>
53 #endif
54 #if HAVE_SETCONSOLECTRLHANDLER
55 #include <windows.h>
56 #endif
57
58 #if HAVE_SYS_SELECT_H
59 #include <sys/select.h>
60 #endif
61
62 #if HAVE_TERMIOS_H
63 #include <fcntl.h>
64 #include <sys/ioctl.h>
65 #include <sys/time.h>
66 #include <termios.h>
67 #elif HAVE_KBHIT
68 #include <conio.h>
69 #endif
70
71 #include "libavutil/bprint.h"
72 #include "libavutil/dict.h"
73 #include "libavutil/mem.h"
74 #include "libavutil/time.h"
75
76 #include "libavformat/avformat.h"
77
78 #include "libavdevice/avdevice.h"
79
80 #include "cmdutils.h"
81 #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 16915 static void term_exit_sigsafe(void)
128 {
129 #if HAVE_TERMIOS_H
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16915 times.
16915 if(restore_tty)
131 tcsetattr (0, TCSANOW, &oldtty);
132 #endif
133 16915 }
134
135 16915 void term_exit(void)
136 {
137 16915 av_log(NULL, AV_LOG_QUIET, "%s", "");
138 16915 term_exit_sigsafe();
139 16915 }
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 8457 void term_init(void)
206 {
207 #if defined __linux__
208 8457 struct sigaction action = {0};
209 8457 action.sa_handler = sigterm_handler;
210
211 /* block other interrupts while processing this one */
212 8457 sigfillset(&action.sa_mask);
213
214 /* restart interruptible functions (i.e. don't fail with EINTR) */
215 8457 action.sa_flags = SA_RESTART;
216 #endif
217
218 #if HAVE_TERMIOS_H
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 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 8457 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
241 8457 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
242 #ifdef SIGXCPU
243 8457 SIGNAL(SIGXCPU, sigterm_handler);
244 #endif
245 #ifdef SIGPIPE
246 8457 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
247 #endif
248 #if HAVE_SETCONSOLECTRLHANDLER
249 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
250 #endif
251 8457 }
252
253 /* read a key without blocking */
254 static int read_key(void)
255 {
256 unsigned char ch = -1;
257 #if HAVE_TERMIOS_H
258 int n = 1;
259 struct timeval tv;
260 fd_set rfds;
261
262 FD_ZERO(&rfds);
263 FD_SET(0, &rfds);
264 tv.tv_sec = 0;
265 tv.tv_usec = 0;
266 n = select(1, &rfds, NULL, NULL, &tv);
267 if (n > 0) {
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 if (read(0, &ch, 1) == 1)
293 return ch;
294 return 0;
295 }else{
296 return -1;
297 }
298 }
299 # endif
300 if(kbhit())
301 return(getch());
302 #endif
303 return ch;
304 }
305
306 797176 static int decode_interrupt_cb(void *ctx)
307 {
308 797176 return received_nb_signals > atomic_load(&transcode_init_done);
309 }
310
311 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
312
313 8458 static void ffmpeg_cleanup(int ret)
314 {
315
2/6
✓ Branch 0 taken 8458 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8458 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8458 if ((print_graphs || print_graphs_file) && nb_output_files > 0)
316 print_filtergraphs(filtergraphs, nb_filtergraphs, input_files, nb_input_files, output_files, nb_output_files);
317
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8458 times.
8458 if (do_benchmark) {
319 int64_t maxrss = getmaxrss() / 1024;
320 av_log(NULL, AV_LOG_INFO, "bench: maxrss=%"PRId64"KiB\n", maxrss);
321 }
322
323
2/2
✓ Branch 0 taken 1253 times.
✓ Branch 1 taken 8458 times.
9711 for (int i = 0; i < nb_filtergraphs; i++)
324 1253 fg_free(&filtergraphs[i]);
325 8458 av_freep(&filtergraphs);
326
327
2/2
✓ Branch 0 taken 8461 times.
✓ Branch 1 taken 8458 times.
16919 for (int i = 0; i < nb_output_files; i++)
328 8461 of_free(&output_files[i]);
329
330
2/2
✓ Branch 0 taken 7367 times.
✓ Branch 1 taken 8458 times.
15825 for (int i = 0; i < nb_input_files; i++)
331 7367 ifile_close(&input_files[i]);
332
333
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8458 times.
8459 for (int i = 0; i < nb_decoders; i++)
334 1 dec_free(&decoders[i]);
335 8458 av_freep(&decoders);
336
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8458 times.
8458 if (vstats_file) {
338 if (fclose(vstats_file))
339 av_log(NULL, AV_LOG_ERROR,
340 "Error closing vstats file, loss of information possible: %s\n",
341 av_err2str(AVERROR(errno)));
342 }
343 8458 av_freep(&vstats_filename);
344 8458 of_enc_stats_close();
345
346 8458 hw_device_free_all();
347
348 8458 av_freep(&filter_nbthreads);
349
350 8458 av_freep(&print_graphs_file);
351 8458 av_freep(&print_graphs_format);
352
353 8458 av_freep(&input_files);
354 8458 av_freep(&output_files);
355
356 8458 uninit_opts();
357
358 8458 avformat_network_deinit();
359
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8458 times.
8458 if (received_sigterm) {
361 av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n",
362 (int) received_sigterm);
363
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8457 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
8458 } else if (ret && atomic_load(&transcode_init_done)) {
364 1 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
365 }
366 8458 term_exit();
367 8458 ffmpeg_exited = 1;
368 8458 }
369
370 34867 OutputStream *ost_iter(OutputStream *prev)
371 {
372
2/2
✓ Branch 0 taken 17928 times.
✓ Branch 1 taken 16939 times.
34867 int of_idx = prev ? prev->file->index : 0;
373
2/2
✓ Branch 0 taken 17928 times.
✓ Branch 1 taken 16939 times.
34867 int ost_idx = prev ? prev->index + 1 : 0;
374
375
2/2
✓ Branch 0 taken 34875 times.
✓ Branch 1 taken 16939 times.
51814 for (; of_idx < nb_output_files; of_idx++) {
376 34875 OutputFile *of = output_files[of_idx];
377
2/2
✓ Branch 0 taken 17928 times.
✓ Branch 1 taken 16947 times.
34875 if (ost_idx < of->nb_streams)
378 17928 return of->streams[ost_idx];
379
380 16947 ost_idx = 0;
381 }
382
383 16939 return NULL;
384 }
385
386 16644 InputStream *ist_iter(InputStream *prev)
387 {
388
2/2
✓ Branch 0 taken 8003 times.
✓ Branch 1 taken 8641 times.
16644 int if_idx = prev ? prev->file->index : 0;
389
2/2
✓ Branch 0 taken 8003 times.
✓ Branch 1 taken 8641 times.
16644 int ist_idx = prev ? prev->index + 1 : 0;
390
391
2/2
✓ Branch 0 taken 15576 times.
✓ Branch 1 taken 8477 times.
24053 for (; if_idx < nb_input_files; if_idx++) {
392 15576 InputFile *f = input_files[if_idx];
393
2/2
✓ Branch 0 taken 8167 times.
✓ Branch 1 taken 7409 times.
15576 if (ist_idx < f->nb_streams)
394 8167 return f->streams[ist_idx];
395
396 7409 ist_idx = 0;
397 }
398
399 8477 return NULL;
400 }
401
402 1446201 static void frame_data_free(void *opaque, uint8_t *data)
403 {
404 1446201 FrameData *fd = (FrameData *)data;
405
406 1446201 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
407 1446201 avcodec_parameters_free(&fd->par_enc);
408
409 1446201 av_free(data);
410 1446201 }
411
412 2907851 static int frame_data_ensure(AVBufferRef **dst, int writable)
413 {
414 2907851 AVBufferRef *src = *dst;
415
416
6/6
✓ Branch 0 taken 2403692 times.
✓ Branch 1 taken 504159 times.
✓ Branch 2 taken 2396794 times.
✓ Branch 3 taken 6898 times.
✓ Branch 5 taken 942042 times.
✓ Branch 6 taken 1454752 times.
2907851 if (!src || (writable && !av_buffer_is_writable(src))) {
417 FrameData *fd;
418
419 1446201 fd = av_mallocz(sizeof(*fd));
420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1446201 times.
1446201 if (!fd)
421 return AVERROR(ENOMEM);
422
423 1446201 *dst = av_buffer_create((uint8_t *)fd, sizeof(*fd),
424 frame_data_free, NULL, 0);
425
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1446201 times.
1446201 if (!*dst) {
426 av_buffer_unref(&src);
427 av_freep(&fd);
428 return AVERROR(ENOMEM);
429 }
430
431
2/2
✓ Branch 0 taken 942042 times.
✓ Branch 1 taken 504159 times.
1446201 if (src) {
432 942042 const FrameData *fd_src = (const FrameData *)src->data;
433
434 942042 memcpy(fd, fd_src, sizeof(*fd));
435 942042 fd->par_enc = NULL;
436 942042 fd->side_data = NULL;
437 942042 fd->nb_side_data = 0;
438
439
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 942041 times.
942042 if (fd_src->par_enc) {
440 1 int ret = 0;
441
442 1 fd->par_enc = avcodec_parameters_alloc();
443 2 ret = fd->par_enc ?
444
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 avcodec_parameters_copy(fd->par_enc, fd_src->par_enc) :
445 AVERROR(ENOMEM);
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0) {
447 av_buffer_unref(dst);
448 av_buffer_unref(&src);
449 return ret;
450 }
451 }
452
453
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 941864 times.
942042 if (fd_src->nb_side_data) {
454 178 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
455 178 fd_src->side_data, fd_src->nb_side_data, 0);
456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
178 if (ret < 0) {
457 av_buffer_unref(dst);
458 av_buffer_unref(&src);
459 return ret;
460 }
461 }
462
463 942042 av_buffer_unref(&src);
464 } else {
465 504159 fd->dec.frame_num = UINT64_MAX;
466 504159 fd->dec.pts = AV_NOPTS_VALUE;
467
468
2/2
✓ Branch 0 taken 3529113 times.
✓ Branch 1 taken 504159 times.
4033272 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
469 3529113 fd->wallclock[i] = INT64_MIN;
470 }
471 }
472
473 2907851 return 0;
474 }
475
476 1621632 FrameData *frame_data(AVFrame *frame)
477 {
478 1621632 int ret = frame_data_ensure(&frame->opaque_ref, 1);
479
1/2
✓ Branch 0 taken 1621632 times.
✗ Branch 1 not taken.
1621632 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
480 }
481
482 8177 const FrameData *frame_data_c(AVFrame *frame)
483 {
484 8177 int ret = frame_data_ensure(&frame->opaque_ref, 0);
485
1/2
✓ Branch 0 taken 8177 times.
✗ Branch 1 not taken.
8177 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
486 }
487
488 1278042 FrameData *packet_data(AVPacket *pkt)
489 {
490 1278042 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
491
1/2
✓ Branch 0 taken 1278042 times.
✗ Branch 1 not taken.
1278042 return ret < 0 ? NULL : (FrameData*)pkt->opaque_ref->data;
492 }
493
494 const FrameData *packet_data_c(AVPacket *pkt)
495 {
496 int ret = frame_data_ensure(&pkt->opaque_ref, 0);
497 return ret < 0 ? NULL : (const FrameData*)pkt->opaque_ref->data;
498 }
499
500 15828 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
501 void *logctx, int decode)
502 {
503 15828 const AVClass *class = avcodec_get_class();
504 15828 const AVClass *fclass = avformat_get_class();
505
506
2/2
✓ Branch 0 taken 7367 times.
✓ Branch 1 taken 8461 times.
15828 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
507 AV_OPT_FLAG_ENCODING_PARAM;
508 15828 const AVDictionaryEntry *e = NULL;
509
510
2/2
✓ Branch 1 taken 49214 times.
✓ Branch 2 taken 15828 times.
65042 while ((e = av_dict_iterate(opts, e))) {
511 const AVOption *option, *foption;
512 char *optname, *p;
513
514
2/2
✓ Branch 1 taken 48387 times.
✓ Branch 2 taken 827 times.
49214 if (av_dict_get(opts_used, e->key, NULL, 0))
515 48388 continue;
516
517 827 optname = av_strdup(e->key);
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 827 times.
827 if (!optname)
519 return AVERROR(ENOMEM);
520
521 827 p = strchr(optname, ':');
522
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 816 times.
827 if (p)
523 11 *p = 0;
524
525 827 option = av_opt_find(&class, optname, NULL, 0,
526 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
527 827 foption = av_opt_find(&fclass, optname, NULL, 0,
528 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
529 827 av_freep(&optname);
530
3/4
✓ Branch 0 taken 827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 826 times.
827 if (!option || foption)
531 1 continue;
532
533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 826 times.
826 if (!(option->flags & flag)) {
534 av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s "
535 "option.\n", e->key, option->help ? option->help : "",
536 decode ? "decoding" : "encoding");
537 return AVERROR(EINVAL);
538 }
539
540 826 av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
541 "for any stream. The most likely reason is either wrong type "
542 "(e.g. a video option with no video streams) or that it is a "
543 "private option of some decoder which was not actually used "
544
2/2
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 4 times.
1652 "for any stream.\n", e->key, option->help ? option->help : "");
545 }
546
547 15828 return 0;
548 }
549
550 2870717 void update_benchmark(const char *fmt, ...)
551 {
552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2870717 times.
2870717 if (do_benchmark_all) {
553 BenchmarkTimeStamps t = get_benchmark_time_stamps();
554 va_list va;
555 char buf[1024];
556
557 if (fmt) {
558 va_start(va, fmt);
559 vsnprintf(buf, sizeof(buf), fmt, va);
560 va_end(va);
561 av_log(NULL, AV_LOG_INFO,
562 "bench: %8" PRIu64 " user %8" PRIu64 " sys %8" PRIu64 " real %s \n",
563 t.user_usec - current_time.user_usec,
564 t.sys_usec - current_time.sys_usec,
565 t.real_usec - current_time.real_usec, buf);
566 }
567 current_time = t;
568 }
569 2870717 }
570
571 26447 static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts)
572 {
573 AVBPrint buf, buf_script;
574 26447 int64_t total_size = of_filesize(output_files[0]);
575 int vid;
576 double bitrate;
577 double speed;
578 static int64_t last_time = -1;
579 static int first_report = 1;
580 26447 uint64_t nb_frames_dup = 0, nb_frames_drop = 0;
581 int mins, secs, ms, us;
582 int64_t hours;
583 const char *hours_sign;
584 int ret;
585 float t;
586
587
5/6
✓ Branch 0 taken 26394 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 17965 times.
✓ Branch 3 taken 8429 times.
✓ Branch 4 taken 17965 times.
✗ Branch 5 not taken.
26447 if (!print_stats && !is_last_report && !progress_avio)
588 17965 return;
589
590
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 8457 times.
8482 if (!is_last_report) {
591
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 13 times.
25 if (last_time == -1) {
592 12 last_time = cur_time;
593 }
594
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
25 if (((cur_time - last_time) < stats_period && !first_report) ||
595
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
25 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
596 return;
597 25 last_time = cur_time;
598 }
599
600 8482 t = (cur_time-timer_start) / 1000000.0;
601
602 8482 vid = 0;
603 8482 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
604 8482 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
605
606
2/2
✓ Branch 2 taken 8977 times.
✓ Branch 3 taken 8482 times.
17459 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
607
2/2
✓ Branch 0 taken 8247 times.
✓ Branch 1 taken 730 times.
8977 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
608
609
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 8695 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 201 times.
8977 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
610 81 av_bprintf(&buf, "q=%2.1f ", q);
611 81 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
612 81 ost->file->index, ost->index, q);
613 }
614
4/4
✓ Branch 0 taken 8695 times.
✓ Branch 1 taken 282 times.
✓ Branch 2 taken 7142 times.
✓ Branch 3 taken 1553 times.
8977 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
615 float fps;
616 7142 uint64_t frame_number = atomic_load(&ost->packets_written);
617
618
2/2
✓ Branch 0 taken 1985 times.
✓ Branch 1 taken 5157 times.
7142 fps = t > 1 ? frame_number / t : 0;
619 7142 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
620 frame_number, fps < 9.95, fps, q);
621 7142 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
622 7142 av_bprintf(&buf_script, "fps=%.2f\n", fps);
623 7142 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
624 7142 ost->file->index, ost->index, q);
625
2/2
✓ Branch 0 taken 7141 times.
✓ Branch 1 taken 1 times.
7142 if (is_last_report)
626 7141 av_bprintf(&buf, "L");
627
628
2/2
✓ Branch 0 taken 6820 times.
✓ Branch 1 taken 322 times.
7142 if (ost->filter) {
629 6820 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
630 6820 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
631 }
632
633 7142 vid = 1;
634 }
635 }
636
637
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8469 times.
8482 if (copy_ts) {
638
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 if (copy_ts_first_pts == AV_NOPTS_VALUE && pts > 1)
639 13 copy_ts_first_pts = pts;
640
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (copy_ts_first_pts != AV_NOPTS_VALUE)
641 13 pts -= copy_ts_first_pts;
642 }
643
644
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8353 times.
8482 us = FFABS64U(pts) % AV_TIME_BASE;
645
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8353 times.
8482 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
646
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8353 times.
8482 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
647
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 8353 times.
8482 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
648
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8369 times.
8482 hours_sign = (pts < 0) ? "-" : "";
649
650
6/6
✓ Branch 0 taken 8369 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 8353 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 8233 times.
✓ Branch 5 taken 120 times.
8482 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
651
3/4
✓ Branch 0 taken 8369 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 8369 times.
✗ Branch 3 not taken.
8482 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
652
653
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 8360 times.
8482 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
654 8360 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
655
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8369 times.
8482 if (pts == AV_NOPTS_VALUE) {
656 113 av_bprintf(&buf, "N/A ");
657 } else {
658 8369 av_bprintf(&buf, "%s%02"PRId64":%02d:%02d.%02d ",
659 hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
660 }
661
662
2/2
✓ Branch 0 taken 249 times.
✓ Branch 1 taken 8233 times.
8482 if (bitrate < 0) {
663 249 av_bprintf(&buf, "bitrate=N/A");
664 249 av_bprintf(&buf_script, "bitrate=N/A\n");
665 }else{
666 8233 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
667 8233 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
668 }
669
670
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 8360 times.
8482 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
671 8360 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
672
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8369 times.
8482 if (pts == AV_NOPTS_VALUE) {
673 113 av_bprintf(&buf_script, "out_time_us=N/A\n");
674 113 av_bprintf(&buf_script, "out_time_ms=N/A\n");
675 113 av_bprintf(&buf_script, "out_time=N/A\n");
676 } else {
677 8369 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
678 8369 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
679 8369 av_bprintf(&buf_script, "out_time=%s%02"PRId64":%02d:%02d.%06d\n",
680 hours_sign, hours, mins, secs, us);
681 }
682
683
4/4
✓ Branch 0 taken 8466 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8460 times.
8482 if (nb_frames_dup || nb_frames_drop)
684 22 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
685 8482 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
686 8482 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
687
688
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8369 times.
8482 if (speed < 0) {
689 113 av_bprintf(&buf, " speed=N/A");
690 113 av_bprintf(&buf_script, "speed=N/A\n");
691 } else {
692 8369 av_bprintf(&buf, " speed=%4.3gx", speed);
693 8369 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
694 }
695
696 8482 secs = (int)t;
697 8482 ms = (int)((t - secs) * 1000);
698 8482 mins = secs / 60;
699 8482 secs %= 60;
700 8482 hours = mins / 60;
701 8482 mins %= 60;
702
703 8482 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
704
705
3/4
✓ Branch 0 taken 8429 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 8429 times.
✗ Branch 3 not taken.
8482 if (print_stats || is_last_report) {
706
2/2
✓ Branch 0 taken 8457 times.
✓ Branch 1 taken 25 times.
8482 const char end = is_last_report ? '\n' : '\r';
707
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8482 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8482 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
708 fprintf(stderr, "%s %c", buf.str, end);
709 } else
710 8482 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
711
712 8482 fflush(stderr);
713 }
714 8482 av_bprint_finalize(&buf, NULL);
715
716
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8482 times.
8482 if (progress_avio) {
717 av_bprintf(&buf_script, "progress=%s\n",
718 is_last_report ? "end" : "continue");
719 avio_write(progress_avio, buf_script.str,
720 FFMIN(buf_script.len, buf_script.size - 1));
721 avio_flush(progress_avio);
722 av_bprint_finalize(&buf_script, NULL);
723 if (is_last_report) {
724 if ((ret = avio_closep(&progress_avio)) < 0)
725 av_log(NULL, AV_LOG_ERROR,
726 "Error closing progress log, loss of information possible: %s\n", av_err2str(ret));
727 }
728 }
729
730 8482 first_report = 0;
731 }
732
733 8457 static void print_stream_maps(void)
734 {
735 8457 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
736
2/2
✓ Branch 2 taken 7947 times.
✓ Branch 3 taken 8457 times.
16404 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
737
2/2
✓ Branch 0 taken 6958 times.
✓ Branch 1 taken 7947 times.
14905 for (int j = 0; j < ist->nb_filters; j++) {
738
2/2
✓ Branch 1 taken 163 times.
✓ Branch 2 taken 6795 times.
6958 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
739 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
740 163 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
741
1/2
✓ Branch 0 taken 163 times.
✗ Branch 1 not taken.
163 ist->filters[j]->name);
742
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 159 times.
163 if (nb_filtergraphs > 1)
743 4 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
744 163 av_log(NULL, AV_LOG_INFO, "\n");
745 }
746 }
747 }
748
749
2/2
✓ Branch 2 taken 8951 times.
✓ Branch 3 taken 8457 times.
17408 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
750
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8950 times.
8951 if (ost->attachment_filename) {
751 /* an attached file */
752 1 av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
753 1 ost->attachment_filename, ost->file->index, ost->index);
754 1 continue;
755 }
756
757
4/4
✓ Branch 0 taken 8179 times.
✓ Branch 1 taken 771 times.
✓ Branch 3 taken 1384 times.
✓ Branch 4 taken 6795 times.
8950 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
758 /* output from a complex graph */
759 1384 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
760
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1383 times.
1384 if (nb_filtergraphs > 1)
761 1 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
762
763 1384 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
764 1384 ost->index, ost->enc->enc_ctx->codec->name);
765 1384 continue;
766 }
767
768 7566 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
769 7566 ost->ist->file->index,
770 7566 ost->ist->index,
771 7566 ost->file->index,
772 ost->index);
773
2/2
✓ Branch 0 taken 6837 times.
✓ Branch 1 taken 729 times.
7566 if (ost->enc) {
774 6837 const AVCodec *in_codec = ost->ist->dec;
775 6837 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
776 6837 const char *decoder_name = "?";
777 6837 const char *in_codec_name = "?";
778 6837 const char *encoder_name = "?";
779 6837 const char *out_codec_name = "?";
780 const AVCodecDescriptor *desc;
781
782
1/2
✓ Branch 0 taken 6837 times.
✗ Branch 1 not taken.
6837 if (in_codec) {
783 6837 decoder_name = in_codec->name;
784 6837 desc = avcodec_descriptor_get(in_codec->id);
785
1/2
✓ Branch 0 taken 6837 times.
✗ Branch 1 not taken.
6837 if (desc)
786 6837 in_codec_name = desc->name;
787
2/2
✓ Branch 0 taken 6669 times.
✓ Branch 1 taken 168 times.
6837 if (!strcmp(decoder_name, in_codec_name))
788 6669 decoder_name = "native";
789 }
790
791
1/2
✓ Branch 0 taken 6837 times.
✗ Branch 1 not taken.
6837 if (out_codec) {
792 6837 encoder_name = out_codec->name;
793 6837 desc = avcodec_descriptor_get(out_codec->id);
794
1/2
✓ Branch 0 taken 6837 times.
✗ Branch 1 not taken.
6837 if (desc)
795 6837 out_codec_name = desc->name;
796
2/2
✓ Branch 0 taken 6725 times.
✓ Branch 1 taken 112 times.
6837 if (!strcmp(encoder_name, out_codec_name))
797 6725 encoder_name = "native";
798 }
799
800 6837 av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))",
801 in_codec_name, decoder_name,
802 out_codec_name, encoder_name);
803 } else
804 729 av_log(NULL, AV_LOG_INFO, " (copy)");
805 7566 av_log(NULL, AV_LOG_INFO, "\n");
806 }
807 8457 }
808
809 static void set_tty_echo(int on)
810 {
811 #if HAVE_TERMIOS_H
812 struct termios tty;
813 if (tcgetattr(0, &tty) == 0) {
814 if (on) tty.c_lflag |= ECHO;
815 else tty.c_lflag &= ~ECHO;
816 tcsetattr(0, TCSANOW, &tty);
817 }
818 #endif
819 }
820
821 static int check_keyboard_interaction(int64_t cur_time)
822 {
823 int i, key;
824 static int64_t last_time;
825 /* read_key() returns 0 on EOF */
826 if (cur_time - last_time >= 100000) {
827 key = read_key();
828 last_time = cur_time;
829 }else
830 key = -1;
831 if (key == 'q') {
832 av_log(NULL, AV_LOG_INFO, "\n\n[q] command received. Exiting.\n\n");
833 return AVERROR_EXIT;
834 }
835 if (key == '+') av_log_set_level(av_log_get_level()+10);
836 if (key == '-') av_log_set_level(av_log_get_level()-10);
837 if (key == 'c' || key == 'C'){
838 char buf[4096], target[64], command[256], arg[256] = {0};
839 double time;
840 int k, n = 0;
841 fprintf(stderr, "\nEnter command: <target>|all <time>|-1 <command>[ <argument>]\n");
842 i = 0;
843 set_tty_echo(1);
844 while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
845 if (k > 0)
846 buf[i++] = k;
847 buf[i] = 0;
848 set_tty_echo(0);
849 fprintf(stderr, "\n");
850 if (k > 0 &&
851 (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
852 av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
853 target, time, command, arg);
854 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
855 if (ost->fg_simple)
856 fg_send_command(ost->fg_simple, time, target, command, arg,
857 key == 'C');
858 }
859 for (i = 0; i < nb_filtergraphs; i++)
860 fg_send_command(filtergraphs[i], time, target, command, arg,
861 key == 'C');
862 } else {
863 av_log(NULL, AV_LOG_ERROR,
864 "Parse error, at least 3 arguments were expected, "
865 "only %d given in string '%s'\n", n, buf);
866 }
867 }
868 if (key == '?'){
869 fprintf(stderr, "key function\n"
870 "? show this help\n"
871 "+ increase verbosity\n"
872 "- decrease verbosity\n"
873 "c Send command to first matching filter supporting it\n"
874 "C Send/Queue command to all matching filters\n"
875 "h dump packets/hex press to cycle through the 3 states\n"
876 "q quit\n"
877 "s Show QP histogram\n"
878 );
879 }
880 return 0;
881 }
882
883 /*
884 * The following code is the main loop of the file converter
885 */
886 8457 static int transcode(Scheduler *sch)
887 {
888 8457 int ret = 0;
889 8457 int64_t timer_start, transcode_ts = 0;
890
891 8457 print_stream_maps();
892
893 8457 atomic_store(&transcode_init_done, 1);
894
895 8457 ret = sch_start(sch);
896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 if (ret < 0)
897 return ret;
898
899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 if (stdin_interaction) {
900 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
901 }
902
903 8457 timer_start = av_gettime_relative();
904
905
2/2
✓ Branch 1 taken 17990 times.
✓ Branch 2 taken 8457 times.
26447 while (!sch_wait(sch, stats_period, &transcode_ts)) {
906 17990 int64_t cur_time= av_gettime_relative();
907
908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17990 times.
17990 if (received_nb_signals)
909 break;
910
911 /* if 'q' pressed, exits */
912
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17990 times.
17990 if (stdin_interaction)
913 if (check_keyboard_interaction(cur_time) < 0)
914 break;
915
916 /* dump report by using the output first video and audio streams */
917 17990 print_report(0, timer_start, cur_time, transcode_ts);
918 }
919
920 8457 ret = sch_stop(sch, &transcode_ts);
921
922 /* write the trailer if needed */
923
2/2
✓ Branch 0 taken 8461 times.
✓ Branch 1 taken 8457 times.
16918 for (int i = 0; i < nb_output_files; i++) {
924 8461 int err = of_write_trailer(output_files[i]);
925 8461 ret = err_merge(ret, err);
926 }
927
928 8457 term_exit();
929
930 /* dump report by using the first video and audio streams */
931 8457 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
932
933 8457 return ret;
934 }
935
936 8457 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
937 {
938 8457 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
939 #if HAVE_GETRUSAGE
940 struct rusage rusage;
941
942 8457 getrusage(RUSAGE_SELF, &rusage);
943 8457 time_stamps.user_usec =
944 8457 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
945 8457 time_stamps.sys_usec =
946 8457 (rusage.ru_stime.tv_sec * 1000000LL) + rusage.ru_stime.tv_usec;
947 #elif HAVE_GETPROCESSTIMES
948 HANDLE proc;
949 FILETIME c, e, k, u;
950 proc = GetCurrentProcess();
951 GetProcessTimes(proc, &c, &e, &k, &u);
952 time_stamps.user_usec =
953 ((int64_t)u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
954 time_stamps.sys_usec =
955 ((int64_t)k.dwHighDateTime << 32 | k.dwLowDateTime) / 10;
956 #else
957 time_stamps.user_usec = time_stamps.sys_usec = 0;
958 #endif
959 8457 return time_stamps;
960 }
961
962 static int64_t getmaxrss(void)
963 {
964 #if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
965 struct rusage rusage;
966 getrusage(RUSAGE_SELF, &rusage);
967 return (int64_t)rusage.ru_maxrss * 1024;
968 #elif HAVE_GETPROCESSMEMORYINFO
969 HANDLE proc;
970 PROCESS_MEMORY_COUNTERS memcounters;
971 proc = GetCurrentProcess();
972 memcounters.cb = sizeof(memcounters);
973 GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
974 return memcounters.PeakPagefileUsage;
975 #else
976 return 0;
977 #endif
978 }
979
980 8458 int main(int argc, char **argv)
981 {
982 8458 Scheduler *sch = NULL;
983
984 int ret;
985 BenchmarkTimeStamps ti;
986
987 8458 init_dynload();
988
989 8458 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
990
991 8458 av_log_set_flags(AV_LOG_SKIP_REPEATED);
992 8458 parse_loglevel(argc, argv, options);
993
994 #if CONFIG_AVDEVICE
995 8458 avdevice_register_all();
996 #endif
997 8458 avformat_network_init();
998
999 8458 show_banner(argc, argv, options);
1000
1001 8458 sch = sch_alloc();
1002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8458 times.
8458 if (!sch) {
1003 ret = AVERROR(ENOMEM);
1004 goto finish;
1005 }
1006
1007 /* parse options and open all input/output files */
1008 8458 ret = ffmpeg_parse_options(argc, argv, sch);
1009
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8457 times.
8458 if (ret < 0)
1010 1 goto finish;
1011
1012
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8457 if (nb_output_files <= 0 && nb_input_files == 0) {
1013 show_usage();
1014 av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
1015 ret = 1;
1016 goto finish;
1017 }
1018
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8457 times.
8457 if (nb_output_files <= 0) {
1020 av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
1021 ret = 1;
1022 goto finish;
1023 }
1024
1025 #if CONFIG_MEDIACODEC
1026 android_binder_threadpool_init_if_required();
1027 #endif
1028
1029 8457 current_time = ti = get_benchmark_time_stamps();
1030 8457 ret = transcode(sch);
1031
3/4
✓ Branch 0 taken 8456 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8456 times.
8457 if (ret >= 0 && do_benchmark) {
1032 int64_t utime, stime, rtime;
1033 current_time = get_benchmark_time_stamps();
1034 utime = current_time.user_usec - ti.user_usec;
1035 stime = current_time.sys_usec - ti.sys_usec;
1036 rtime = current_time.real_usec - ti.real_usec;
1037 av_log(NULL, AV_LOG_INFO,
1038 "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
1039 utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
1040 }
1041
1042
1/2
✓ Branch 0 taken 8457 times.
✗ Branch 1 not taken.
16914 ret = received_nb_signals ? 255 :
1043
2/2
✓ Branch 0 taken 8456 times.
✓ Branch 1 taken 1 times.
8457 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1044
1045 8458 finish:
1046
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8457 times.
8458 if (ret == AVERROR_EXIT)
1047 1 ret = 0;
1048
1049 8458 ffmpeg_cleanup(ret);
1050
1051 8458 sch_free(&sch);
1052
1053 8458 av_log(NULL, AV_LOG_VERBOSE, "\n");
1054 8458 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1055
1056 8458 return ret;
1057 }
1058