コード例 #1
0
void VS_CC rffCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    rffData *data;
    string msg;
    int i;

    /* Allocate our private data. */
    data = new(nothrow) rffData;
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    /* Parse the D2V to get flags. */
    data->d2v = d2vparse((char *) vsapi->propGetData(in, "d2v", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        delete data;
        return;
    }

    /* Get our frame info and copy it, so we can modify it after. */
    data->node = vsapi->propGetNode(in, "clip", 0, 0);
    data->vi   = *vsapi->getVideoInfo(data->node);

    /*
     * Parse all the RFF flags to figure out which fields go
     * with which frames, and out total number of frames after
     * apply the RFF flags.
     */
    for(i = 0; i < data->vi.numFrames; i++) {
        frame f  = data->d2v->frames[i];
        bool rff = !!(data->d2v->gops[f.gop].flags[f.offset] & FRAME_FLAG_RFF);
        bool tff = !!(data->d2v->gops[f.gop].flags[f.offset] & FRAME_FLAG_TFF);

        int progressive_sequence = !!(data->d2v->gops[f.gop].info & GOP_FLAG_PROGRESSIVE_SEQUENCE);

        if (progressive_sequence) {
            /*
             * We repeat whole frames instead of fields, to turn one
             * coded progressive frame into either two or three
             * identical progressive frames.
             */
            rffField field;
            field.frame = i;
            field.type = Progressive;

            data->fields.push_back(field);
            data->fields.push_back(field);

            if (rff) {
                data->fields.push_back(field);
                data->fields.push_back(field);

                if (tff) {
                    data->fields.push_back(field);
                    data->fields.push_back(field);
                }
            }
        } else {
            /* Sequence is not progressive. Repeat fields. */

            rffField first_field, second_field;
            first_field.frame = second_field.frame = i;
            first_field.type = tff ? Top : Bottom;
            second_field.type = tff ? Bottom : Top;

            data->fields.push_back(first_field);
            data->fields.push_back(second_field);

            if (rff)
                data->fields.push_back(first_field);
        }
    }

    data->vi.numFrames = (int)data->fields.size() / 2;

    vsapi->createFilter(in, out, "applyrff", rffInit, rffGetFrame, rffFree, fmParallel, 0, data, core);
}
コード例 #2
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);
    }
}
コード例 #3
0
void VS_CC rffCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    rffData *data;
    fieldFrame ff = { -1, -1 };
    string msg;
    int i;

    /* Allocate our private data. */
    data = new(nothrow) rffData;
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    /* Parse the D2V to get flags. */
    data->d2v = d2vparse((char *) vsapi->propGetData(in, "d2v", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        delete data;
        return;
    }

    /* Get our frame info and copy it, so we can modify it after. */
    data->node = vsapi->propGetNode(in, "clip", 0, 0);
    data->vi   = *vsapi->getVideoInfo(data->node);

    /*
     * Parse all the RFF flags to figure out which fields go
     * with which frames, and out total number of frames after
     * apply the RFF flags.
     */
    data->frames.push_back(ff);
    for(i = 0; i < data->vi.numFrames; i++) {
        frame f  = data->d2v->frames[i];
        bool rff = !!(data->d2v->gops[f.gop].flags[f.offset] & FRAME_FLAG_RFF);
        bool tff = !!(data->d2v->gops[f.gop].flags[f.offset] & FRAME_FLAG_TFF);
        int pos  = data->frames.size() - 1;

        int progressive_sequence = !!(data->d2v->gops[f.gop].info & GOP_FLAG_PROGRESSIVE_SEQUENCE);

        if (progressive_sequence) {
            /*
             * We repeat whole frames instead of fields, to turn one
             * coded progressive frame into either two or three
             * identical progressive frames.
             */
            ff.top = ff.bottom = i;

            if (pos == 0)
                data->frames[0] = ff;
            else
                data->frames.push_back(ff);

            if (rff) {
                data->frames.push_back(ff);

                if (tff)
                    data->frames.push_back(ff);
            }
        } else {
            /* Sequence is not progressive. Repeat fields. */

            int *pos_first, *pos_second, *ff_first, *ff_second;
            if (tff) {
                pos_first = &data->frames[pos].top;
                pos_second = &data->frames[pos].bottom;
                ff_first = &ff.top;
                ff_second = &ff.bottom;
            } else {
                pos_first = &data->frames[pos].bottom;
                pos_second = &data->frames[pos].top;
                ff_first = &ff.bottom;
                ff_second = &ff.top;
            }

            if (rff) {
                if (*pos_first == -1) {
                    *pos_first  = i;
                    *pos_second = i;

                    *ff_first  = i;
                    *ff_second = -1;
                } else if (*pos_second == -1) {
                    *pos_second = i;

                    *ff_first  = i;
                    *ff_second = i;
                } else {
                    *ff_first  = i;
                    *ff_second = i;

                    data->frames.push_back(ff);

                    *ff_second = -1;
                }
            } else {
                if (*pos_first == -1) {
                    *pos_first  = i;
                    *pos_second = i;

                    *ff_first  = -1;
                    *ff_second = -1;
                } else if (*pos_second == -1) {
                    *pos_second = i;

                    *ff_first  = i;
                    *ff_second = -1;
                } else {
                    *ff_first  = i;
                    *ff_second = i;
                }
            }
            data->frames.push_back(ff);
        }
    }

    data->vi.numFrames = (int)data->frames.size() - 1;

    vsapi->createFilter(in, out, "applyrff", rffInit, rffGetFrame, rffFree, fmParallel, 0, data, core);
}