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); }
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 = ∈ 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; }