mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
video: pass through container fps to filters
This means vf_vapoursynth doesn't need a hack to work around the filter code, and libavfilter filters now actually get the frame_rate field on input pads set. The libavfilter doxygen says the frame_rate field is only to be set if the frame rate is known to be constant, and uses the word "must" (which probably means they really mean it?) - but ffmpeg.c sets the field to mere guesses anyway, and it looks like this normally won't lead to problems.
This commit is contained in:
parent
e7e06a47a0
commit
ff24285eb1
@ -358,6 +358,7 @@ static void process_video_frame(struct priv *p, struct mp_image *mpi)
|
||||
fix_image_params(p, &mpi->params);
|
||||
|
||||
mpi->params = p->fixed_format;
|
||||
mpi->nominal_fps = p->public.fps;
|
||||
|
||||
mpi->pts = pts;
|
||||
p->pts = pts;
|
||||
|
@ -340,7 +340,8 @@ static bool is_vformat_ok(struct mp_image *a, struct mp_image *b)
|
||||
{
|
||||
return a->imgfmt == b->imgfmt &&
|
||||
a->w == b->w && a->h && b->h &&
|
||||
a->params.p_w == b->params.p_w && a->params.p_h == b->params.p_h;
|
||||
a->params.p_w == b->params.p_w && a->params.p_h == b->params.p_h &&
|
||||
a->nominal_fps == b->nominal_fps;
|
||||
}
|
||||
static bool is_format_ok(struct mp_frame a, struct mp_frame b)
|
||||
{
|
||||
@ -483,6 +484,7 @@ static bool init_pads(struct lavfi *c)
|
||||
params->sample_aspect_ratio.num = fmt->params.p_w;
|
||||
params->sample_aspect_ratio.den = fmt->params.p_h;
|
||||
params->hw_frames_ctx = fmt->hwctx;
|
||||
params->frame_rate = av_d2q(fmt->nominal_fps, 1000000);
|
||||
filter_name = "buffer";
|
||||
} else {
|
||||
assert(0);
|
||||
@ -680,6 +682,11 @@ static bool read_output_pads(struct lavfi *c)
|
||||
mp_aframe_set_pts(aframe, c->in_pts +
|
||||
(c->in_pts != MP_NOPTS_VALUE ? (out_time - in_time) : 0));
|
||||
}
|
||||
if (frame.type == MP_FRAME_VIDEO) {
|
||||
struct mp_image *vframe = frame.data;
|
||||
vframe->nominal_fps =
|
||||
av_q2d(av_buffersink_get_frame_rate(pad->buffer));
|
||||
}
|
||||
av_frame_unref(c->tmp_frame);
|
||||
if (frame.type) {
|
||||
mp_pin_in_write(pad->pin, frame);
|
||||
|
@ -357,12 +357,6 @@ static double get_display_fps(struct mp_stream_info *i)
|
||||
return res;
|
||||
}
|
||||
|
||||
static double get_container_fps(struct mp_stream_info *i)
|
||||
{
|
||||
struct chain *p = i->priv;
|
||||
return p->public.container_fps;
|
||||
}
|
||||
|
||||
void mp_output_chain_set_vo(struct mp_output_chain *c, struct vo *vo)
|
||||
{
|
||||
struct chain *p = c->f->priv;
|
||||
@ -650,7 +644,6 @@ static void create_video_things(struct chain *p)
|
||||
|
||||
p->stream_info.priv = p;
|
||||
p->stream_info.get_display_fps = get_display_fps;
|
||||
p->stream_info.get_container_fps = get_container_fps;
|
||||
|
||||
p->f->stream_info = &p->stream_info;
|
||||
|
||||
|
@ -382,7 +382,6 @@ struct mp_stream_info {
|
||||
void *priv; // for use by whoever implements the callbacks
|
||||
|
||||
double (*get_display_fps)(struct mp_stream_info *i);
|
||||
double (*get_container_fps)(struct mp_stream_info *i);
|
||||
|
||||
struct mp_hwdec_devices *hwdec_devs;
|
||||
struct osd_state *osd;
|
||||
|
@ -103,7 +103,7 @@ static const struct mp_image dummy_img;
|
||||
static const struct mp_image dummy_img_eof;
|
||||
|
||||
static void destroy_vs(struct priv *p);
|
||||
static int reinit_vs(struct priv *p);
|
||||
static int reinit_vs(struct priv *p, struct mp_image *input);
|
||||
|
||||
struct script_driver {
|
||||
int (*init)(struct priv *p); // first time init
|
||||
@ -368,7 +368,7 @@ static void vf_vapoursynth_process(struct mp_filter *f)
|
||||
if (p->out_node)
|
||||
destroy_vs(p);
|
||||
p->fmt_in = mpi->params;
|
||||
if (reinit_vs(p) < 0) {
|
||||
if (reinit_vs(p, mpi) < 0) {
|
||||
MP_ERR(p, "could not init VS\n");
|
||||
mp_frame_unref(&frame);
|
||||
return;
|
||||
@ -617,7 +617,7 @@ static void destroy_vs(struct priv *p)
|
||||
MP_DBG(p, "uninitialized.\n");
|
||||
}
|
||||
|
||||
static int reinit_vs(struct priv *p)
|
||||
static int reinit_vs(struct priv *p, struct mp_image *input)
|
||||
{
|
||||
VSMap *vars = NULL, *in = NULL, *out = NULL;
|
||||
int res = -1;
|
||||
@ -665,11 +665,9 @@ static int reinit_vs(struct priv *p)
|
||||
p->vsapi->propSetInt(vars, "video_in_dh", d_h, 0);
|
||||
|
||||
struct mp_stream_info *info = mp_filter_find_stream_info(p->f);
|
||||
double container_fps = 0;
|
||||
double container_fps = input->nominal_fps;
|
||||
double display_fps = 0;
|
||||
if (info) {
|
||||
if (info->get_container_fps)
|
||||
container_fps = info->get_container_fps(info);
|
||||
if (info->get_display_fps)
|
||||
display_fps = info->get_display_fps(info);
|
||||
}
|
||||
|
@ -508,6 +508,7 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
|
||||
dst->params.color = src->params.color;
|
||||
dst->params.chroma_location = src->params.chroma_location;
|
||||
dst->params.spherical = src->params.spherical;
|
||||
dst->nominal_fps = src->nominal_fps;
|
||||
// ensure colorspace consistency
|
||||
if (mp_image_params_get_forced_csp(&dst->params) !=
|
||||
mp_image_params_get_forced_csp(&src->params))
|
||||
|
@ -105,6 +105,8 @@ typedef struct mp_image {
|
||||
double pts;
|
||||
/* only after decoder */
|
||||
double dts, pkt_duration;
|
||||
/* container reported FPS; can be incorrect, or 0 if unknown */
|
||||
double nominal_fps;
|
||||
/* for private use */
|
||||
void* priv;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user