예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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);
    }
}