FFmpeg
Loading...
Searching...
No Matches
ffmpeg.c
Go to the documentation of this file.
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
77
79
80#include "cmdutils.h"
81#if CONFIG_MEDIACODEC
83#endif
84#include "ffmpeg.h"
85#include "ffmpeg_sched.h"
86#include "ffmpeg_utils.h"
87#include "graph/graphprint.h"
88
89const char program_name[] = "ffmpeg";
90const int program_birth_year = 2000;
91
93
99
101static int64_t getmaxrss(void);
102
104
107
110
113
116
119
120#if HAVE_TERMIOS_H
121
122/* init terminal so that we can grab keys */
123static struct termios oldtty;
124static int restore_tty;
125#endif
126
127static void term_exit_sigsafe(void)
128{
129#if HAVE_TERMIOS_H
130 if(restore_tty)
131 tcsetattr (0, TCSANOW, &oldtty);
132#endif
133}
134
135void term_exit(void)
136{
137 av_log(NULL, AV_LOG_QUIET, "%s", "");
139}
140
141static volatile int received_sigterm = 0;
142static volatile int received_nb_signals = 0;
144static volatile int ffmpeg_exited = 0;
146
147static void
149{
150 int ret;
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
163static 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
205void term_init(void)
206{
207#if defined __linux__
208 struct sigaction action = {0};
209 action.sa_handler = sigterm_handler;
210
211 /* block other interrupts while processing this one */
212 sigfillset(&action.sa_mask);
213
214 /* restart interruptible functions (i.e. don't fail with EINTR) */
215 action.sa_flags = SA_RESTART;
216#endif
217
218#if HAVE_TERMIOS_H
219 /* A closed fd 0 is later reused by the first opened input file. read_key()
220 * would then read from that input instead of the terminal and corrupt the
221 * stream, so disable interaction when fd 0 is not an open descriptor.
222 */
223 if (stdin_interaction && fcntl(0, F_GETFD) == -1) {
225 "fd 0 is not an open file descriptor, stdin interaction disabled\n");
227 }
228
229 if (stdin_interaction) {
230 struct termios tty;
231 if (tcgetattr (0, &tty) == 0) {
232 oldtty = tty;
233 restore_tty = 1;
234
235 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
236 |INLCR|IGNCR|ICRNL|IXON);
237 tty.c_oflag |= OPOST;
238 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
239 tty.c_cflag &= ~(CSIZE|PARENB);
240 tty.c_cflag |= CS8;
241 tty.c_cc[VMIN] = 1;
242 tty.c_cc[VTIME] = 0;
243
244 tcsetattr (0, TCSANOW, &tty);
245 }
246 SIGNAL(SIGQUIT, sigterm_handler); /* Quit (POSIX). */
247 }
248#endif
249
250 SIGNAL(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
251 SIGNAL(SIGTERM, sigterm_handler); /* Termination (ANSI). */
252#ifdef SIGXCPU
253 SIGNAL(SIGXCPU, sigterm_handler);
254#endif
255#ifdef SIGPIPE
256 signal(SIGPIPE, SIG_IGN); /* Broken pipe (POSIX). */
257#endif
258#if HAVE_SETCONSOLECTRLHANDLER
259 SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
260#endif
261}
262
263/* read a key without blocking */
264static int read_key(void)
265{
266#if HAVE_TERMIOS_H
267 int n = 1;
268 struct timeval tv;
269 fd_set rfds;
270
271 FD_ZERO(&rfds);
272 FD_SET(0, &rfds);
273 tv.tv_sec = 0;
274 tv.tv_usec = 0;
275 n = select(1, &rfds, NULL, NULL, &tv);
276 if (n > 0) {
277 unsigned char ch;
278 n = read(0, &ch, 1);
279 if (n == 1)
280 return ch;
281
282 return n;
283 }
284#elif HAVE_KBHIT
285# if HAVE_PEEKNAMEDPIPE && HAVE_GETSTDHANDLE
286 static int is_pipe;
287 static HANDLE input_handle;
288 DWORD dw, nchars;
289 if(!input_handle){
290 input_handle = GetStdHandle(STD_INPUT_HANDLE);
291 is_pipe = !GetConsoleMode(input_handle, &dw);
292 }
293
294 if (is_pipe) {
295 /* When running under a GUI, you will end here. */
296 if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL)) {
297 // input pipe may have been closed by the program that ran ffmpeg
298 return -1;
299 }
300 //Read it
301 if(nchars != 0) {
302 unsigned char ch;
303 if (read(0, &ch, 1) == 1)
304 return ch;
305 return 0;
306 }else{
307 return -1;
308 }
309 }
310# endif
311 if(kbhit())
312 return(getch());
313#endif
314 return -1;
315}
316
321
323
324static void ffmpeg_cleanup(int ret)
325{
328
329 if (do_benchmark) {
330 int64_t maxrss = getmaxrss() / 1024;
331 av_log(NULL, AV_LOG_INFO, "bench: maxrss=%"PRId64"KiB\n", maxrss);
332 }
333
334 for (int i = 0; i < nb_filtergraphs; i++)
337
338 for (int i = 0; i < nb_output_files; i++)
340
341 for (int i = 0; i < nb_input_files; i++)
343
344 for (int i = 0; i < nb_decoders; i++)
347
348 if (vstats_file) {
349 if (fclose(vstats_file))
351 "Error closing vstats file, loss of information possible: %s\n",
352 av_err2str(AVERROR(errno)));
353 }
356
358
360
363
366
367 uninit_opts();
368
370
371 if (received_sigterm) {
372 av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n",
373 (int) received_sigterm);
374 } else if (ret && atomic_load(&transcode_init_done)) {
375 av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
376 }
377 term_exit();
378 ffmpeg_exited = 1;
379}
380
382{
383 int of_idx = prev ? prev->file->index : 0;
384 int ost_idx = prev ? prev->index + 1 : 0;
385
386 for (; of_idx < nb_output_files; of_idx++) {
387 OutputFile *of = output_files[of_idx];
388 if (ost_idx < of->nb_streams)
389 return of->streams[ost_idx];
390
391 ost_idx = 0;
392 }
393
394 return NULL;
395}
396
398{
399 int if_idx = prev ? prev->file->index : 0;
400 int ist_idx = prev ? prev->index + 1 : 0;
401
402 for (; if_idx < nb_input_files; if_idx++) {
403 InputFile *f = input_files[if_idx];
404 if (ist_idx < f->nb_streams)
405 return f->streams[ist_idx];
406
407 ist_idx = 0;
408 }
409
410 return NULL;
411}
412
413static void frame_data_free(void *opaque, uint8_t *data)
414{
415 FrameData *fd = (FrameData *)data;
416
420
421 av_free(data);
422}
423
424static int frame_data_ensure(AVBufferRef **dst, int writable)
425{
426 AVBufferRef *src = *dst;
427
428 if (!src || (writable && !av_buffer_is_writable(src))) {
429 FrameData *fd;
430
431 fd = av_mallocz(sizeof(*fd));
432 if (!fd)
433 return AVERROR(ENOMEM);
434
435 *dst = av_buffer_create((uint8_t *)fd, sizeof(*fd),
437 if (!*dst) {
439 av_freep(&fd);
440 return AVERROR(ENOMEM);
441 }
442
443 if (src) {
444 const FrameData *fd_src = (const FrameData *)src->data;
445
446 memcpy(fd, fd_src, sizeof(*fd));
447 fd->par_enc = NULL;
448 fd->side_data = NULL;
449 fd->nb_side_data = 0;
450 fd->reinit_opts = NULL;
451
452 if (fd_src->par_enc) {
453 int ret = 0;
454
456 ret = fd->par_enc ?
458 AVERROR(ENOMEM);
459 if (!ret && fd_src->reinit_opts)
460 ret = av_dict_copy(&fd->reinit_opts, fd_src->reinit_opts, 0);
461 if (ret < 0) {
464 return ret;
465 }
466 }
467
468 if (fd_src->nb_side_data) {
469 int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
470 fd_src->side_data, fd_src->nb_side_data, 0);
471 if (ret < 0) {
474 return ret;
475 }
476 }
477
479 } else {
480 fd->dec.frame_num = UINT64_MAX;
481 fd->dec.pts = AV_NOPTS_VALUE;
482
483 for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i++)
484 fd->wallclock[i] = INT64_MIN;
485 }
486 }
487
488 return 0;
489}
490
492{
493 int ret = frame_data_ensure(&frame->opaque_ref, 1);
494 return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
495}
496
498{
499 int ret = frame_data_ensure(&frame->opaque_ref, 0);
500 return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
501}
502
504{
505 int ret = frame_data_ensure(&pkt->opaque_ref, 1);
506 return ret < 0 ? NULL : (FrameData*)pkt->opaque_ref->data;
507}
508
510{
511 int ret = frame_data_ensure(&pkt->opaque_ref, 0);
512 return ret < 0 ? NULL : (const FrameData*)pkt->opaque_ref->data;
513}
514
516 void *logctx, int decode)
517{
518 const AVClass *class = avcodec_get_class();
519 const AVClass *fclass = avformat_get_class();
520
523 const AVDictionaryEntry *e = NULL;
524
525 while ((e = av_dict_iterate(opts, e))) {
526 const AVOption *option, *foption;
527 char *optname, *p;
528
529 if (av_dict_get(opts_used, e->key, NULL, 0))
530 continue;
531
532 optname = av_strdup(e->key);
533 if (!optname)
534 return AVERROR(ENOMEM);
535
536 p = strchr(optname, ':');
537 if (p)
538 *p = 0;
539
540 option = av_opt_find(&class, optname, NULL, 0,
542 foption = av_opt_find(&fclass, optname, NULL, 0,
544 av_freep(&optname);
545 if (!option || foption)
546 continue;
547
548 if (!(option->flags & flag)) {
549 av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s "
550 "option.\n", e->key, option->help ? option->help : "",
551 decode ? "decoding" : "encoding");
552 return AVERROR(EINVAL);
553 }
554
555 av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
556 "for any stream. The most likely reason is either wrong type "
557 "(e.g. a video option with no video streams) or that it is a "
558 "private option of some decoder which was not actually used "
559 "for any stream.\n", e->key, option->help ? option->help : "");
560 }
561
562 return 0;
563}
564
565void update_benchmark(const char *fmt, ...)
566{
567 if (do_benchmark_all) {
569 va_list va;
570 char buf[1024];
571
572 if (fmt) {
573 va_start(va, fmt);
574 vsnprintf(buf, sizeof(buf), fmt, va);
575 va_end(va);
577 "bench: %8" PRIu64 " user %8" PRIu64 " sys %8" PRIu64 " real %s \n",
578 t.user_usec - current_time.user_usec,
579 t.sys_usec - current_time.sys_usec,
580 t.real_usec - current_time.real_usec, buf);
581 }
582 current_time = t;
583 }
584}
585
586static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts)
587{
588 AVBPrint buf, buf_script;
589 int64_t total_size = of_filesize(output_files[0]);
590 int vid;
591 double bitrate;
592 double speed;
593 static int64_t last_time = -1;
594 static int first_report = 1;
595 uint64_t nb_frames_dup = 0, nb_frames_drop = 0;
596 int mins, secs, ms, us;
597 int64_t hours;
598 const char *hours_sign;
599 int ret;
600 float t;
601
602 if (!print_stats && !is_last_report && !progress_avio)
603 return;
604
605 if (!is_last_report) {
606 if (last_time == -1) {
607 last_time = cur_time;
608 }
609 if (((cur_time - last_time) < stats_period && !first_report) ||
610 (first_report && atomic_load(&nb_output_dumped) < nb_output_files))
611 return;
612 last_time = cur_time;
613 }
614
615 t = (cur_time-timer_start) / 1000000.0;
616
617 vid = 0;
620
622 const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1;
623
624 if (vid && ost->type == AVMEDIA_TYPE_VIDEO) {
625 av_bprintf(&buf, "q=%2.1f ", q);
626 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
627 ost->file->index, ost->index, q);
628 }
629 if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
630 float fps;
631 uint64_t frame_number = atomic_load(&ost->packets_written);
632
633 fps = t > 1 ? frame_number / t : 0;
634 av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
635 frame_number, fps < 9.95, fps, q);
636 av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
637 av_bprintf(&buf_script, "fps=%.2f\n", fps);
638 av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
639 ost->file->index, ost->index, q);
640 if (is_last_report)
641 av_bprintf(&buf, "L");
642
643 if (ost->filter) {
644 nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
645 nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
646 }
647
648 vid = 1;
649 }
650 }
651
652 if (copy_ts) {
657 }
658
660 secs = FFABS64U(pts) / AV_TIME_BASE % 60;
661 mins = FFABS64U(pts) / AV_TIME_BASE / 60 % 60;
662 hours = FFABS64U(pts) / AV_TIME_BASE / 3600;
663 hours_sign = (pts < 0) ? "-" : "";
664
665 bitrate = pts != AV_NOPTS_VALUE && pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
666 speed = pts != AV_NOPTS_VALUE && t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
667
668 if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
669 else av_bprintf(&buf, "size=%8.0fKiB time=", total_size / 1024.0);
670 if (pts == AV_NOPTS_VALUE) {
671 av_bprintf(&buf, "N/A ");
672 } else {
673 av_bprintf(&buf, "%s%02"PRId64":%02d:%02d.%02d ",
674 hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
675 }
676
677 if (bitrate < 0) {
678 av_bprintf(&buf, "bitrate=N/A");
679 av_bprintf(&buf_script, "bitrate=N/A\n");
680 }else{
681 av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
682 av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
683 }
684
685 if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
686 else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
687 if (pts == AV_NOPTS_VALUE) {
688 av_bprintf(&buf_script, "out_time_us=N/A\n");
689 av_bprintf(&buf_script, "out_time_ms=N/A\n");
690 av_bprintf(&buf_script, "out_time=N/A\n");
691 } else {
692 av_bprintf(&buf_script, "out_time_us=%"PRId64"\n", pts);
693 av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
694 av_bprintf(&buf_script, "out_time=%s%02"PRId64":%02d:%02d.%06d\n",
695 hours_sign, hours, mins, secs, us);
696 }
697
698 if (nb_frames_dup || nb_frames_drop)
699 av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
700 av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
701 av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
702
703 if (speed < 0) {
704 av_bprintf(&buf, " speed=N/A");
705 av_bprintf(&buf_script, "speed=N/A\n");
706 } else {
707 av_bprintf(&buf, " speed=%4.3gx", speed);
708 av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
709 }
710
711 secs = (int)t;
712 ms = (int)((t - secs) * 1000);
713 mins = secs / 60;
714 secs %= 60;
715 hours = mins / 60;
716 mins %= 60;
717
718 av_bprintf(&buf, " elapsed=%"PRId64":%02d:%02d.%02d", hours, mins, secs, ms / 10);
719
720 if (print_stats || is_last_report) {
721 const char end = is_last_report ? '\n' : '\r';
723 fprintf(stderr, "%s %c", buf.str, end);
724 } else
725 av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
726
727 fflush(stderr);
728 }
730
731 if (progress_avio) {
732 av_bprintf(&buf_script, "progress=%s\n",
733 is_last_report ? "end" : "continue");
734 avio_write(progress_avio, buf_script.str,
735 FFMIN(buf_script.len, buf_script.size - 1));
737 av_bprint_finalize(&buf_script, NULL);
738 if (is_last_report) {
739 if ((ret = avio_closep(&progress_avio)) < 0)
741 "Error closing progress log, loss of information possible: %s\n", av_err2str(ret));
742 }
743 }
744
745 first_report = 0;
746}
747
748static void print_stream_maps(void)
749{
750 av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
751 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
752 for (int j = 0; j < ist->nb_filters; j++) {
753 if (!filtergraph_is_simple(ist->filters[j]->graph)) {
754 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
755 ist->file->index, ist->index, ist->dec ? ist->dec->name : "?",
756 ist->filters[j]->name);
757 if (nb_filtergraphs > 1)
758 av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
759 av_log(NULL, AV_LOG_INFO, "\n");
760 }
761 }
762 }
763
765 if (ost->attachment_filename) {
766 /* an attached file */
767 av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
768 ost->attachment_filename, ost->file->index, ost->index);
769 continue;
770 }
771
772 if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
773 /* output from a complex graph */
774 av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
775 if (nb_filtergraphs > 1)
776 av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
777
778 av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file->index,
779 ost->index, ost->enc->enc_ctx->codec->name);
780 continue;
781 }
782
783 av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
784 ost->ist->file->index,
785 ost->ist->index,
786 ost->file->index,
787 ost->index);
788 if (ost->enc) {
789 const AVCodec *in_codec = ost->ist->dec;
790 const AVCodec *out_codec = ost->enc->enc_ctx->codec;
791 const char *decoder_name = "?";
792 const char *in_codec_name = "?";
793 const char *encoder_name = "?";
794 const char *out_codec_name = "?";
795 const AVCodecDescriptor *desc;
796
797 if (in_codec) {
798 decoder_name = in_codec->name;
799 desc = avcodec_descriptor_get(in_codec->id);
800 if (desc)
801 in_codec_name = desc->name;
802 if (!strcmp(decoder_name, in_codec_name))
803 decoder_name = "native";
804 }
805
806 if (out_codec) {
807 encoder_name = out_codec->name;
808 desc = avcodec_descriptor_get(out_codec->id);
809 if (desc)
810 out_codec_name = desc->name;
811 if (!strcmp(encoder_name, out_codec_name))
812 encoder_name = "native";
813 }
814
815 av_log(NULL, AV_LOG_INFO, " (%s (%s) -> %s (%s))",
816 in_codec_name, decoder_name,
817 out_codec_name, encoder_name);
818 } else
819 av_log(NULL, AV_LOG_INFO, " (copy)");
820 av_log(NULL, AV_LOG_INFO, "\n");
821 }
822}
823
824static void set_tty_echo(int on)
825{
826#if HAVE_TERMIOS_H
827 struct termios tty;
828 if (tcgetattr(0, &tty) == 0) {
829 if (on) tty.c_lflag |= ECHO;
830 else tty.c_lflag &= ~ECHO;
831 tcsetattr(0, TCSANOW, &tty);
832 }
833#endif
834}
835
837{
838 int i, key;
839 static int64_t last_time;
840 /* read_key() returns 0 on EOF */
841 if (cur_time - last_time >= 100000) {
842 key = read_key();
843 last_time = cur_time;
844 }else
845 key = -1;
846 if (key == 'q') {
847 av_log(NULL, AV_LOG_INFO, "\n\n[q] command received. Exiting.\n\n");
848 return AVERROR_EXIT;
849 }
850 if (key == '+') av_log_set_level(av_log_get_level()+10);
851 if (key == '-') av_log_set_level(av_log_get_level()-10);
852 if (key == 'c' || key == 'C'){
853 char buf[4096], target[64], command[256], arg[256] = {0};
854 double time;
855 int k, n = 0;
856 fprintf(stderr, "\nEnter command: <target>|all <time>|-1 <command>[ <argument>]\n");
857 i = 0;
858 set_tty_echo(1);
859 while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
860 if (k > 0)
861 buf[i++] = k;
862 buf[i] = 0;
863 set_tty_echo(0);
864 fprintf(stderr, "\n");
865 if (k > 0 &&
866 (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
867 av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
868 target, time, command, arg);
870 if (ost->fg_simple)
871 fg_send_command(ost->fg_simple, time, target, command, arg,
872 key == 'C');
873 }
874 for (i = 0; i < nb_filtergraphs; i++)
875 fg_send_command(filtergraphs[i], time, target, command, arg,
876 key == 'C');
877 } else {
879 "Parse error, at least 3 arguments were expected, "
880 "only %d given in string '%s'\n", n, buf);
881 }
882 }
883 if (key == '?'){
884 fprintf(stderr, "key function\n"
885 "? show this help\n"
886 "+ increase verbosity\n"
887 "- decrease verbosity\n"
888 "c Send command to first matching filter supporting it\n"
889 "C Send/Queue command to all matching filters\n"
890 "h dump packets/hex press to cycle through the 3 states\n"
891 "q quit\n"
892 "s Show QP histogram\n"
893 );
894 }
895 return 0;
896}
897
898/*
899 * The following code is the main loop of the file converter
900 */
901static int transcode(Scheduler *sch)
902{
903 int ret = 0;
904 int64_t timer_start, transcode_ts = 0;
905
907
909
910 ret = sch_start(sch);
911 if (ret < 0)
912 return ret;
913
914 if (stdin_interaction) {
915 av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
916 }
917
918 timer_start = av_gettime_relative();
919
920 while (!sch_wait(sch, stats_period, &transcode_ts)) {
921 int64_t cur_time= av_gettime_relative();
922
924 break;
925
926 /* if 'q' pressed, exits */
928 if (check_keyboard_interaction(cur_time) < 0)
929 break;
930
931 /* dump report by using the output first video and audio streams */
932 print_report(0, timer_start, cur_time, transcode_ts);
933 }
934
935 ret = sch_stop(sch, &transcode_ts);
936
937 /* write the trailer if needed */
938 for (int i = 0; i < nb_output_files; i++) {
939 int err = of_write_trailer(output_files[i]);
940 ret = err_merge(ret, err);
941 }
942
943 term_exit();
944
945 /* dump report by using the first video and audio streams */
946 print_report(1, timer_start, av_gettime_relative(), transcode_ts);
947
948 return ret;
949}
950
952{
953 BenchmarkTimeStamps time_stamps = { av_gettime_relative() };
954#if HAVE_GETRUSAGE
955 struct rusage rusage;
956
957 getrusage(RUSAGE_SELF, &rusage);
958 time_stamps.user_usec =
959 (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
960 time_stamps.sys_usec =
961 (rusage.ru_stime.tv_sec * 1000000LL) + rusage.ru_stime.tv_usec;
962#elif HAVE_GETPROCESSTIMES
963 HANDLE proc;
964 FILETIME c, e, k, u;
965 proc = GetCurrentProcess();
966 GetProcessTimes(proc, &c, &e, &k, &u);
967 time_stamps.user_usec =
968 ((int64_t)u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
969 time_stamps.sys_usec =
970 ((int64_t)k.dwHighDateTime << 32 | k.dwLowDateTime) / 10;
971#else
972 time_stamps.user_usec = time_stamps.sys_usec = 0;
973#endif
974 return time_stamps;
975}
976
977static int64_t getmaxrss(void)
978{
979#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
980 struct rusage rusage;
981 getrusage(RUSAGE_SELF, &rusage);
982 return (int64_t)rusage.ru_maxrss * 1024;
983#elif HAVE_GETPROCESSMEMORYINFO
984 HANDLE proc;
985 PROCESS_MEMORY_COUNTERS memcounters;
986 proc = GetCurrentProcess();
987 memcounters.cb = sizeof(memcounters);
988 GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
989 return memcounters.PeakPagefileUsage;
990#else
991 return 0;
992#endif
993}
994
995int main(int argc, char **argv)
996{
997 Scheduler *sch = NULL;
998
999 int ret;
1001
1002 init_dynload();
1003
1004 setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
1005
1007 parse_loglevel(argc, argv, options);
1008
1009#if CONFIG_AVDEVICE
1011#endif
1013
1014 show_banner(argc, argv, options);
1015
1016 sch = sch_alloc();
1017 if (!sch) {
1018 ret = AVERROR(ENOMEM);
1019 goto finish;
1020 }
1021
1022 /* parse options and open all input/output files */
1023 ret = ffmpeg_parse_options(argc, argv, sch);
1024 if (ret < 0)
1025 goto finish;
1026
1027 if (nb_output_files <= 0 && nb_input_files == 0) {
1028 show_usage();
1029 av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
1030 ret = 1;
1031 goto finish;
1032 }
1033
1034 if (nb_output_files <= 0) {
1035 av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
1036 ret = 1;
1037 goto finish;
1038 }
1039
1040#if CONFIG_MEDIACODEC
1042#endif
1043
1045 ret = transcode(sch);
1046 if (ret >= 0 && do_benchmark) {
1047 int64_t utime, stime, rtime;
1049 utime = current_time.user_usec - ti.user_usec;
1050 stime = current_time.sys_usec - ti.sys_usec;
1051 rtime = current_time.real_usec - ti.real_usec;
1053 "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
1054 utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
1055 }
1056
1057 ret = received_nb_signals ? 255 :
1058 (ret == FFMPEG_ERROR_RATE_EXCEEDED) ? 69 : ret;
1059
1060finish:
1061 if (ret == AVERROR_EXIT)
1062 ret = 0;
1063
1064 ffmpeg_cleanup(ret);
1065
1066 sch_free(&sch);
1067
1068 av_log(NULL, AV_LOG_VERBOSE, "\n");
1069 av_log(NULL, AV_LOG_VERBOSE, "Exiting with exit code %d\n", ret);
1070
1071 return ret;
1072}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define ECHO(name, type, min, max)
Definition af_aecho.c:157
Main libavdevice API header.
Main libavformat public API header.
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition avio.c:717
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition aviobuf.c:228
void android_binder_threadpool_init_if_required(void)
Initialize Android Binder thread pool.
static uint32_t BS_FUNC read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:122
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_AUTOMATIC
#define flag(name)
Definition cbs_h264.c:60
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
void init_dynload(void)
Initialize dynamic library loading.
Definition cmdutils.c:75
void parse_loglevel(int argc, char **argv, const OptionDef *options)
Find the '-loglevel' option in the command line args and apply it.
Definition cmdutils.c:556
void uninit_opts(void)
Uninitialize the cmdutils option system, in particular free the *_opts contexts and their contents.
Definition cmdutils.c:62
const char program_name[]
program name, defined by the program for show_version().
Definition ffmpeg.c:89
void show_banner(int argc, char **argv, const OptionDef *options)
Print the program banner to stderr.
Definition opt_common.c:240
const int program_birth_year
program birth year, defined by the program for show_banner()
Definition ffmpeg.c:90
AVCodecParameters * avcodec_parameters_alloc(void)
Definition codec_par.c:57
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Definition codec_par.c:107
void avcodec_parameters_free(AVCodecParameters **ppar)
Definition codec_par.c:67
#define FFABS64U(a)
Definition common.h:92
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
static AVPacket * pkt
static AVFrame * frame
Public dictionary API.
int main
Definition dovi_rpuenc.c:38
#define atomic_store(object, desired)
Definition stdatomic.h:85
intptr_t atomic_int
Definition stdatomic.h:55
#define atomic_load(object)
Definition stdatomic.h:93
intptr_t atomic_uint
Definition stdatomic.h:56
const FrameData * frame_data_c(AVFrame *frame)
Definition ffmpeg.c:497
AVIOContext * progress_avio
Definition ffmpeg.c:106
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
Definition ffmpeg.c:491
static void set_tty_echo(int on)
Definition ffmpeg.c:824
static int check_keyboard_interaction(int64_t cur_time)
Definition ffmpeg.c:836
static BenchmarkTimeStamps get_benchmark_time_stamps(void)
Definition ffmpeg.c:951
void term_exit(void)
Definition ffmpeg.c:135
static volatile int received_sigterm
Definition ffmpeg.c:141
static void frame_data_free(void *opaque, uint8_t *data)
Definition ffmpeg.c:413
FrameData * packet_data(AVPacket *pkt)
Definition ffmpeg.c:503
static void print_stream_maps(void)
Definition ffmpeg.c:748
int nb_filtergraphs
Definition ffmpeg.c:115
const FrameData * packet_data_c(AVPacket *pkt)
Definition ffmpeg.c:509
InputFile ** input_files
Definition ffmpeg.c:108
const AVIOInterruptCB int_cb
Definition ffmpeg.c:322
OutputStream * ost_iter(OutputStream *prev)
Definition ffmpeg.c:381
static int64_t getmaxrss(void)
Definition ffmpeg.c:977
int nb_input_files
Definition ffmpeg.c:109
FilterGraph ** filtergraphs
Definition ffmpeg.c:114
static int frame_data_ensure(AVBufferRef **dst, int writable)
Definition ffmpeg.c:424
static volatile int ffmpeg_exited
Definition ffmpeg.c:144
int nb_output_files
Definition ffmpeg.c:112
static int read_key(void)
Definition ffmpeg.c:264
Decoder ** decoders
Definition ffmpeg.c:117
atomic_uint nb_output_dumped
Definition ffmpeg.c:103
#define SIGNAL(sig, func)
Definition ffmpeg.c:201
static int decode_interrupt_cb(void *ctx)
Definition ffmpeg.c:317
int nb_decoders
Definition ffmpeg.c:118
static void term_exit_sigsafe(void)
Definition ffmpeg.c:127
static volatile int received_nb_signals
Definition ffmpeg.c:142
static int64_t copy_ts_first_pts
Definition ffmpeg.c:145
FILE * vstats_file
Definition ffmpeg.c:92
static BenchmarkTimeStamps current_time
Definition ffmpeg.c:105
int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used, void *logctx, int decode)
Definition ffmpeg.c:515
static int transcode(Scheduler *sch)
Definition ffmpeg.c:901
static void ffmpeg_cleanup(int ret)
Definition ffmpeg.c:324
void term_init(void)
Definition ffmpeg.c:205
void update_benchmark(const char *fmt,...)
Definition ffmpeg.c:565
OutputFile ** output_files
Definition ffmpeg.c:111
InputStream * ist_iter(InputStream *prev)
Definition ffmpeg.c:397
static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts)
Definition ffmpeg.c:586
static void sigterm_handler(int sig)
Definition ffmpeg.c:148
static atomic_int transcode_init_done
Definition ffmpeg.c:143
char * filter_nbthreads
Definition ffmpeg_opt.c:73
void dec_free(Decoder **pdec)
Definition ffmpeg_dec.c:118
int64_t of_filesize(OutputFile *of)
Definition ffmpeg_mux.c:883
int print_stats
Definition ffmpeg_opt.c:70
int stdin_interaction
Definition ffmpeg_opt.c:71
int do_benchmark
Definition ffmpeg_opt.c:60
void ifile_close(InputFile **f)
#define FFMPEG_ERROR_RATE_EXCEEDED
Definition ffmpeg.h:54
void fg_send_command(FilterGraph *fg, double time, const char *target, const char *command, const char *arg, int all_filters)
void show_usage(void)
char * print_graphs_format
Definition ffmpeg_opt.c:79
void of_free(OutputFile **pof)
Definition ffmpeg_mux.c:856
int ffmpeg_parse_options(int argc, char **argv, Scheduler *sch)
void hw_device_free_all(void)
Definition ffmpeg_hw.c:286
int print_graphs
Definition ffmpeg_opt.c:77
char * vstats_filename
Definition ffmpeg_opt.c:54
void of_enc_stats_close(void)
int of_write_trailer(OutputFile *of)
Definition ffmpeg_mux.c:752
char * print_graphs_file
Definition ffmpeg_opt.c:78
int64_t stats_period
Definition ffmpeg_opt.c:81
int copy_ts
Definition ffmpeg_opt.c:64
int do_benchmark_all
Definition ffmpeg_opt.c:61
int filtergraph_is_simple(const FilterGraph *fg)
void fg_free(FilterGraph **pfg)
const char * key
Scheduler * sch_alloc(void)
int sch_start(Scheduler *sch)
int sch_stop(Scheduler *sch, int64_t *finish_ts)
int sch_wait(Scheduler *sch, uint64_t timeout_us, int64_t *transcode_ts)
Wait until transcoding terminates or the specified timeout elapses.
void sch_free(Scheduler **psch)
static int err_merge(int err0, int err1)
Merge two return codes - return one of the error codes if at least one of them was negative,...
static int clone_side_data(AVFrameSideData ***dst, int *nb_dst, AVFrameSideData *const *src, int nb_src, unsigned int flags)
Wrapper calling av_frame_side_data_clone() in a loop for all source entries.
static unsigned int nb_streams
Definition ffprobe.c:352
int print_filtergraphs(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
const AVClass * avcodec_get_class(void)
Get the AVClass for AVCodecContext.
Definition options.c:184
FF_VISIBILITY_POP_HIDDEN av_cold void avdevice_register_all(void)
Initialize libavdevice and register all the input and output devices.
Definition alldevices.c:67
int avformat_network_deinit(void)
Undo the initialization done by avformat_network_init.
Definition utils.c:579
int avformat_network_init(void)
Do global initialization of network libraries.
Definition utils.c:567
const AVClass * avformat_get_class(void)
Get the AVClass for AVFormatContext.
Definition options.c:193
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
int av_buffer_is_writable(const AVBufferRef *buf)
Definition buffer.c:147
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition avutil.h:226
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition error.h:58
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
Free all side data entries and their contents, then zeroes out the values which the pointers are poin...
Definition side_data.c:139
#define AV_LOG_QUIET
Print no output.
Definition log.h:192
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void av_log_set_level(int level)
Set the log level.
Definition log.c:476
#define AV_LOG_SKIP_REPEATED
Skip repeated messages, this requires the user app to use av_log() instead of (f)printf as the 2 woul...
Definition log.h:400
int av_log_get_level(void)
Get the current log level.
Definition log.c:471
void av_log_set_flags(int arg)
Definition log.c:481
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition opt.h:604
const AVOption * av_opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
Look for an option in an object.
Definition opt.c:2067
#define AV_OPT_SEARCH_FAKE_OBJ
The obj passed to av_opt_find() or av_opt_set() is fake – only a double pointer to AVClass instead of...
Definition opt.h:612
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
#define us(width, name, range_min, range_max, subs,...)
Definition cbs_apv.c:70
const char * arg
Definition jacosubdec.c:65
option
Definition libkvazaar.c:312
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define av_strdup(s)
Definition ops_static.c:55
static volatile sig_atomic_t sig
Definition signal.c:48
#define FF_ARRAY_ELEMS(a)
#define vsnprintf
Definition snprintf.h:36
A reference to a data buffer.
Definition buffer.h:82
Describe the class of an AVClass context structure.
Definition log.h:76
This struct describes the properties of a single codec described by an AVCodecID.
Definition codec_desc.h:38
AVCodec.
Definition codec.h:175
enum AVCodecID id
Definition codec.h:189
const char * name
Name of the codec implementation.
Definition codec.h:182
char * key
Definition dict.h:91
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
Bytestream IO Context.
Definition avio.h:160
Callback for checking whether to abort blocking functions.
Definition avio.h:59
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int64_t sys_usec
Definition ffmpeg.c:97
int64_t real_usec
Definition ffmpeg.c:95
int64_t user_usec
Definition ffmpeg.c:96
uint64_t frame_num
Definition ffmpeg.h:711
struct FrameData::@304126211346234154321045014345346376220164157123 dec
int64_t wallclock[LATENCY_PROBE_NB]
Definition ffmpeg.h:721
int64_t pts
Definition ffmpeg.h:713
int nb_side_data
Definition ffmpeg.h:726
AVCodecParameters * par_enc
Definition ffmpeg.h:723
AVFrameSideData ** side_data
Definition ffmpeg.h:725
AVDictionary * reinit_opts
Definition ffmpeg.h:728
int index
Definition ffmpeg.h:511
int index
Definition ffmpeg.h:471
struct InputFile * file
Definition ffmpeg.h:469
int index
Definition ffmpeg.h:690
OutputStream ** streams
Definition ffmpeg.h:694
struct OutputFile * file
Definition ffmpeg.h:641
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
int64_t bitrate
Definition av1_levels.c:47
#define src
Definition vp8dsp.c:248
static AVFormatContext * ctx
Definition movenc.c:49
static void finish(void)
Definition movenc.c:374
static AVDictionary * opts
Definition movenc.c:51
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition time.c:57
static int64_t pts
static AVStream * ost
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
static double c[64]