summaryrefslogtreecommitdiffstats
path: root/filters
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-04-12 22:08:56 +0200
committerJan Ekström <jeebjp@gmail.com>2018-04-15 23:11:33 +0300
commit7bfb240309225fa6fb4e51a0deda8fd8e34953e0 (patch)
tree7c912d645a3e786e8713d93cbbaf3b9b73a65885 /filters
parent3ca0a7fd4d6615e438fdc80192dca951fff74ff1 (diff)
downloadmpv-7bfb240309225fa6fb4e51a0deda8fd8e34953e0.tar.bz2
mpv-7bfb240309225fa6fb4e51a0deda8fd8e34953e0.tar.xz
f_lavfi: add an option to use old audio PTS handling for af_lavfi
The fix-pts option basically uses the old af_lavfi's (before filter rewrite) timestamp logic. The rest is explained in the manpage.
Diffstat (limited to 'filters')
-rw-r--r--filters/f_lavfi.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/filters/f_lavfi.c b/filters/f_lavfi.c
index 3716dd1f85..1b41c93aac 100644
--- a/filters/f_lavfi.c
+++ b/filters/f_lavfi.c
@@ -93,6 +93,12 @@ struct lavfi {
AVFrame *tmp_frame;
+ // Audio timestamp emulation.
+ bool emulate_audio_pts;
+ double in_pts; // last input timestamps
+ int64_t in_samples; // samples ever sent to the filter
+ double delay; // seconds of audio apparently buffered by filter
+
struct mp_lavfi public;
};
@@ -137,6 +143,9 @@ static void free_graph(struct lavfi *c)
}
c->initialized = false;
c->draining_recover = false;
+ c->in_pts = MP_NOPTS_VALUE;
+ c->in_samples = 0;
+ c->delay = 0;
}
static void add_pad(struct lavfi *c, int dir, int index, AVFilterContext *filter,
@@ -611,6 +620,13 @@ static bool feed_input_pads(struct lavfi *c)
AVFrame *frame = mp_frame_to_av(pad->pending, &pad->timebase);
bool eof = pad->pending.type == MP_FRAME_EOF;
+ if (c->emulate_audio_pts && pad->pending.type == MP_FRAME_AUDIO) {
+ struct mp_aframe *aframe = pad->pending.data;
+ c->in_pts = mp_aframe_end_pts(aframe);
+ frame->pts = c->in_samples; // timebase is 1/sample_rate
+ c->in_samples += frame->nb_samples;
+ }
+
mp_frame_unref(&pad->pending);
if (!frame && !eof) {
@@ -656,6 +672,14 @@ static bool read_output_pads(struct lavfi *c)
#endif
struct mp_frame frame =
mp_frame_from_av(pad->type, c->tmp_frame, &pad->timebase);
+ if (c->emulate_audio_pts && frame.type == MP_FRAME_AUDIO) {
+ AVFrame *avframe = c->tmp_frame;
+ struct mp_aframe *aframe = frame.data;
+ double in_time = c->in_samples * av_q2d(c->in_pads[0]->timebase);
+ double out_time = avframe->pts * av_q2d(pad->timebase);
+ mp_aframe_set_pts(aframe, c->in_pts +
+ (c->in_pts != MP_NOPTS_VALUE ? (out_time - in_time) : 0));
+ }
av_frame_unref(c->tmp_frame);
if (frame.type) {
mp_pin_in_write(pad->pin, frame);
@@ -871,6 +895,8 @@ struct lavfi_user_opts {
char *filter_name;
char **filter_opts;
+
+ int fix_pts;
};
static struct mp_filter *lavfi_create(struct mp_filter *parent, void *options)
@@ -884,6 +910,10 @@ static struct mp_filter *lavfi_create(struct mp_filter *parent, void *options)
l = mp_lavfi_create_graph(parent, opts->type, true,
opts->avopts, opts->graph);
}
+ if (l) {
+ struct lavfi *c = l->f->priv;
+ c->emulate_audio_pts = opts->fix_pts;
+ }
talloc_free(opts);
return l ? l->f : NULL;
}
@@ -1030,6 +1060,7 @@ const struct mp_user_filter_entry af_lavfi = {
.priv_size = sizeof(OPT_BASE_STRUCT),
.options = (const m_option_t[]){
OPT_STRING("graph", graph, M_OPT_MIN, .min = 1),
+ OPT_FLAG("fix-pts", fix_pts, 0),
OPT_KEYVALUELIST("o", avopts, 0),
{0}
},