FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg.c
Date: 2026-06-02 12:35:18
Exec Total Coverage
Lines: 344 478 72.0%
Functions: 20 25 80.0%
Branches: 207 316 65.5%

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 17182 static void term_exit_sigsafe(void)
128 {
129 #if HAVE_TERMIOS_H
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17182 times.
17182 if(restore_tty)
131 tcsetattr (0, TCSANOW, &oldtty);
132 #endif
133 17182 }
134
135 17181 void term_exit(void)
136 {
137 17181 av_log(NULL, AV_LOG_QUIET, "%s", "");
138 17181 term_exit_sigsafe();
139 17181 }
140
141 static volatile int received_sigterm = 0;
142 static volatile int received_nb_signals = 0;
143 static atomic_int transcode_init_done = 0;
144 static volatile int ffmpeg_exited = 0;
145 static int64_t copy_ts_first_pts = AV_NOPTS_VALUE;
146
147 static void
148 1 sigterm_handler(int sig)
149 {
150 int ret;
151 1 received_sigterm = sig;
152 1 received_nb_signals++;
153 1 term_exit_sigsafe();
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(received_nb_signals > 3) {
155 ret = write(2/*STDERR_FILENO*/, "Received > 3 system signals, hard exiting\n",
156 strlen("Received > 3 system signals, hard exiting\n"));
157 if (ret < 0) { /* Do nothing */ };
158 exit(123);
159 }
160 1 }
161
162 #if HAVE_SETCONSOLECTRLHANDLER
163 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
164 {
165 av_log(NULL, AV_LOG_DEBUG, "\nReceived windows signal %ld\n", fdwCtrlType);
166
167 switch (fdwCtrlType)
168 {
169 case CTRL_C_EVENT:
170 case CTRL_BREAK_EVENT:
171 sigterm_handler(SIGINT);
172 return TRUE;
173
174 case CTRL_CLOSE_EVENT:
175 case CTRL_LOGOFF_EVENT:
176 case CTRL_SHUTDOWN_EVENT:
177 sigterm_handler(SIGTERM);
178 /* Basically, with these 3 events, when we return from this method the
179 process is hard terminated, so stall as long as we need to
180 to try and let the main thread(s) clean up and gracefully terminate
181 (we have at most 5 seconds, but should be done far before that). */
182 while (!ffmpeg_exited) {
183 Sleep(0);
184 }
185 return TRUE;
186
187 default:
188 av_log(NULL, AV_LOG_ERROR, "Received unknown windows signal %ld\n", fdwCtrlType);
189 return FALSE;
190 }
191 }
192 #endif
193
194 #ifdef __linux__
195 #define SIGNAL(sig, func) \
196 do { \
197 action.sa_handler = func; \
198 sigaction(sig, &action, NULL); \
199 } while (0)
200 #else
201 #define SIGNAL(sig, func) \
202 signal(sig, func)
203 #endif
204
205 8590 void term_init(void)
206 {
207 #if defined __linux__
208 8590 struct sigaction action = {0};
209 8590 action.sa_handler = sigterm_handler;
210
211 /* block other interrupts while processing this one */
212 8590 sigfillset(&action.sa_mask);
213
214 /* restart interruptible functions (i.e. don't fail with EINTR) */
215 8590 action.sa_flags = SA_RESTART;
216 #endif
217
218 #if HAVE_TERMIOS_H
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8590 times.
8590 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 8590 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
241 8590 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
242 #ifdef SIGXCPU
243 8590 SIGNAL(SIGXCPU, sigterm_handler);
244 #endif
245 #ifdef SIGPIPE
246 8590 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
247 #endif
248 #if HAVE_SETCONSOLECTRLHANDLER
249 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
250 #endif
251 8590 }
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 818287 static int decode_interrupt_cb(void *ctx)
308 {
309 818287 return received_nb_signals > atomic_load(&transcode_init_done);
310 }
311
312 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
313
314 8592 static void ffmpeg_cleanup(int ret)
315 {
316
2/6
✓ Branch 0 taken 8592 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8592 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8592 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 8592 times.
8592 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 1261 times.
✓ Branch 1 taken 8592 times.
9853 for (int i = 0; i < nb_filtergraphs; i++)
325 1261 fg_free(&filtergraphs[i]);
326 8592 av_freep(&filtergraphs);
327
328
2/2
✓ Branch 0 taken 8593 times.
✓ Branch 1 taken 8592 times.
17185 for (int i = 0; i < nb_output_files; i++)
329 8593 of_free(&output_files[i]);
330
331
2/2
✓ Branch 0 taken 7501 times.
✓ Branch 1 taken 8592 times.
16093 for (int i = 0; i < nb_input_files; i++)
332 7501 ifile_close(&input_files[i]);
333
334
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8592 times.
8593 for (int i = 0; i < nb_decoders; i++)
335 1 dec_free(&decoders[i]);
336 8592 av_freep(&decoders);
337
338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8592 times.
8592 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 8592 av_freep(&vstats_filename);
345 8592 of_enc_stats_close();
346
347 8592 hw_device_free_all();
348
349 8592 av_freep(&filter_nbthreads);
350
351 8592 av_freep(&print_graphs_file);
352 8592 av_freep(&print_graphs_format);
353
354 8592 av_freep(&input_files);
355 8592 av_freep(&output_files);
356
357 8592 uninit_opts();
358
359 8592 avformat_network_deinit();
360
361
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8591 times.
8592 if (received_sigterm) {
362 1 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 8588 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
8591 } else if (ret && atomic_load(&transcode_init_done)) {
365 2 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
366 }
367 8592 term_exit();
368 8592 ffmpeg_exited = 1;
369 8592 }
370
371 35442 OutputStream *ost_iter(OutputStream *prev)
372 {
373
2/2
✓ Branch 0 taken 18238 times.
✓ Branch 1 taken 17204 times.
35442 int of_idx = prev ? prev->file->index : 0;
374
2/2
✓ Branch 0 taken 18238 times.
✓ Branch 1 taken 17204 times.
35442 int ost_idx = prev ? prev->index + 1 : 0;
375
376
2/2
✓ Branch 0 taken 35450 times.
✓ Branch 1 taken 17204 times.
52654 for (; of_idx < nb_output_files; of_idx++) {
377 35450 OutputFile *of = output_files[of_idx];
378
2/2
✓ Branch 0 taken 18238 times.
✓ Branch 1 taken 17212 times.
35450 if (ost_idx < of->nb_streams)
379 18238 return of->streams[ost_idx];
380
381 17212 ost_idx = 0;
382 }
383
384 17204 return NULL;
385 }
386
387 16938 InputStream *ist_iter(InputStream *prev)
388 {
389
2/2
✓ Branch 0 taken 8165 times.
✓ Branch 1 taken 8773 times.
16938 int if_idx = prev ? prev->file->index : 0;
390
2/2
✓ Branch 0 taken 8165 times.
✓ Branch 1 taken 8773 times.
16938 int ist_idx = prev ? prev->index + 1 : 0;
391
392
2/2
✓ Branch 0 taken 15871 times.
✓ Branch 1 taken 8609 times.
24480 for (; if_idx < nb_input_files; if_idx++) {
393 15871 InputFile *f = input_files[if_idx];
394
2/2
✓ Branch 0 taken 8329 times.
✓ Branch 1 taken 7542 times.
15871 if (ist_idx < f->nb_streams)
395 8329 return f->streams[ist_idx];
396
397 7542 ist_idx = 0;
398 }
399
400 8609 return NULL;
401 }
402
403 1667218 static void frame_data_free(void *opaque, uint8_t *data)
404 {
405 1667218 FrameData *fd = (FrameData *)data;
406
407 1667218 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
408 1667218 avcodec_parameters_free(&fd->par_enc);
409
410 1667218 av_free(data);
411 1667218 }
412
413 3280636 static int frame_data_ensure(AVBufferRef **dst, int writable)
414 {
415 3280636 AVBufferRef *src = *dst;
416
417
6/6
✓ Branch 0 taken 2697134 times.
✓ Branch 1 taken 583502 times.
✓ Branch 2 taken 2690159 times.
✓ Branch 3 taken 6975 times.
✓ Branch 5 taken 1083716 times.
✓ Branch 6 taken 1606443 times.
3280636 if (!src || (writable && !av_buffer_is_writable(src))) {
418 FrameData *fd;
419
420 1667218 fd = av_mallocz(sizeof(*fd));
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1667218 times.
1667218 if (!fd)
422 return AVERROR(ENOMEM);
423
424 1667218 *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 1667218 times.
1667218 if (!*dst) {
427 av_buffer_unref(&src);
428 av_freep(&fd);
429 return AVERROR(ENOMEM);
430 }
431
432
2/2
✓ Branch 0 taken 1083716 times.
✓ Branch 1 taken 583502 times.
1667218 if (src) {
433 1083716 const FrameData *fd_src = (const FrameData *)src->data;
434
435 1083716 memcpy(fd, fd_src, sizeof(*fd));
436 1083716 fd->par_enc = NULL;
437 1083716 fd->side_data = NULL;
438 1083716 fd->nb_side_data = 0;
439
440
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1083715 times.
1083716 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 199 times.
✓ Branch 1 taken 1083517 times.
1083716 if (fd_src->nb_side_data) {
455 199 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
456 199 fd_src->side_data, fd_src->nb_side_data, 0);
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (ret < 0) {
458 av_buffer_unref(dst);
459 av_buffer_unref(&src);
460 return ret;
461 }
462 }
463
464 1083716 av_buffer_unref(&src);
465 } else {
466 583502 fd->dec.frame_num = UINT64_MAX;
467 583502 fd->dec.pts = AV_NOPTS_VALUE;
468
469
2/2
✓ Branch 0 taken 4084514 times.
✓ Branch 1 taken 583502 times.
4668016 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
470 4084514 fd->wallclock[i] = INT64_MIN;
471 }
472 }
473
474 3280636 return 0;
475 }
476
477 1806412 FrameData *frame_data(AVFrame *frame)
478 {
479 1806412 int ret = frame_data_ensure(&frame->opaque_ref, 1);
480
1/2
✓ Branch 0 taken 1806412 times.
✗ Branch 1 not taken.
1806412 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
481 }
482
483 8261 const FrameData *frame_data_c(AVFrame *frame)
484 {
485 8261 int ret = frame_data_ensure(&frame->opaque_ref, 0);
486
1/2
✓ Branch 0 taken 8261 times.
✗ Branch 1 not taken.
8261 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
487 }
488
489 1465963 FrameData *packet_data(AVPacket *pkt)
490 {
491 1465963 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
492
1/2
✓ Branch 0 taken 1465963 times.
✗ Branch 1 not taken.
1465963 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 16093 int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
502 void *logctx, int decode)
503 {
504 16093 const AVClass *class = avcodec_get_class();
505 16093 const AVClass *fclass = avformat_get_class();
506
507
2/2
✓ Branch 0 taken 7500 times.
✓ Branch 1 taken 8593 times.
16093 const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
508 AV_OPT_FLAG_ENCODING_PARAM;
509 16093 const AVDictionaryEntry *e = NULL;
510
511
2/2
✓ Branch 1 taken 49974 times.
✓ Branch 2 taken 16093 times.
66067 while ((e = av_dict_iterate(opts, e))) {
512 const AVOption *option, *foption;
513 char *optname, *p;
514
515
2/2
✓ Branch 1 taken 48993 times.
✓ Branch 2 taken 981 times.
49974 if (av_dict_get(opts_used, e->key, NULL, 0))
516 48995 continue;
517
518 981 optname = av_strdup(e->key);
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 981 times.
981 if (!optname)
520 return AVERROR(ENOMEM);
521
522 981 p = strchr(optname, ':');
523
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 969 times.
981 if (p)
524 12 *p = 0;
525
526 981 option = av_opt_find(&class, optname, NULL, 0,
527 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
528 981 foption = av_opt_find(&fclass, optname, NULL, 0,
529 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
530 981 av_freep(&optname);
531
3/4
✓ Branch 0 taken 981 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 979 times.
981 if (!option || foption)
532 2 continue;
533
534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 979 times.
979 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 979 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 974 times.
✓ Branch 1 taken 5 times.
1958 "for any stream.\n", e->key, option->help ? option->help : "");
546 }
547
548 16093 return 0;
549 }
550
551 3235071 void update_benchmark(const char *fmt, ...)
552 {
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3235071 times.
3235071 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 3235071 }
571
572 26782 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 26782 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 26782 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 26699 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 18167 times.
✓ Branch 3 taken 8532 times.
✓ Branch 4 taken 18167 times.
✗ Branch 5 not taken.
26782 if (!print_stats && !is_last_report && !progress_avio)
589 18167 return;
590
591
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 8589 times.
8615 if (!is_last_report) {
592
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 12 times.
26 if (last_time == -1) {
593 14 last_time = cur_time;
594 }
595
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
26 if (((cur_time - last_time) < stats_period && !first_report) ||
596
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
26 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
597 return;
598 26 last_time = cur_time;
599 }
600
601 8615 t = (cur_time-timer_start) / 1000000.0;
602
603 8615 vid = 0;
604 8615 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
605 8615 av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
606
607
2/2
✓ Branch 2 taken 9136 times.
✓ Branch 3 taken 8615 times.
17751 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
608
2/2
✓ Branch 0 taken 8340 times.
✓ Branch 1 taken 796 times.
9136 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
609
610
4/4
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 8844 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 208 times.
9136 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 8844 times.
✓ Branch 1 taken 292 times.
✓ Branch 2 taken 7206 times.
✓ Branch 3 taken 1638 times.
9136 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
616 float fps;
617 7206 uint64_t frame_number = atomic_load(&ost->packets_written);
618
619
2/2
✓ Branch 0 taken 1969 times.
✓ Branch 1 taken 5237 times.
7206 fps = t > 1 ? frame_number / t : 0;
620 7206 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
621 frame_number, fps < 9.95, fps, q);
622 7206 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
623 7206 av_bprintf(&buf_script, "fps=%.2f\n", fps);
624 7206 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
625 7206 ost->file->index, ost->index, q);
626
2/2
✓ Branch 0 taken 7204 times.
✓ Branch 1 taken 2 times.
7206 if (is_last_report)
627 7204 av_bprintf(&buf, "L");
628
629
2/2
✓ Branch 0 taken 6862 times.
✓ Branch 1 taken 344 times.
7206 if (ost->filter) {
630 6862 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
631 6862 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
632 }
633
634 7206 vid = 1;
635 }
636 }
637
638
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 8604 times.
8615 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 132 times.
✓ Branch 1 taken 8483 times.
8615 us = FFABS64U(pts) % AV_TIME_BASE;
646
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 8483 times.
8615 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
647
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 8483 times.
8615 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
648
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 8483 times.
8615 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
649
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8498 times.
8615 hours_sign = (pts < 0) ? "-" : "";
650
651
6/6
✓ Branch 0 taken 8502 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 8487 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 8357 times.
✓ Branch 5 taken 130 times.
8615 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
652
3/4
✓ Branch 0 taken 8502 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 8502 times.
✗ Branch 3 not taken.
8615 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
653
654
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 8485 times.
8615 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
655 8485 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
656
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8502 times.
8615 if (pts == AV_NOPTS_VALUE) {
657 113 av_bprintf(&buf, "N/A ");
658 } else {
659 8502 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 262 times.
✓ Branch 1 taken 8353 times.
8615 if (bitrate < 0) {
664 262 av_bprintf(&buf, "bitrate=N/A");
665 262 av_bprintf(&buf_script, "bitrate=N/A\n");
666 }else{
667 8353 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
668 8353 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
669 }
670
671
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 8485 times.
8615 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
672 8485 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
673
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 8502 times.
8615 if (pts == AV_NOPTS_VALUE) {
674 113 av_bprintf(&buf_script, "out_time_us=N/A\n");
675 113 av_bprintf(&buf_script, "out_time_ms=N/A\n");
676 113 av_bprintf(&buf_script, "out_time=N/A\n");
677 } else {
678 8502 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
679 8502 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
680 8502 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 8599 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 8593 times.
8615 if (nb_frames_dup || nb_frames_drop)
685 22 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
686 8615 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
687 8615 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
688
689
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 8498 times.
8615 if (speed < 0) {
690 117 av_bprintf(&buf, " speed=N/A");
691 117 av_bprintf(&buf_script, "speed=N/A\n");
692 } else {
693 8498 av_bprintf(&buf, " speed=%4.3gx", speed);
694 8498 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
695 }
696
697 8615 secs = (int)t;
698 8615 ms = (int)((t - secs) * 1000);
699 8615 mins = secs / 60;
700 8615 secs %= 60;
701 8615 hours = mins / 60;
702 8615 mins %= 60;
703
704 8615 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
705
706
3/4
✓ Branch 0 taken 8532 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 8532 times.
✗ Branch 3 not taken.
8615 if (print_stats || is_last_report) {
707
2/2
✓ Branch 0 taken 8589 times.
✓ Branch 1 taken 26 times.
8615 const char end = is_last_report ? '\n' : '\r';
708
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8615 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8615 if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
709 fprintf(stderr, "%s %c", buf.str, end);
710 } else
711 8615 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
712
713 8615 fflush(stderr);
714 }
715 8615 av_bprint_finalize(&buf, NULL);
716
717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8615 times.
8615 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 8615 first_report = 0;
732 }
733
734 8589 static void print_stream_maps(void)
735 {
736 8589 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
737
2/2
✓ Branch 2 taken 8109 times.
✓ Branch 3 taken 8589 times.
16698 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
738
2/2
✓ Branch 0 taken 7042 times.
✓ Branch 1 taken 8109 times.
15151 for (int j = 0; j < ist->nb_filters; j++) {
739
2/2
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 6869 times.
7042 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 9102 times.
✓ Branch 3 taken 8589 times.
17691 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
751
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9101 times.
9102 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 8264 times.
✓ Branch 1 taken 837 times.
✓ Branch 3 taken 1395 times.
✓ Branch 4 taken 6869 times.
9101 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
759 /* output from a complex graph */
760 1395 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
761
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1394 times.
1395 if (nb_filtergraphs > 1)
762 1 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
763
764 1395 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
765 1395 ost->index, ost->enc->enc_ctx->codec->name);
766 1395 continue;
767 }
768
769 7706 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
770 7706 ost->ist->file->index,
771 7706 ost->ist->index,
772 7706 ost->file->index,
773 ost->index);
774
2/2
✓ Branch 0 taken 6911 times.
✓ Branch 1 taken 795 times.
7706 if (ost->enc) {
775 6911 const AVCodec *in_codec = ost->ist->dec;
776 6911 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
777 6911 const char *decoder_name = "?";
778 6911 const char *in_codec_name = "?";
779 6911 const char *encoder_name = "?";
780 6911 const char *out_codec_name = "?";
781 const AVCodecDescriptor *desc;
782
783
1/2
✓ Branch 0 taken 6911 times.
✗ Branch 1 not taken.
6911 if (in_codec) {
784 6911 decoder_name = in_codec->name;
785 6911 desc = avcodec_descriptor_get(in_codec->id);
786
1/2
✓ Branch 0 taken 6911 times.
✗ Branch 1 not taken.
6911 if (desc)
787 6911 in_codec_name = desc->name;
788
2/2
✓ Branch 0 taken 6737 times.
✓ Branch 1 taken 174 times.
6911 if (!strcmp(decoder_name, in_codec_name))
789 6737 decoder_name = "native";
790 }
791
792
1/2
✓ Branch 0 taken 6911 times.
✗ Branch 1 not taken.
6911 if (out_codec) {
793 6911 encoder_name = out_codec->name;
794 6911 desc = avcodec_descriptor_get(out_codec->id);
795
1/2
✓ Branch 0 taken 6911 times.
✗ Branch 1 not taken.
6911 if (desc)
796 6911 out_codec_name = desc->name;
797
2/2
✓ Branch 0 taken 6797 times.
✓ Branch 1 taken 114 times.
6911 if (!strcmp(encoder_name, out_codec_name))
798 6797 encoder_name = "native";
799 }
800
801 6911 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 795 av_log(NULL, AV_LOG_INFO, " (copy)");
806 7706 av_log(NULL, AV_LOG_INFO, "\n");
807 }
808 8589 }
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 8589 static int transcode(Scheduler *sch)
888 {
889 8589 int ret = 0;
890 8589 int64_t timer_start, transcode_ts = 0;
891
892 8589 print_stream_maps();
893
894 8589 atomic_store(&transcode_init_done, 1);
895
896 8589 ret = sch_start(sch);
897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8589 times.
8589 if (ret < 0)
898 return ret;
899
900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8589 times.
8589 if (stdin_interaction) {
901 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
902 }
903
904 8589 timer_start = av_gettime_relative();
905
906
2/2
✓ Branch 1 taken 18194 times.
✓ Branch 2 taken 8588 times.
26782 while (!sch_wait(sch, stats_period, &transcode_ts)) {
907 18194 int64_t cur_time= av_gettime_relative();
908
909
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18193 times.
18194 if (received_nb_signals)
910 1 break;
911
912 /* if 'q' pressed, exits */
913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18193 times.
18193 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 18193 print_report(0, timer_start, cur_time, transcode_ts);
919 }
920
921 8589 ret = sch_stop(sch, &transcode_ts);
922
923 /* write the trailer if needed */
924
2/2
✓ Branch 0 taken 8593 times.
✓ Branch 1 taken 8589 times.
17182 for (int i = 0; i < nb_output_files; i++) {
925 8593 int err = of_write_trailer(output_files[i]);
926 8593 ret = err_merge(ret, err);
927 }
928
929 8589 term_exit();
930
931 /* dump report by using the first video and audio streams */
932 8589 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
933
934 8589 return ret;
935 }
936
937 8589 static BenchmarkTimeStamps get_benchmark_time_stamps(void)
938 {
939 8589 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
940 #if HAVE_GETRUSAGE
941 struct rusage rusage;
942
943 8589 getrusage(RUSAGE_SELF, &rusage);
944 8589 time_stamps.user_usec =
945 8589 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
946 8589 time_stamps.sys_usec =
947 8589 (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 8589 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 8592 int main(int argc, char **argv)
982 {
983 8592 Scheduler *sch = NULL;
984
985 int ret;
986 BenchmarkTimeStamps ti;
987
988 8592 init_dynload();
989
990 8592 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
991
992 8592 av_log_set_flags(AV_LOG_SKIP_REPEATED);
993 8592 parse_loglevel(argc, argv, options);
994
995 #if CONFIG_AVDEVICE
996 8592 avdevice_register_all();
997 #endif
998 8592 avformat_network_init();
999
1000 8592 show_banner(argc, argv, options);
1001
1002 8592 sch = sch_alloc();
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8592 times.
8592 if (!sch) {
1004 ret = AVERROR(ENOMEM);
1005 goto finish;
1006 }
1007
1008 /* parse options and open all input/output files */
1009 8592 ret = ffmpeg_parse_options(argc, argv, sch);
1010
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8589 times.
8592 if (ret < 0)
1011 3 goto finish;
1012
1013
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8589 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8589 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 8589 times.
8589 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 8589 current_time = ti = get_benchmark_time_stamps();
1031 8589 ret = transcode(sch);
1032
3/4
✓ Branch 0 taken 8587 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8587 times.
8589 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
2/2
✓ Branch 0 taken 8588 times.
✓ Branch 1 taken 1 times.
17177 ret = received_nb_signals ? 255 :
1044
2/2
✓ Branch 0 taken 8587 times.
✓ Branch 1 taken 1 times.
8588 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1045
1046 8592 finish:
1047
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8590 times.
8592 if (ret == AVERROR_EXIT)
1048 2 ret = 0;
1049
1050 8592 ffmpeg_cleanup(ret);
1051
1052 8592 sch_free(&sch);
1053
1054 8592 av_log(NULL, AV_LOG_VERBOSE, "\n");
1055 8592 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1056
1057 8592 return ret;
1058 }
1059