History

vf_vapoursynth: pass image properties from input

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.

Kacper Michajłow committed 2 years ago

Commit 21e167c1 parent 83e51a81 file · +21 −9Browse files

Unified · Split

video/filter/vf_vapoursynth.c+21−9
@@ -209,6 +209,10 @@ static void copy_mp_to_vs_frame_props_map(struct priv *p, VSMap *map, · 208 unmodified lines
209 if (img->fields & MP_IMGFIELD_INTERLACED)209 if (img->fields & MP_IMGFIELD_INTERLACED)
210 field = img->fields & MP_IMGFIELD_TOP_FIRST ? 2 : 1;210 field = img->fields & MP_IMGFIELD_TOP_FIRST ? 2 : 1;
211 p->vsapi->propSetInt(map, "_FieldBased", field, 0);211 p->vsapi->propSetInt(map, "_FieldBased", field, 0);
212
213 // Don't increase the reference count. It is not intended to be read externally,
214 // and we know it will be alive when we retrieve it.
215 p->vsapi->propSetData(map, "_MP_IMAGE", (const char *)img, sizeof(*img), 0);
212}216}
213 217
214static int set_vs_frame_props(struct priv *p, VSFrameRef *frame,218static int set_vs_frame_props(struct priv *p, VSFrameRef *frame,
@@ -231,11 +235,13 @@ static VSFrameRef *alloc_vs_frame(struct priv *p, struct mp_image_params *fmt) · 16 unmodified lines
231}235}
232 236
233static struct mp_image map_vs_frame(struct priv *p, const VSFrameRef *ref,237static struct mp_image map_vs_frame(struct priv *p, const VSFrameRef *ref,
234 bool w)238 bool w, struct mp_image *ref_image)
235{239{
236 const VSFormat *fmt = p->vsapi->getFrameFormat(ref);240 const VSFormat *fmt = p->vsapi->getFrameFormat(ref);
237 241
238 struct mp_image img = {0};242 struct mp_image img = {0};
243 if (ref_image)
244 img = *ref_image;
239 mp_image_setfmt(&img, mp_from_vs(fmt->id));245 mp_image_setfmt(&img, mp_from_vs(fmt->id));
240 mp_image_set_size(&img, p->vsapi->getFrameWidth(ref, 0),246 mp_image_set_size(&img, p->vsapi->getFrameWidth(ref, 0),
241 p->vsapi->getFrameHeight(ref, 0));247 p->vsapi->getFrameHeight(ref, 0));
@@ -270,13 +276,19 @@ static void VS_CC vs_frame_done(void *userData, const VSFrameRef *f, int n, · 28 unmodified lines
270 276
271 struct mp_image *res = NULL;277 struct mp_image *res = NULL;
272 if (f) {278 if (f) {
273 struct mp_image img = map_vs_frame(p, f, false);
274 struct mp_image dummy = {.params = p->fmt_in};
275 if (p->fmt_in.w != img.w || p->fmt_in.h != img.h)
276 dummy.params.crop = (struct mp_rect){0, 0, img.w, img.h};
277 mp_image_copy_attributes(&img, &dummy);
278 img.pkt_duration = -1;
279 const VSMap *map = p->vsapi->getFramePropsRO(f);279 const VSMap *map = p->vsapi->getFramePropsRO(f);
280 if (!map)
281 MP_ERR(p, "Failed to get frame properties!");
282 struct mp_image *mpi = NULL;
283 if (map) {
284 mpi = (void *)p->vsapi->propGetData(map, "_MP_IMAGE", 0, NULL);
285 if (!mpi)
286 MP_ERR(p, "Failed to get mp_image attributes!");
287 }
288 struct mp_image img = map_vs_frame(p, f, false, mpi);
289 img.pkt_duration = -1;
290 if (mpi && (mpi->params.w != img.w || mpi->params.h != img.h))
291 img.params.crop = (struct mp_rect){0, 0, img.w, img.h};
280 if (map) {292 if (map) {
281 int err1, err2;293 int err1, err2;
282 int num = p->vsapi->propGetInt(map, "_DurationNum", 0, &err1);294 int num = p->vsapi->propGetInt(map, "_DurationNum", 0, &err1);
@@ -491,7 +503,7 @@ static const VSFrameRef *VS_CC infiltGetFrame(int frameno, int activationReason, · 208 unmodified lines
491 p->vsapi->setFilterError("Could not allocate VS frame", frameCtx);503 p->vsapi->setFilterError("Could not allocate VS frame", frameCtx);
492 break;504 break;
493 }505 }
494 struct mp_image vsframe = map_vs_frame(p, ret, true);506 struct mp_image vsframe = map_vs_frame(p, ret, true, NULL);
495 mp_image_clear(&vsframe, 0, 0, p->fmt_in.w, p->fmt_in.h);507 mp_image_clear(&vsframe, 0, 0, p->fmt_in.w, p->fmt_in.h);
496 struct mp_image dummy = {0};508 struct mp_image dummy = {0};
497 mp_image_set_params(&dummy, &p->fmt_in);509 mp_image_set_params(&dummy, &p->fmt_in);
@@ -539,7 +551,7 @@ static const VSFrameRef *VS_CC infiltGetFrame(int frameno, int activationReason, · 41 unmodified lines
539 }551 }
540 552
541 mp_mutex_unlock(&p->lock);553 mp_mutex_unlock(&p->lock);
542 struct mp_image vsframe = map_vs_frame(p, ret, true);554 struct mp_image vsframe = map_vs_frame(p, ret, true, NULL);
543 mp_image_copy(&vsframe, img);555 mp_image_copy(&vsframe, img);
544 int res = 1e6;556 int res = 1e6;
545 int dur = img->pkt_duration * res + 0.5;557 int dur = img->pkt_duration * res + 0.5;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t