void VS_CC rffFree(void *instanceData, VSCore *core, const VSAPI *vsapi) { rffData *d = (rffData *) instanceData; vsapi->freeNode(d->node); d2vfreep(&d->d2v); d->fields.clear(); delete d; }
void VS_CC d2vFree(void *instanceData, VSCore *core, const VSAPI *vsapi) { d2vData *d = (d2vData *) instanceData; d2vfreep(&d->d2v); decodefreep(&d->dec); av_frame_unref(d->frame); av_freep(&d->frame); free(d); }
void VS_CC d2vCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) { d2vData *data; string msg; bool no_crop; bool rff; int threads; int err; /* Need to get thread info before anything to pass to decodeinit(). */ threads = vsapi->propGetInt(in, "threads", 0, &err); if (err) threads = 0; if (threads < 0) { vsapi->setError(out, "Invalid number of threads."); return; } /* Allocate our private data. */ data = (d2vData *) malloc(sizeof(*data)); if (!data) { vsapi->setError(out, "Cannot allocate private data."); return; } data->d2v = d2vparse((char *) vsapi->propGetData(in, "input", 0, 0), msg); if (!data->d2v) { vsapi->setError(out, msg.c_str()); free(data); return; } data->dec = decodeinit(data->d2v, threads, msg); if (!data->dec) { vsapi->setError(out, msg.c_str()); d2vfreep(&data->d2v); free(data); return; } /* * Make our private data available to libavcodec, and * set our custom get/release_buffer funcs. */ data->dec->avctx->opaque = (void *) data; data->dec->avctx->get_buffer2 = VSGetBuffer; data->vi.numFrames = data->d2v->frames.size(); data->vi.width = data->d2v->width; data->vi.height = data->d2v->height; data->vi.fpsNum = data->d2v->fps_num; data->vi.fpsDen = data->d2v->fps_den; /* Stash the pointer to our core. */ data->core = core; data->api = (VSAPI *) vsapi; /* * Stash our aligned width and height for use with our * custom get_buffer, since it could require this. */ data->aligned_width = FFALIGN(data->vi.width, 16); data->aligned_height = FFALIGN(data->vi.height, 32); data->frame = av_frame_alloc(); if (!data->frame) { vsapi->setError(out, "Cannot allocate AVFrame."); d2vfreep(&data->d2v); decodefreep(&data->dec); free(data); return; } /* * Decode 1 frame to find out how the chroma is subampled. * The first time our custom get_buffer is called, it will * fill in data->vi.format. */ data->format_set = false; err = decodeframe(0, data->d2v, data->dec, data->frame, msg); if (err < 0) { msg.insert(0, "Failed to decode test frame: "); vsapi->setError(out, msg.c_str()); d2vfreep(&data->d2v); decodefreep(&data->dec); av_frame_unref(data->frame); av_freep(&data->frame); free(data); return; } /* See if nocrop is enabled, and set the width/height accordingly. */ no_crop = !!vsapi->propGetInt(in, "nocrop", 0, &err); if (err) no_crop = false; if (no_crop) { data->vi.width = data->aligned_width; data->vi.height = data->aligned_height; } vsapi->createFilter(in, out, "d2vsource", d2vInit, d2vGetFrame, d2vFree, fmUnordered, nfMakeLinear, data, core); rff = !!vsapi->propGetInt(in, "rff", 0, &err); if (err) rff = true; if (rff) { VSPlugin *d2vPlugin = vsapi->getPluginById("com.sources.d2vsource", core); VSPlugin *corePlugin = vsapi->getPluginById("com.vapoursynth.std", core); VSNodeRef *before = vsapi->propGetNode(out, "clip", 0, NULL); VSNodeRef *middle; VSNodeRef *after; VSMap *args = vsapi->createMap(); VSMap *ret; const char *error; vsapi->propSetNode(args, "clip", before, paReplace); vsapi->freeNode(before); ret = vsapi->invoke(corePlugin, "Cache", args); middle = vsapi->propGetNode(ret, "clip", 0, NULL); vsapi->freeMap(ret); vsapi->propSetNode(args, "clip", middle, paReplace); vsapi->propSetData(args, "d2v", vsapi->propGetData(in, "input", 0, NULL), vsapi->propGetDataSize(in, "input", 0, NULL), paReplace); vsapi->freeNode(middle); ret = vsapi->invoke(d2vPlugin, "ApplyRFF", args); vsapi->freeMap(args); error = vsapi->getError(ret); if (error) { vsapi->setError(out, error); vsapi->freeMap(ret); return; } after = vsapi->propGetNode(ret, "clip", 0, NULL); vsapi->propSetNode(out, "clip", after, paReplace); vsapi->freeNode(after); vsapi->freeMap(ret); } }