Пример #1
0
static int callback_init_common(struct callback_data *data, const zimg_filter_graph *graph, vszimg_bool is_pack, const zimg_image_format *format, const VSFormat *vsformat,
                                VSCore *core, const VSAPI *vsapi, char *err_msg, size_t err_msg_size)
{
	zimg_image_buffer_u buf_initialized = { { ZIMG_API_VERSION } };
	unsigned count;
	unsigned mask;

	data->cb = NULL;
	data->frame_tmp = NULL;
	data->plane_buf = buf_initialized;
	data->line_buf = buf_initialized;
	data->height = format->height;

	if (vsformat->colorFamily != cmCompat)
		return 0;

	if (vsformat->id != pfCompatBGR32 && vsformat->id != pfCompatYUY2) {
		sprintf(err_msg, "unsupported compat format: %d (%s)", vsformat->id, vsformat->name);
		return 1;
	}

	if (is_pack && zimg_filter_graph_get_output_buffering(graph, &count)) {
		format_zimg_error(err_msg, err_msg_size);
		return 1;
	}
	if (!is_pack && zimg_filter_graph_get_input_buffering(graph, &count)) {
		format_zimg_error(err_msg, err_msg_size);
		return 1;
	}
	mask = zimg_select_buffer_mask(count);
	count = (mask == ZIMG_BUFFER_MAX) ? format->height : mask + 1;

	data->frame_tmp = vsapi->newVideoFrame(
		vsapi->registerFormat(cmYUV, stInteger, 8, vsformat->subSamplingW, vsformat->subSamplingH, core),
		format->width,
		count,
		NULL,
		core);
	import_frame_as_write_buffer(data->frame_tmp, &data->line_buf.m, mask, vsapi);

	return 0;
}
Пример #2
0
static struct vszimg_graph_data *_vszimg_get_graph_data(struct vszimg_data *data, const zimg_image_format *src_format, const zimg_image_format *dst_format,
                                                        char *err_msg, size_t err_msg_size)
{
	struct vszimg_graph_data *graph_data = NULL;
	struct vszimg_graph_data *ret = NULL;
	vszimg_bool mutex_locked = VSZIMG_FALSE;
	vszimg_bool allocate_new;

	if (vszimg_mutex_lock(&data->graph_mutex)) {
		sprintf(err_msg, "error locking mutex");
		goto fail;
	}
	mutex_locked = VSZIMG_TRUE;

	allocate_new = !data->graph_data ||
	               (!image_format_eq(&data->graph_data->src_format, src_format) ||
	                !image_format_eq(&data->graph_data->dst_format, dst_format));

	if (allocate_new) {
		if (!(graph_data = malloc(sizeof(*graph_data)))) {
			sprintf(err_msg, "error allocating vszimg_graph_data");
			goto fail;
		}
		graph_data->graph = NULL;
		graph_data->ref_count = 1;

		if (!(graph_data->graph = zimg_filter_graph_build(src_format, dst_format, &data->params))) {
			format_zimg_error(err_msg, err_msg_size);
			goto fail;
		}

		graph_data->src_format = *src_format;
		graph_data->dst_format = *dst_format;

		_vszimg_release_graph_data_unsafe(data->graph_data);

		++graph_data->ref_count;
		data->graph_data = graph_data;

		ret = graph_data;
		graph_data = NULL;
	} else {
		++data->graph_data->ref_count;
		ret = data->graph_data;
	}
fail:
	if (mutex_locked)
		vszimg_mutex_unlock(&data->graph_mutex);

	_vszimg_release_graph_data(data, graph_data);
	return ret;
}
Пример #3
0
static const VSFrameRef *_vszimg_get_frame(struct vszimg_data *data, const VSFrameRef *src_frame, VSCore *core, const VSAPI *vsapi, char *err_msg, size_t err_msg_size)
{
	struct vszimg_graph_data *graph_data = NULL;
	VSFrameRef *dst_frame = NULL;
	VSFrameRef *ret = NULL;
	void *tmp = NULL;

	struct callback_data unpack_cb_data = { 0 };
	struct callback_data pack_cb_data = { 0 };

	zimg_image_format src_format;
	zimg_image_format dst_format;
	const VSFormat *src_vsformat;
	const VSFormat *dst_vsformat;

	const VSMap *src_props;
	VSMap *dst_props;
	size_t tmp_size;

	zimg_image_format_default(&src_format, ZIMG_API_VERSION);
	zimg_image_format_default(&dst_format, ZIMG_API_VERSION);

	src_props = vsapi->getFramePropsRO(src_frame);
	src_vsformat = vsapi->getFrameFormat(src_frame);
	dst_vsformat = data->vi.format ? data->vi.format : src_vsformat;

	src_format.width = vsapi->getFrameWidth(src_frame, 0);
	src_format.height = vsapi->getFrameHeight(src_frame, 0);

	dst_format.width = data->vi.width ? (unsigned)data->vi.width : src_format.width;
	dst_format.height = data->vi.height ? (unsigned)data->vi.height : src_format.height;

	if (translate_vsformat(src_vsformat, &src_format, err_msg))
		goto fail;
	if (translate_vsformat(dst_vsformat, &dst_format, err_msg))
		goto fail;

	_vszimg_set_src_colorspace(data, &src_format);

	if (import_frame_props(vsapi, src_props, &src_format, err_msg))
		goto fail;

	_vszimg_set_dst_colorspace(data, &src_format, &dst_format);

	if (!(graph_data = _vszimg_get_graph_data(data, &src_format, &dst_format, err_msg, err_msg_size)))
		goto fail;

	dst_frame = vsapi->newVideoFrame(dst_vsformat, dst_format.width, dst_format.height, src_frame, core);
	dst_props = vsapi->getFramePropsRW(dst_frame);

	if (callback_init_unpack(&unpack_cb_data, graph_data->graph, src_frame, &src_format, src_vsformat, core, vsapi, err_msg, err_msg_size))
		goto fail;
	if (callback_init_pack(&pack_cb_data, graph_data->graph, dst_frame, &dst_format, dst_vsformat, core, vsapi, err_msg, err_msg_size))
		goto fail;

	if (zimg_filter_graph_get_tmp_size(graph_data->graph, &tmp_size)) {
		format_zimg_error(err_msg, err_msg_size);
		goto fail;
	}

	VS_ALIGNED_MALLOC(&tmp, tmp_size, 64);
	if (!tmp) {
		sprintf(err_msg, "error allocating temporary buffer");
		goto fail;
	}

	if (zimg_filter_graph_process(graph_data->graph,
	                              &unpack_cb_data.line_buf.c,
	                              &pack_cb_data.line_buf.m,
	                              tmp,
	                              unpack_cb_data.cb,
	                              &unpack_cb_data,
	                              pack_cb_data.cb,
	                              &pack_cb_data))
	{
		format_zimg_error(err_msg, err_msg_size);
		goto fail;
	}

	propagate_sar(vsapi, src_props, dst_props, &src_format, &dst_format);
	export_frame_props(vsapi, &dst_format, dst_props);

	ret = dst_frame;
	dst_frame = NULL;
fail:
	_vszimg_release_graph_data(data, graph_data);
	vsapi->freeFrame(dst_frame);
	VS_ALIGNED_FREE(tmp);
	callback_destroy(&unpack_cb_data, vsapi);
	callback_destroy(&pack_cb_data, vsapi);
	return ret;
}
Пример #4
0
static const VSFrameRef * VS_CC vszimg_get_frame(int n, int activationReason, void **instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
	struct vszimg_data *data = *instanceData;
	struct vszimg_graph_data *graph_data = NULL;
	const VSFrameRef *src_frame = NULL;
	VSFrameRef *dst_frame = NULL;
	VSFrameRef *ret = NULL;
	void *tmp = NULL;
	char err_msg[1024];
	int err_flag = 1;

	if (activationReason == arInitial) {
		vsapi->requestFrameFilter(n, data->node, frameCtx);
	} else if (activationReason == arAllFramesReady) {
		zimg_image_buffer_const src_buf = { ZIMG_API_VERSION };
		zimg_image_buffer dst_buf = { { ZIMG_API_VERSION } };
		zimg_image_format src_format;
		zimg_image_format dst_format;
		const VSFormat *src_vsformat;
		const VSFormat *dst_vsformat;
		const VSMap *src_props;
		VSMap *dst_props;
		size_t tmp_size;
		int p;

		zimg2_image_format_default(&src_format, ZIMG_API_VERSION);
		zimg2_image_format_default(&dst_format, ZIMG_API_VERSION);

		src_frame = vsapi->getFrameFilter(n, data->node, frameCtx);
		src_props = vsapi->getFramePropsRO(src_frame);

		src_vsformat = vsapi->getFrameFormat(src_frame);
		dst_vsformat = data->vi.format ? data->vi.format : src_vsformat;

		src_format.width = vsapi->getFrameWidth(src_frame, 0);
		src_format.height = vsapi->getFrameHeight(src_frame, 0);

		dst_format.width = data->vi.width ? (unsigned)data->vi.width : src_format.width;
		dst_format.height = data->vi.height ? (unsigned)data->vi.height : src_format.height;

		if (translate_vsformat(src_vsformat, &src_format, err_msg))
			goto fail;
		if (translate_vsformat(dst_vsformat, &dst_format, err_msg))
			goto fail;

		_vszimg_set_src_colorspace(data, &src_format);

		if (import_frame_props(vsapi, src_props, &src_format, err_msg))
			goto fail;

		_vszimg_set_dst_colorspace(data, &src_format, &dst_format);

		if (!(graph_data = _vszimg_get_graph_data(data, &src_format, &dst_format, err_msg, sizeof(err_msg))))
			goto fail;

		dst_frame = vsapi->newVideoFrame(dst_vsformat, dst_format.width, dst_format.height, src_frame, core);
		dst_props = vsapi->getFramePropsRW(dst_frame);

		for (p = 0; p < src_vsformat->numPlanes; ++p) {
			src_buf.data[p] = vsapi->getReadPtr(src_frame, p);
			src_buf.stride[p] = vsapi->getStride(src_frame, p);
			src_buf.mask[p] = -1;
		}
		for (p = 0; p < dst_vsformat->numPlanes; ++p) {
			dst_buf.m.data[p] = vsapi->getWritePtr(dst_frame, p);
			dst_buf.m.stride[p] = vsapi->getStride(dst_frame, p);
			dst_buf.m.mask[p] = -1;
		}

		if (zimg2_filter_graph_get_tmp_size(graph_data->graph, &tmp_size)) {
			format_zimg_error(err_msg, sizeof(err_msg));
			goto fail;
		}

		VS_ALIGNED_MALLOC(&tmp, tmp_size, 64);
		if (!tmp) {
			sprintf(err_msg, "error allocating temporary buffer");
			goto fail;
		}

		if (zimg2_filter_graph_process(graph_data->graph, &src_buf, &dst_buf, tmp, NULL, NULL, NULL, NULL)) {
			format_zimg_error(err_msg, sizeof(err_msg));
			goto fail;
		}

		propagate_sar(vsapi, src_props, dst_props, &src_format, &dst_format);
		export_frame_props(vsapi, &dst_format, dst_props);

		ret = dst_frame;
		dst_frame = NULL;
	}

	err_flag = 0;
fail:
	if (err_flag)
		vsapi->setFilterError(err_msg, frameCtx);

	_vszimg_release_graph_data(data, graph_data);
	vsapi->freeFrame(src_frame);
	vsapi->freeFrame(dst_frame);
	return ret;
}