void tryGraph() {
		if (type != Graph || !graph.initialize(option, in->format().size(), in->format().imgfmt())
				|| !graph.push(in->mpi()))
			return;
		while (auto out = graph.pull())
			push(out);
	}
	void split() {
		static const VideoFrame::Field field[] = {VideoFrame::Bottom, VideoFrame::Top};
		const bool topFirst = in->mpi()->fields & MP_IMGFIELD_TOP_FIRST;
		push(field[topFirst]);
		if (deint.doubler)
			push(field[!topFirst] | VideoFrame::Additional);
	}
Beispiel #3
0
bool VaApiPostProcessor::process(const VideoFrame &in, QLinkedList<VideoFrame> &queue) {
	if (!d->pipeline)
		return false;
	auto surface = VaApiSurfacePool::getSurface(in.mpi());
	if (!surface)
		return false;
	mp_image *out1 = nullptr, *out2 = nullptr;
	out1 = d->pipeline->render(in, d->setupDeint(in.mpi()->fields, true));
	if (d->deint.doubler && d->deint.method != DeintMethod::None)
		out2 = d->pipeline->render(in, d->setupDeint(in.mpi()->fields, false));
	if (out1)
		queue.push_back(VideoFrame(true, out1, nextPTS(), in.field() & ~VideoFrame::Interlaced));
	if (out2)
		queue.push_back(VideoFrame(true, out2, nextPTS(), in.field() & ~VideoFrame::Interlaced));
	return out1 || out2;
}
	void tryPostProc() {
		if (type != PP || !pp.initialize(option, in->format().size(), in->format().imgfmt()))
			return;
		const bool topFirst = in->mpi()->fields & MP_IMGFIELD_TOP_FIRST;
		push(topFirst ? topField() : bottomField());
		if (deint.doubler)
			push(!topFirst ? topField() : bottomField());
	}
	mp_image *bottomField() const {
		auto inm = in->mpi();
		auto out = pp.newImage(inm);
		inm->planes[0] += inm->stride[0];
		out->planes[0] += out->stride[0];
		inm->h -= 2;
		out->h -= 2;
		pp.process(out, inm);
		out->planes[0] -= out->stride[0];
		inm->planes[0] -= inm->stride[0];
		out->h += 2;
		inm->h += 2;
		return out;
	}
bool SoftwareDeinterlacer::process(const VideoFrame &in, QLinkedList<VideoFrame> &queue) {
	if (!(in.mpi()->fields & MP_IMGFIELD_INTERLACED))
		return 0;
	if (d->prev != MP_NOPTS_VALUE && ((in.pts() < d->prev) || (in.pts() - d->prev > 0.5))) // reset
		d->prev = MP_NOPTS_VALUE;
	d->in = &in;
	d->queue = &queue;
	switch (d->type) {
	case Mark:
		d->split();
		break;
	case Graph:
		d->tryGraph();
		break;
	case PP:
		d->tryPostProc();
		break;
	default:
		return 0;
	}
	return d->pushed;
}
	mp_image *topField() const {
		auto out = pp.newImage(in->mpi());
		pp.process(out, in->mpi());
		return out;
	}
	void push(int field) {
		queue->push_back(VideoFrame(false, in->mpi(), p->nextPTS(), field | (in->field() & ~VideoFrame::Interlaced)));
		++pushed;
	}