static void format_zimg_error(char *err_msg, size_t n) { zimg_error_code_e err_code; int offset; err_code = zimg_get_last_error(NULL, 0); offset = sprintf(err_msg, "zimg %d: ", err_code); zimg_get_last_error(err_msg + offset, n - offset); }
static void VS_CC vs_depth_create(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) { vs_depth_data *data = 0; zimg_depth_params params; zimg_filter *filter = 0; zimg_filter *filter_uv = 0; char fail_str[1024]; int err; VSNodeRef *node = 0; const VSVideoInfo *node_vi; const VSFormat *node_fmt; VSVideoInfo vi; const char *dither_str; int sample_type; int depth; node = vsapi->propGetNode(in, "clip", 0, 0); node_vi = vsapi->getVideoInfo(node); node_fmt = node_vi->format; if (!isConstantFormat(node_vi)) { strcpy(fail_str, "clip must have a defined format"); goto fail; } sample_type = (int)propGetIntDefault(vsapi, in, "sample", 0, node_fmt->sampleType); depth = (int)propGetIntDefault(vsapi, in, "depth", 0, node_fmt->bitsPerSample); if (sample_type != stInteger && sample_type != stFloat) { strcpy(fail_str, "invalid sample type: must be stInteger or stFloat"); goto fail; } if (sample_type == stFloat && depth != 16 && depth != 32) { strcpy(fail_str, "invalid depth: must be 16 or 32 for stFloat"); goto fail; } if (sample_type == stInteger && (depth <= 0 || depth > 16)) { strcpy(fail_str, "invalid depth: must be between 1-16 for stInteger"); goto fail; } vi = *node_vi; vi.format = vsapi->registerFormat(node_fmt->colorFamily, sample_type, depth < 8 ? 8 : depth, node_fmt->subSamplingW, node_fmt->subSamplingH, core); if (!vi.format) { strcpy(fail_str, "unable to register output VSFormat"); goto fail; } zimg2_depth_params_default(¶ms, ZIMG_API_VERSION); params.width = node_vi->width; params.height = node_vi->height; dither_str = vsapi->propGetData(in, "dither", 0, &err); if (!err) params.dither_type = translate_dither(dither_str); params.chroma = 0; params.pixel_in = translate_pixel(node_fmt); params.depth_in = node_fmt->bitsPerSample; params.range_in = (int)propGetIntDefault(vsapi, in, "range_in", 0, node_fmt->colorFamily == cmRGB ? ZIMG_RANGE_FULL : ZIMG_RANGE_LIMITED); params.pixel_out = translate_pixel(vi.format); params.depth_out = depth; params.range_out = (int)propGetIntDefault(vsapi, in, "range_out", 0, params.range_in); if (!(filter = zimg2_depth_create(¶ms))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } if (node_fmt->colorFamily == cmYUV || node_fmt->colorFamily == cmYCoCg) { params.width = params.width >> node_fmt->subSamplingW; params.height = params.height >> node_fmt->subSamplingH; params.chroma = 1; if (!(filter_uv = zimg2_depth_create(¶ms))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } }
static void VS_CC vs_colorspace_create(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) { vs_colorspace_data *data = 0; zimg_colorspace_params params; zimg_filter *filter = 0; char fail_str[1024]; VSNodeRef *node = 0; const VSVideoInfo *node_vi; const VSFormat *node_fmt; VSVideoInfo vi; node = vsapi->propGetNode(in, "clip", 0, 0); node_vi = vsapi->getVideoInfo(node); node_fmt = node_vi->format; if (!isConstantFormat(node_vi)) { strcpy(fail_str, "clip must have a defined format"); goto fail; } if (node_fmt->numPlanes < 3 || node_fmt->subSamplingW || node_fmt->subSamplingH) { strcpy(fail_str, "colorspace conversion can only be performed on 4:4:4 clips"); goto fail; } zimg2_colorspace_params_default(¶ms, ZIMG_API_VERSION); params.width = node_vi->width; params.height = node_vi->height; params.matrix_in = (int)vsapi->propGetInt(in, "matrix_in", 0, 0); params.transfer_in = (int)vsapi->propGetInt(in, "transfer_in", 0, 0); params.primaries_in = (int)vsapi->propGetInt(in, "primaries_in", 0, 0); params.matrix_out = (int)propGetIntDefault(vsapi, in, "matrix_out", 0, params.matrix_in); params.transfer_out = (int)propGetIntDefault(vsapi, in, "transfer_out", 0, params.transfer_in); params.primaries_out = (int)propGetIntDefault(vsapi, in, "primaries_out", 0, params.primaries_in); params.pixel_type = translate_pixel(node_fmt); params.depth = node_fmt->bitsPerSample; params.range_in = (int)!!propGetIntDefault(vsapi, in, "fullrange_in", 0, params.matrix_in == ZIMG_MATRIX_RGB ? ZIMG_RANGE_FULL : ZIMG_RANGE_LIMITED); params.range_out = (int)!!propGetIntDefault(vsapi, in, "fullrange_out", 0, params.matrix_out == ZIMG_MATRIX_RGB ? ZIMG_RANGE_FULL : ZIMG_RANGE_LIMITED); vi = *node_vi; vi.format = vsapi->registerFormat(params.matrix_out == ZIMG_MATRIX_RGB ? cmRGB : cmYUV, node_fmt->sampleType, node_fmt->bitsPerSample, node_fmt->subSamplingW, node_fmt->subSamplingH, core); if (!(filter = zimg2_colorspace_create(¶ms))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } if (!(data = malloc(sizeof(*data)))) { strcpy(fail_str, "error allocating vs_colorspace_data"); goto fail; } data->filter = filter; data->node = node; data->vi = vi; data->matrix_out = params.matrix_out; data->transfer_out = params.transfer_out; data->primaries_out = params.primaries_out; vsapi->createFilter(in, out, "colorspace", vs_colorspace_init, vs_colorspace_get_frame, vs_colorspace_free, fmParallel, 0, data, core); return; fail: vsapi->setError(out, fail_str); vsapi->freeNode(node); zimg2_filter_free(filter); free(data); }
static const VSFrameRef * VS_CC vs_depth_get_frame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) { vs_depth_data *data = *instanceData; VSFrameRef *ret = 0; char fail_str[1024]; int err = 0; if (activationReason == arInitial) { vsapi->requestFrameFilter(n, data->node, frameCtx); } else { const VSFrameRef *src_frame = 0; VSFrameRef *dst_frame = 0; void *tmp = 0; const void *src_plane[3] = { 0 }; void *dst_plane[3] = { 0 }; ptrdiff_t src_stride[3] = { 0 }; ptrdiff_t dst_stride[3] = { 0 }; int width; int height; unsigned num_planes; size_t tmp_size; size_t tmp_size_uv; VSMap *props; unsigned p; width = data->vi.width; height = data->vi.height; num_planes = data->vi.format->numPlanes; src_frame = vsapi->getFrameFilter(n, data->node, frameCtx); dst_frame = vsapi->newVideoFrame(data->vi.format, width, height, src_frame, core); if ((err = zimg2_plane_filter_get_tmp_size(data->filter, &tmp_size))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } if (data->filter_uv) { if ((err = zimg2_plane_filter_get_tmp_size(data->filter_uv, &tmp_size_uv))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } } else { tmp_size_uv = 0; } VS_ALIGNED_MALLOC(&tmp, VSMAX(tmp_size, tmp_size_uv), 32); if (!tmp) { strcpy(fail_str, "error allocating temporary buffer"); err = 1; goto fail; } for (p = 0; p < num_planes; ++p) { const zimg_filter *filter; if ((p == 1 || p == 2) && data->filter_uv) filter = data->filter_uv; else filter = data->filter; src_plane[0] = vsapi->getReadPtr(src_frame, p); src_stride[0] = vsapi->getStride(src_frame, p); dst_plane[0] = vsapi->getWritePtr(dst_frame, p); dst_stride[0] = vsapi->getStride(dst_frame, p); if ((err = zimg2_plane_filter_process(filter, tmp, src_plane, dst_plane, src_stride, dst_stride))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } } props = vsapi->getFramePropsRW(dst_frame); vsapi->propSetInt(props, "_ColorRange", !data->fullrange, paReplace); ret = dst_frame; dst_frame = 0; fail: vsapi->freeFrame(src_frame); vsapi->freeFrame(dst_frame); VS_ALIGNED_FREE(tmp); } if (err) vsapi->setFilterError(fail_str, frameCtx); return ret; }
static const VSFrameRef * VS_CC vs_colorspace_get_frame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) { vs_colorspace_data *data = *instanceData; VSFrameRef *ret = 0; char fail_str[1024]; int err = 0; if (activationReason == arInitial) { vsapi->requestFrameFilter(n, data->node, frameCtx); } else if (activationReason == arAllFramesReady) { const VSFrameRef *src_frame = 0; VSFrameRef *dst_frame = 0; void *tmp = 0; const void *src_plane[3]; void *dst_plane[3]; ptrdiff_t src_stride[3]; ptrdiff_t dst_stride[3]; int width; int height; size_t tmp_size; VSMap *props; unsigned p; width = data->vi.width; height = data->vi.height; src_frame = vsapi->getFrameFilter(n, data->node, frameCtx); dst_frame = vsapi->newVideoFrame(data->vi.format, width, height, src_frame, core); if ((err = zimg2_plane_filter_get_tmp_size(data->filter, &tmp_size))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } VS_ALIGNED_MALLOC(&tmp, tmp_size, 32); if (!tmp) { strcpy(fail_str, "error allocating temporary buffer"); err = 1; goto fail; } for (p = 0; p < 3; ++p) { src_plane[p] = vsapi->getReadPtr(src_frame, p); src_stride[p] = vsapi->getStride(src_frame, p); dst_plane[p] = vsapi->getWritePtr(dst_frame, p); dst_stride[p] = vsapi->getStride(dst_frame, p); } if ((err = zimg2_plane_filter_process(data->filter, tmp, src_plane, dst_plane, src_stride, dst_stride))) { zimg_get_last_error(fail_str, sizeof(fail_str)); goto fail; } props = vsapi->getFramePropsRW(dst_frame); vsapi->propSetInt(props, "_Matrix", data->matrix_out, paReplace); vsapi->propSetInt(props, "_Transfer", data->transfer_out, paReplace); vsapi->propSetInt(props, "_Primaries", data->primaries_out, paReplace); ret = dst_frame; dst_frame = 0; fail: vsapi->freeFrame(src_frame); vsapi->freeFrame(dst_frame); VS_ALIGNED_FREE(tmp); } if (err) vsapi->setFilterError(fail_str, frameCtx); return ret; }