static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) { // pass-through if pp disabled if (!vf->priv->pp) return mpi; bool non_local = vf->priv->pp & 0xFFFF; struct mp_image *dmpi = mpi; if (!mp_image_is_writeable(mpi) || non_local) { dmpi = vf_alloc_out_image(vf); mp_image_copy_attributes(dmpi, mpi); } // apparently this is required assert(mpi->stride[0] >= ((mpi->w+7)&(~7))); // do the postprocessing! (or copy if no DR) pp_postprocess((const uint8_t **)mpi->planes, mpi->stride, dmpi->planes,dmpi->stride, (mpi->w+7)&(~7),mpi->h, mpi->qscale, mpi->qstride, vf->priv->ppMode[ vf->priv->pp ], vf->priv->context, #ifdef PP_PICT_TYPE_QP2 mpi->pict_type | (mpi->qscale_type ? PP_PICT_TYPE_QP2 : 0)); #else mpi->pict_type); #endif if (dmpi != mpi) talloc_free(mpi); return dmpi; }
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) { mp_image_t *dmpi = vf_alloc_out_image(vf); mp_image_copy_attributes(dmpi, mpi); for (int p = 0; p < mpi->num_planes; p++) { for (int y = 0; y < mpi->plane_h[p]; y++) { void *p_src = mpi->planes[p] + mpi->stride[p] * y; void *p_dst = dmpi->planes[p] + dmpi->stride[p] * y; int w = dmpi->plane_w[p]; if (mpi->imgfmt == IMGFMT_YUYV) { mirror_4_m(p_dst, p_src, w / 2, 2, 1, 0, 3); } else if (mpi->imgfmt == IMGFMT_UYVY) { mirror_4_m(p_dst, p_src, w / 2, 0, 3, 2, 1); } else { // make the compiler unroll the memcpy in mirror() switch (mpi->fmt.bytes[p]) { case 1: mirror(p_dst, p_src, 1, w); break; case 2: mirror(p_dst, p_src, 2, w); break; case 3: mirror(p_dst, p_src, 3, w); break; case 4: mirror(p_dst, p_src, 4, w); break; default: mirror(p_dst, p_src, mpi->fmt.bytes[p], w); } } } } talloc_free(mpi); return dmpi; }
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) { int e_x = vf->priv->exp_x, e_y = vf->priv->exp_y; int e_w = vf->priv->exp_w, e_h = vf->priv->exp_h; if (e_x == 0 && e_y == 0 && e_w == mpi->w && e_h == mpi->h) return mpi; struct mp_image *dmpi = vf_alloc_out_image(vf); mp_image_copy_attributes(dmpi, mpi); struct mp_image cropped = *dmpi; mp_image_crop(&cropped, e_x, e_y, e_x + mpi->w, e_y + mpi->h); mp_image_copy(&cropped, mpi); int e_x2 = e_x + MP_ALIGN_DOWN(mpi->w, mpi->fmt.align_x); int e_y2 = e_y + MP_ALIGN_DOWN(mpi->h, mpi->fmt.align_y); // top border (over the full width) mp_image_clear(dmpi, 0, 0, e_w, e_y); // bottom border (over the full width) mp_image_clear(dmpi, 0, e_y2, e_w, e_h); // left mp_image_clear(dmpi, 0, e_y, e_x, e_y2); // right mp_image_clear(dmpi, e_x2, e_y, e_w, e_y2); talloc_free(mpi); return dmpi; }
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) { struct mp_image *dmpi = vf_alloc_out_image(vf); mp_image_copy_attributes(dmpi, mpi); mp_sws_scale(vf->priv->sws, dmpi, mpi); talloc_free(mpi); return dmpi; }
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) { if (vf->priv->direction & 4) return mpi; struct mp_image *dmpi = vf_alloc_out_image(vf); mp_image_copy_attributes(dmpi, mpi); for (int p = 0; p < mpi->num_planes; p++) { rotate(dmpi->planes[p],mpi->planes[p], dmpi->stride[p],mpi->stride[p], dmpi->plane_w[p], dmpi->plane_h[p], mpi->fmt.bytes[p], vf->priv->direction); } talloc_free(mpi); return dmpi; }
static int filter_ext(struct vf_instance *vf, struct mp_image *mpi) { VdpStatus vdp_st; struct vf_priv_s *p = vf->priv; struct mp_vdpau_ctx *ctx = p->ctx; struct vdp_functions *vdp = &ctx->vdp; if (!mpi) { return 0; } // Pass-through anything that's not been decoded by VDPAU if (mpi->imgfmt != IMGFMT_VDPAU) { vf_add_output_frame(vf, mpi); return 0; } if (mp_vdpau_mixed_frame_get(mpi)) { MP_ERR(vf, "Can't apply vdpaurb filter after vdpaupp filter.\n"); mp_image_unrefp(&mpi); return -1; } struct mp_image *out = vf_alloc_out_image(vf); if (!out) { mp_image_unrefp(&mpi); return -1; } mp_image_copy_attributes(out, mpi); VdpVideoSurface surface = (uintptr_t)mpi->planes[3]; assert(surface > 0); vdp_st = vdp->video_surface_get_bits_y_cb_cr(surface, VDP_YCBCR_FORMAT_NV12, (void * const *)out->planes, out->stride); CHECK_VDP_WARNING(vf, "Error when calling vdp_output_surface_get_bits_y_cb_cr"); vf_add_output_frame(vf, out); mp_image_unrefp(&mpi); return 0; }
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) { struct pullup_context *c = vf->priv->ctx; struct pullup_buffer *b; struct pullup_frame *f; int p; int i; double pts = mpi->pts; struct mp_image *dmpi = NULL; if (!vf->priv->init) init_pullup(vf, mpi); if (1) { b = pullup_get_buffer(c, 2); if (!b) { mp_msg(MSGT_VFILTER,MSGL_ERR,"Could not get buffer from pullup!\n"); f = pullup_get_frame(c); pullup_release_frame(f); goto skip; } memcpy_pic(b->planes[0], mpi->planes[0], mpi->w, mpi->h, c->stride[0], mpi->stride[0]); memcpy_pic(b->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, c->stride[1], mpi->stride[1]); memcpy_pic(b->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, c->stride[2], mpi->stride[2]); } if (mpi->qscale) { memcpy(b->planes[3], mpi->qscale, c->w[3]); memcpy(b->planes[3]+c->w[3], mpi->qscale, c->w[3]); } p = mpi->fields & MP_IMGFIELD_TOP_FIRST ? 0 : (mpi->fields & MP_IMGFIELD_ORDERED ? 1 : 0); if (pts == MP_NOPTS_VALUE) { pullup_submit_field(c, b, p, MP_NOPTS_VALUE); pullup_submit_field(c, b, p^1, MP_NOPTS_VALUE); if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST) pullup_submit_field(c, b, p, MP_NOPTS_VALUE); } else { double delta; if (vf->priv->lastpts == MP_NOPTS_VALUE) delta = 1001.0/60000.0; // delta = field time distance else delta = (pts - vf->priv->lastpts) / 2; if (delta <= 0.0 || delta >= 0.5) delta = 0.0; vf->priv->lastpts = pts; if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST) { pullup_submit_field(c, b, p, pts - delta); pullup_submit_field(c, b, p^1, pts); pullup_submit_field(c, b, p, pts + delta); } else { pullup_submit_field(c, b, p, pts - delta * 0.5); pullup_submit_field(c, b, p^1, pts + delta * 0.5); } } pullup_release_buffer(b, 2); f = pullup_get_frame(c); /* Fake yes for first few frames (buffer depth) to keep from * breaking A/V sync with G1's bad architecture... */ //if (!f) return vf->priv->fakecount ? (--vf->priv->fakecount,1) : 0; if (!f) goto skip; if (f->length < 2) { pullup_release_frame(f); f = pullup_get_frame(c); if (!f) goto skip; if (f->length < 2) { pullup_release_frame(f); if (!(mpi->fields & MP_IMGFIELD_REPEAT_FIRST)) goto skip; f = pullup_get_frame(c); if (!f) goto skip; if (f->length < 2) { pullup_release_frame(f); goto skip; } } } #if 0 /* Average qscale tables from both frames. */ if (mpi->qscale) { for (i=0; i<c->w[3]; i++) { vf->priv->qbuf[i] = (f->ofields[0]->planes[3][i] + f->ofields[1]->planes[3][i+c->w[3]])>>1; } } #else /* Take worst of qscale tables from both frames. */ if (mpi->qscale) { for (i=0; i<c->w[3]; i++) { vf->priv->qbuf[i] = MAX(f->ofields[0]->planes[3][i], f->ofields[1]->planes[3][i+c->w[3]]); } } #endif /* If the frame isn't already exportable... */ if (!f->buffer) pullup_pack_frame(c, f); // NOTE: the copy could probably be avoided by changing or using the // pullup internal buffer management. But right now just do the // safe thing and always copy. Code outside the filter might // hold a buffer reference even if the filter chain is destroyed. dmpi = vf_alloc_out_image(vf); mp_image_copy_attributes(dmpi, mpi); struct mp_image data = *dmpi; data.planes[0] = f->buffer->planes[0]; data.planes[1] = f->buffer->planes[1]; data.planes[2] = f->buffer->planes[2]; data.stride[0] = c->stride[0]; data.stride[1] = c->stride[1]; data.stride[2] = c->stride[2]; mp_image_copy(dmpi, &data); dmpi->pts = f->pts; // Warning: entirely bogus memory management of qscale if (mpi->qscale) { dmpi->qscale = vf->priv->qbuf; dmpi->qstride = mpi->qstride; dmpi->qscale_type = mpi->qscale_type; } pullup_release_frame(f); skip: talloc_free(mpi); return dmpi; }