summaryrefslogtreecommitdiff
path: root/fftools
diff options
context:
space:
mode:
authorGyan Doshi <ffmpeg@gyani.pro>2021-07-16 17:59:39 +0530
committerGyan Doshi <ffmpeg@gyani.pro>2021-07-17 20:34:21 +0530
commitc320b78e95bab2a71a636dc4da905522c4646b35 (patch)
tree55053642cd89687b0e6072a3a83846b8219c2e60 /fftools
parent075157ec867e0bf8d500bbbd23fee86f37eff45a (diff)
ffmpeg: add option readrate
Allows to read inputs at arbitrary rates. -re is equivalent to -readrate 1 Tested with -copyts {+ start_at_zero}, -ss, streamcopied & decoded streams.
Diffstat (limited to 'fftools')
-rw-r--r--fftools/ffmpeg.c13
-rw-r--r--fftools/ffmpeg.h2
-rw-r--r--fftools/ffmpeg_opt.c16
3 files changed, 27 insertions, 4 deletions
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 1ac2e48600..e0f2fe138f 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3765,7 +3765,7 @@ static int transcode_init(void)
/* init framerate emulation */
for (i = 0; i < nb_input_files; i++) {
InputFile *ifile = input_files[i];
- if (ifile->rate_emu)
+ if (ifile->readrate || ifile->rate_emu)
for (j = 0; j < ifile->nb_streams; j++)
input_streams[j + ifile->ist_index]->start = av_gettime_relative();
}
@@ -4225,12 +4225,19 @@ static int get_input_packet_mt(InputFile *f, AVPacket **pkt)
static int get_input_packet(InputFile *f, AVPacket **pkt)
{
- if (f->rate_emu) {
+ if (f->readrate || f->rate_emu) {
int i;
+ int64_t file_start = copy_ts * (
+ (f->ctx->start_time != AV_NOPTS_VALUE ? f->ctx->start_time * !start_at_zero : 0) +
+ (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
+ );
+ float scale = f->rate_emu ? 1.0 : f->readrate;
for (i = 0; i < f->nb_streams; i++) {
InputStream *ist = input_streams[f->ist_index + i];
+ if (!ist->nb_packets) continue;
+ int64_t stream_ts_offset = FFMAX(ist->first_dts != AV_NOPTS_VALUE ? ist->first_dts : 0, file_start);
int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
- int64_t now = av_gettime_relative() - ist->start;
+ int64_t now = (av_gettime_relative() - ist->start)*scale + stream_ts_offset;
if (pts > now)
return AVERROR(EAGAIN);
}
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 3cfb4c4488..6308fb5aeb 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -119,6 +119,7 @@ typedef struct OptionsContext {
int64_t input_ts_offset;
int loop;
int rate_emu;
+ float readrate;
int accurate_seek;
int thread_queue_size;
@@ -418,6 +419,7 @@ typedef struct InputFile {
from ctx.nb_streams if new streams appear during av_read_frame() */
int nb_streams_warn; /* number of streams that the user was warned of */
int rate_emu;
+ float readrate;
int accurate_seek;
AVPacket *pkt;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index cb7d6ceefc..9558bcaeb2 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1286,6 +1286,17 @@ static int open_input_file(OptionsContext *o, const char *filename)
f->loop = o->loop;
f->duration = 0;
f->time_base = (AVRational){ 1, 1 };
+
+ f->readrate = o->readrate ? o->readrate : 0.0;
+ if (f->readrate < 0.0f) {
+ av_log(NULL, AV_LOG_ERROR, "Option -readrate for Input #%d is %0.3f; it must be non-negative.\n", nb_input_files, f->readrate);
+ exit_program(1);
+ }
+ if (f->readrate && f->rate_emu) {
+ av_log(NULL, AV_LOG_WARNING, "Both -readrate and -re set for Input #%d. Using -readrate %0.3f.\n", nb_input_files, f->readrate);
+ f->rate_emu = 0;
+ }
+
f->pkt = av_packet_alloc();
if (!f->pkt)
exit_program(1);
@@ -3507,7 +3518,10 @@ const OptionDef options[] = {
"when dumping packets, also dump the payload" },
{ "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
OPT_INPUT, { .off = OFFSET(rate_emu) },
- "read input at native frame rate", "" },
+ "read input at native frame rate; equivalent to -readrate 1", "" },
+ { "readrate", HAS_ARG | OPT_FLOAT | OPT_OFFSET |
+ OPT_EXPERT | OPT_INPUT, { .off = OFFSET(readrate) },
+ "read input at specified rate", "speed" },
{ "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
"specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\" or \"dv50\" "
"with optional prefixes \"pal-\", \"ntsc-\" or \"film-\")", "type" },