Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
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;
}