Skip to content

Commit

Permalink
vf_vapoursynth: pass image properties from input
Browse files Browse the repository at this point in the history
This might not always be correct depending on filtering done in VS. But
unless VS send us all the metadata we have to get it from somewhere.

Fixes dynamic frame metadata, which was copied from fmt_in, initialized
only upon reinitialization.

Fixes crashes caused by the use of stale pointers.

Fixes: #13956
  • Loading branch information
kasper93 committed May 11, 2024
1 parent c9b58f9 commit 31f8755
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions video/filter/vf_vapoursynth.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ static void copy_mp_to_vs_frame_props_map(struct priv *p, VSMap *map,
if (img->fields & MP_IMGFIELD_INTERLACED)
field = img->fields & MP_IMGFIELD_TOP_FIRST ? 2 : 1;
p->vsapi->propSetInt(map, "_FieldBased", field, 0);

// Don't ref passed frame, it is not meant to be read externally and we know
// it will be alive once we get it back.
p->vsapi->propSetData(map, "_MP_IMAGE", (const char *)img, sizeof(*img), 0);
}

static int set_vs_frame_props(struct priv *p, VSFrameRef *frame,
Expand Down Expand Up @@ -271,10 +275,6 @@ static void VS_CC vs_frame_done(void *userData, const VSFrameRef *f, int n,
struct mp_image *res = NULL;
if (f) {
struct mp_image img = map_vs_frame(p, f, false);
struct mp_image dummy = {.params = p->fmt_in};
if (p->fmt_in.w != img.w || p->fmt_in.h != img.h)
dummy.params.crop = (struct mp_rect){0, 0, img.w, img.h};
mp_image_copy_attributes(&img, &dummy);
img.pkt_duration = -1;
const VSMap *map = p->vsapi->getFramePropsRO(f);
if (map) {
Expand All @@ -283,6 +283,18 @@ static void VS_CC vs_frame_done(void *userData, const VSFrameRef *f, int n,
int den = p->vsapi->propGetInt(map, "_DurationDen", 0, &err2);
if (!err1 && !err2)
img.pkt_duration = num / (double)den;

const struct mp_image *mpi = (void *)p->vsapi->propGetData(map, "_MP_IMAGE", 0, &err1);
if (!err1) {
// mp_image_new_copy will add new refs to it
img.params = mpi->params;
if (mpi->params.w != img.w || mpi->params.h != img.h)
img.params.crop = (struct mp_rect){0, 0, img.w, img.h};
} else {
MP_ERR(p, "Failed to get mp_image attributes!");
}
} else {
MP_ERR(p, "Failed to get frame properties!");
}
if (img.pkt_duration < 0) {
MP_ERR(p, "No PTS after filter at frame %d!\n", n);
Expand Down

0 comments on commit 31f8755

Please sign in to comment.