コード例 #1
0
static void VS_CC spliceCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    SpliceData d;
    SpliceData *data;
    VSNodeRef *cref;
    int mismatch;
    int i;
    int err;
    int compat = 0;

    d.numclips = vsapi->propNumElements(in, "clips");
    mismatch = !!vsapi->propGetInt(in, "mismatch", 0, &err);

    if (d.numclips == 1) { // passthrough for the special case with only one clip
        cref = vsapi->propGetNode(in, "clips", 0, 0);
        vsapi->propSetNode(out, "clip", cref, 0);
        vsapi->freeNode(cref);
    } else {
        d.node = malloc(sizeof(d.node[0]) * d.numclips);

        for (i = 0; i < d.numclips; i++) {
            d.node[i] = vsapi->propGetNode(in, "clips", i, 0);

            if (isCompatFormat(vsapi->getVideoInfo(d.node[i])))
                compat = 1;
        }

        if (findCommonVi(d.node, d.numclips, &d.vi, 0, vsapi) && (!mismatch || compat) && !isSameFormat(&d.vi, vsapi->getVideoInfo(d.node[0]))) {
            for (i = 0; i < d.numclips; i++)
                vsapi->freeNode(d.node[i]);

            free(d.node);
            RETERROR("Splice: clip property mismatch");
        }

        d.numframes = malloc(sizeof(d.numframes[0]) * d.numclips);
        d.vi.numFrames = 0;

        for (i = 0; i < d.numclips; i++) {
            d.numframes[i] = (vsapi->getVideoInfo(d.node[i]))->numFrames;
            d.vi.numFrames += d.numframes[i];

            if (d.numframes[i] == 0 && i != d.numclips - 1) {
                for (i = 0; i < d.numclips; i++)
                    vsapi->freeNode(d.node[i]);

                free(d.node);
                free(d.numframes);
                RETERROR("Splice: unknown length clips can only be last in a splice operation");
            }
        }

        if (d.numframes[d.numclips - 1] == 0)
            d.vi.numFrames = 0;

        data = malloc(sizeof(d));
        *data = d;

        vsapi->createFilter(in, out, "Splice", spliceInit, spliceGetframe, spliceFree, fmParallel, nfNoCache, data, core);
    }
}
コード例 #2
0
static void VS_CC interleaveCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    InterleaveData d;
    InterleaveData *data;
    VSNodeRef *cref;
    int i;
    int err;
    int compat;

    int mismatch = !!vsapi->propGetInt(in, "mismatch", 0, &err);
    int extend = !!vsapi->propGetInt(in, "extend", 0, &err);
    d.numclips = vsapi->propNumElements(in, "clips");

    if (d.numclips == 1) { // passthrough for the special case with only one clip
        cref = vsapi->propGetNode(in, "clips", 0, 0);
        vsapi->propSetNode(out, "clip", cref, 0);
        vsapi->freeNode(cref);
    } else {
        d.node = malloc(sizeof(d.node[0]) * d.numclips);
        compat = 0;

        for (i = 0; i < d.numclips; i++) {
            d.node[i] = vsapi->propGetNode(in, "clips", i, 0);

            if (isCompatFormat(vsapi->getVideoInfo(d.node[i])))
                compat = 1;
        }

        if (findCommonVi(d.node, d.numclips, &d.vi, 1, vsapi) && (!mismatch || compat)) {
            for (i = 0; i < d.numclips; i++)
                vsapi->freeNode(d.node[i]);

            free(d.node);
            RETERROR("Interleave: clip property mismatch");
        }

        if (extend) {
            d.vi.numFrames *= d.numclips;
        } else if (d.vi.numFrames) {
            // this is exactly how avisynth does it
            d.vi.numFrames = (vsapi->getVideoInfo(d.node[0])->numFrames - 1) * d.numclips + 1;
            for (i = 1; i < d.numclips; i++)
                d.vi.numFrames = VSMAX(d.vi.numFrames, (vsapi->getVideoInfo(d.node[i])->numFrames - 1) * d.numclips + i + 1);
        }
        d.vi.fpsNum *= d.numclips;

        data = malloc(sizeof(d));
        *data = d;

        vsapi->createFilter(in, out, "Interleave", interleaveInit, interleaveGetframe, interleaveFree, fmParallel, nfNoCache, data, core);
    }
}
コード例 #3
0
ファイル: textfilter.cpp プロジェクト: dubhater/vapoursynth
static void VS_CC textCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    TextData d;
    TextData *data;
    int err;

    d.node = vsapi->propGetNode(in, "clip", 0, &err);
    if (err) {
        // Can only happen for CoreInfo.
        VSMap *args = vsapi->createMap();
        VSPlugin *stdPlugin = vsapi->getPluginById("com.vapoursynth.std", core);
        VSMap *ret = vsapi->invoke(stdPlugin, "BlankClip", args);
        vsapi->freeMap(args);
        const char *error = vsapi->getError(ret);
        if (error) {
            std::string msg = "CoreInfo: No input clip was given and invoking BlankClip failed. The error message from BlankClip is:\n";
            msg += error;
            vsapi->setError(out, msg.c_str());
            vsapi->freeMap(ret);
            return;
        }
        d.node = vsapi->propGetNode(ret, "clip", 0, nullptr);
        vsapi->freeMap(ret);
    }
    d.vi = vsapi->getVideoInfo(d.node);

    if (isCompatFormat(d.vi)) {
        vsapi->setError(out, "Text: Compat formats not supported");
        vsapi->freeNode(d.node);
        return;
    }

    if (d.vi->format && ((d.vi->format->sampleType == stInteger && d.vi->format->bitsPerSample > 16) ||
        (d.vi->format->sampleType == stFloat && d.vi->format->bitsPerSample != 32))) {
            vsapi->setError(out, "Text: Only 8-16 bit integer and 32 bit float formats supported");
            vsapi->freeNode(d.node);
            return;
    }

    d.alignment = int64ToIntS(vsapi->propGetInt(in, "alignment", 0, &err));
    if (err) {
        d.alignment = 7; // top left
    }

    if (d.alignment < 1 || d.alignment > 9) {
        vsapi->setError(out, "Text: alignment must be between 1 and 9 (think numpad)");
        vsapi->freeNode(d.node);
        return;
    }

    d.filter = reinterpret_cast<intptr_t>(userData);

    switch (d.filter) {
    case FILTER_TEXT:
        d.text = vsapi->propGetData(in, "text", 0, nullptr);
        d.instanceName = "Text";
        break;
    case FILTER_CLIPINFO:
        d.instanceName = "ClipInfo";
        break;
    case FILTER_COREINFO:
        {
            d.instanceName = "CoreInfo";
            break;
        }
    case FILTER_FRAMENUM:
        d.instanceName = "FrameNum";
        break;
    case FILTER_FRAMEPROPS:
        int numProps = vsapi->propNumElements(in, "props");

        for (int i = 0; i < numProps; i++) {
            d.props.push_back(vsapi->propGetData(in, "props", i, nullptr));
        }

        d.instanceName = "FrameProps";
        break;
    }

    data = new TextData(d);

    vsapi->createFilter(in, out, d.instanceName.c_str(), textInit, textGetFrame, textFree, fmParallel, 0, data, core);
}
コード例 #4
0
ファイル: lutfilters.cpp プロジェクト: Cybuster/vapoursynth
static void VS_CC lut2Create(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    std::unique_ptr<Lut2Data> d(new Lut2Data(vsapi));

    d->node[0] = vsapi->propGetNode(in, "clipa", 0, 0);
    d->node[1] = vsapi->propGetNode(in, "clipb", 0, 0);
    d->vi[0] = vsapi->getVideoInfo(d->node[0]);
    d->vi[1] = vsapi->getVideoInfo(d->node[1]);

    if (!isConstantFormat(d->vi[0]) || !isConstantFormat(d->vi[1]))
        RETERROR("Lut2: only clips with constant format and dimensions supported");

    if (isCompatFormat(d->vi[0]) || isCompatFormat(d->vi[1]))
        RETERROR("Lut2: compat formats are not supported");

    if (d->vi[0]->format->sampleType != stInteger || d->vi[1]->format->sampleType != stInteger
        || (d->vi[0]->format->bitsPerSample + d->vi[1]->format->bitsPerSample) > 20
        || d->vi[0]->format->subSamplingH != d->vi[1]->format->subSamplingH
        || d->vi[0]->format->subSamplingW != d->vi[1]->format->subSamplingW
        || d->vi[0]->width != d->vi[1]->width || d->vi[0]->height != d->vi[1]->height)
        RETERROR("Lut2: only clips with integer samples, same dimensions, same subsampling and up to a total of 20 indexing bits supported");

    int n = d->vi[0]->format->numPlanes;
    int num_planes = vsapi->propNumElements(in, "planes");

    for (int i = 0; i < 3; i++)
        d->process[i] = (num_planes <= 0);

    for (int i = 0; i < num_planes; i++) {
        int o = int64ToIntS(vsapi->propGetInt(in, "planes", i, 0));

        if (o < 0 || o >= n)
            RETERROR("Lut2: plane index out of range");

        if (d->process[o])
            RETERROR("Lut2: plane specified twice");

        d->process[o] = true;
    }

    int err;
    VSFuncRef *func = vsapi->propGetFunc(in, "function", 0, &err);
    int lut_elem = vsapi->propNumElements(in, "lut");
	int lutf_elem = vsapi->propNumElements(in, "lutf");
	bool floatout = !!vsapi->propGetInt(in, "floatout", 0, &err);

    int num_set = (lut_elem >= 0) + (lutf_elem >= 0) + !!func;

	if (!num_set) {
		vsapi->freeFunc(func);
		RETERROR("Lut2: none of lut, lutf and function are set");
	}

	if (num_set > 1) {
		vsapi->freeFunc(func);
		RETERROR("Lut2: more than one of lut, lutf and function are set");
	}

	if (lut_elem >= 0 && floatout) {
		vsapi->freeFunc(func);
		RETERROR("Lut2: lut set but float output specified");
	}

	if (lutf_elem >= 0 && !floatout) {
		vsapi->freeFunc(func);
		RETERROR("Lut2: lutf set but float output not specified");
	}

    n = 1 << (d->vi[0]->format->bitsPerSample + d->vi[1]->format->bitsPerSample);

	int lut_length = std::max(lut_elem, lutf_elem);

	if (lut_length >= 0 && lut_length != n) {
		vsapi->freeFunc(func);
		RETERROR(("Lut2: bad lut length. Expected " + std::to_string(n) + " elements, got " + std::to_string(lut_length) + " instead").c_str());
	}

    int bitsout = int64ToIntS(vsapi->propGetInt(in, "bits", 0, &err));
    if (err)
        bitsout = floatout ? sizeof(float) * 8 : d->vi[0]->format->bitsPerSample;
	if ((floatout && bitsout != 32) || (!floatout && (bitsout < 8 || bitsout > 16))) {
		vsapi->freeFunc(func);
		RETERROR("Lut2: only 8-16 bit integer and 32 bit float output supported");
	}

    d->vi_out = *d->vi[0];
    d->vi_out.format = vsapi->registerFormat(d->vi[0]->format->colorFamily, floatout ? stFloat : stInteger, bitsout, d->vi[0]->format->subSamplingW, d->vi[0]->format->subSamplingH, core);


    if (d->vi[0]->format->bytesPerSample == 1) {
        if (d->vi[1]->format->bytesPerSample == 1) {
            if (d->vi_out.format->bytesPerSample == 1 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint8_t, uint8_t, uint8_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bytesPerSample == 2 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint8_t, uint8_t, uint16_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bitsPerSample == 32 && d->vi_out.format->sampleType == stFloat)
                lut2CreateHelper<uint8_t, uint8_t, float>(in, out, func, d, core, vsapi);
        } else if (d->vi[1]->format->bytesPerSample == 2) {
            if (d->vi_out.format->bytesPerSample == 1 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint8_t, uint16_t, uint8_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bytesPerSample == 2 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint8_t, uint16_t, uint16_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bitsPerSample == 32 && d->vi_out.format->sampleType == stFloat)
                lut2CreateHelper<uint8_t, uint16_t, float>(in, out, func, d, core, vsapi);
        }
    } else if (d->vi[0]->format->bytesPerSample == 2) {
        if (d->vi[1]->format->bytesPerSample == 1) {
            if (d->vi_out.format->bytesPerSample == 1 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint16_t, uint8_t, uint8_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bytesPerSample == 2 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint16_t, uint8_t, uint16_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bitsPerSample == 32 && d->vi_out.format->sampleType == stFloat)
                lut2CreateHelper<uint16_t, uint8_t, float>(in, out, func, d, core, vsapi);
        } else if (d->vi[1]->format->bytesPerSample == 2) {
            if (d->vi_out.format->bytesPerSample == 1 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint16_t, uint16_t, uint8_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bytesPerSample == 2 && d->vi_out.format->sampleType == stInteger)
                lut2CreateHelper<uint16_t, uint16_t, uint16_t>(in, out, func, d, core, vsapi);
            else if (d->vi_out.format->bitsPerSample == 32 && d->vi_out.format->sampleType == stFloat)
                lut2CreateHelper<uint16_t, uint16_t, float>(in, out, func, d, core, vsapi);
        }
    }
}
コード例 #5
0
ファイル: textfilter.cpp プロジェクト: handaimaoh/vapoursynth
static void VS_CC textCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    TextData d;
    TextData *data;
    int err;

    d.node = vsapi->propGetNode(in, "clip", 0, &err);
    if (err) {
        // Can only happen for CoreInfo.
        VSMap *args = vsapi->createMap();
        VSPlugin *stdPlugin = vsapi->getPluginById("com.vapoursynth.std", core);
        VSMap *ret = vsapi->invoke(stdPlugin, "BlankClip", args);
        vsapi->freeMap(args);
        const char *error = vsapi->getError(ret);
        if (error) {
            std::string msg = "CoreInfo: No input clip was given and invoking BlankClip failed. The error message from BlankClip is:\n";
            msg.append(error);
            vsapi->setError(out, msg.c_str());
            vsapi->freeMap(ret);
            return;
        }
        d.node = vsapi->propGetNode(ret, "clip", 0, 0);
        vsapi->freeMap(ret);
    }
    d.vi = vsapi->getVideoInfo(d.node);

    if (isCompatFormat(d.vi)) {
        vsapi->setError(out, "Text: Compat formats not supported");
        vsapi->freeNode(d.node);
        return;
    }

    if (d.vi->format && ((d.vi->format->sampleType == stInteger && d.vi->format->bitsPerSample > 16) ||
        (d.vi->format->sampleType == stFloat && d.vi->format->bitsPerSample != 32))) {
            vsapi->setError(out, "Text: Only 8-16 bit integer and 32 bit float formats supported");
            vsapi->freeNode(d.node);
            return;
    }

    d.alignment = int64ToIntS(vsapi->propGetInt(in, "alignment", 0, &err));
    if (err) {
        d.alignment = 7; // top left
    }

    if (d.alignment < 1 || d.alignment > 9) {
        vsapi->setError(out, "Text: alignment must be between 1 and 9 (think numpad)");
        vsapi->freeNode(d.node);
        return;
    }

    d.filter = (intptr_t)userData;

    switch (d.filter) {
    case FILTER_TEXT:
        d.text = vsapi->propGetData(in, "text", 0, 0);

        d.instanceName = "Text";
        break;
    case FILTER_CLIPINFO:
        d.text.append("Clip info:\n");

        if (d.vi->width) {
            d.text.append("Width: ").append(std::to_string(d.vi->width)).append(" px\n");
            d.text.append("Height: ").append(std::to_string(d.vi->height)).append(" px\n");
        } else {
            d.text.append("Width: may vary\n");
            d.text.append("Height: may vary\n");
        }

        if (d.vi->numFrames) {
            d.text.append("Length: ").append(std::to_string(d.vi->numFrames)).append(" frames\n");
        } else {
            d.text.append("Length: unknown\n");
        }

        if (d.vi->format) {
            const VSFormat *fi = d.vi->format;
            const char *family;
            switch (fi->colorFamily) {
            case cmGray:
                family = "Gray";
                break;
            case cmRGB:
                family = "RGB";
                break;
            case cmYUV:
                family = "YUV";
                break;
            case cmYCoCg:
                family = "YCoCg";
                break;
            case cmCompat:
                family = "Compat";
                break;
            default:
                family = "impossible";
                break;
            }

            const char *type;
            switch (fi->sampleType) {
            case stInteger:
                type = "integer";
                break;
            case stFloat:
                type = "float";
                break;
            default:
                type = "impossible";
                break;
            }

            d.text.append("Format name: ").append(fi->name).append("\n");
            d.text.append("Format id: ").append(std::to_string(fi->id)).append("\n");
            d.text.append("Color family: ").append(family).append("\n");
            d.text.append("Sample type: ").append(type).append("\n");
            d.text.append("Bits per sample: ").append(std::to_string(fi->bitsPerSample)).append("\n");
            d.text.append("Bytes per sample: ").append(std::to_string(fi->bytesPerSample)).append("\n");
            d.text.append("Horizontal subsampling: ").append(std::to_string(fi->subSamplingW)).append("\n");
            d.text.append("Vertical subsampling: ").append(std::to_string(fi->subSamplingH)).append("\n");
            d.text.append("Number of planes: ").append(std::to_string(fi->numPlanes)).append("\n");
        } else {
            d.text.append("Format: may vary").append("\n");
        }

        d.text.append("FpsNum: ").append(std::to_string(d.vi->fpsNum)).append("\n");
        d.text.append("FpsDen: ").append(std::to_string(d.vi->fpsDen));

        d.instanceName = "ClipInfo";
        break;
    case FILTER_COREINFO:
        {
            d.instanceName = "CoreInfo";
            break;
        }
    case FILTER_FRAMENUM:
        d.instanceName = "FrameNum";
        break;
    case FILTER_FRAMEPROPS:
        int numProps = vsapi->propNumElements(in, "props");

        for (int i = 0; i < numProps; i++) {
            d.props.push_back(vsapi->propGetData(in, "props", i, 0));
        }

        d.instanceName = "FrameProps";
        break;
    }

    data = new TextData();
    *data = d;

    vsapi->createFilter(in, out, d.instanceName.c_str(), textInit, textGetFrame, textFree, fmParallel, 0, data, core);
}