mirror of https://github.com/mpv-player/mpv
vdpau: deduplicate video surface upload code
This was a minor code duplication between vf_vdpaupp.c and vo_vdpau.c. (In theory, we could always require using vf_vdpaupp with vo_vdpau, but I think it's better if vo_vdpau can work standalone.)
This commit is contained in:
parent
94441ed139
commit
a7fe47e495
|
@ -53,35 +53,6 @@ struct vf_priv_s {
|
|||
struct mp_vdpau_mixer_opts opts;
|
||||
};
|
||||
|
||||
static struct mp_image *upload(struct vf_instance *vf, struct mp_image *mpi)
|
||||
{
|
||||
struct vf_priv_s *p = vf->priv;
|
||||
struct vdp_functions *vdp = &p->ctx->vdp;
|
||||
VdpStatus vdp_st;
|
||||
|
||||
VdpChromaType chroma_type = (VdpChromaType)-1;
|
||||
VdpYCbCrFormat pixel_format = (VdpYCbCrFormat)-1;
|
||||
mp_vdpau_get_format(mpi->imgfmt, &chroma_type, &pixel_format);
|
||||
|
||||
struct mp_image *hwmpi =
|
||||
mp_vdpau_get_video_surface(p->ctx, chroma_type, mpi->w, mpi->h);
|
||||
if (!hwmpi)
|
||||
return mpi;
|
||||
|
||||
VdpVideoSurface surface = (intptr_t)hwmpi->planes[3];
|
||||
const void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
|
||||
if (mpi->imgfmt == IMGFMT_NV12)
|
||||
destdata[1] = destdata[2];
|
||||
vdp_st = vdp->video_surface_put_bits_y_cb_cr(surface,
|
||||
pixel_format, destdata, mpi->stride);
|
||||
CHECK_VDP_WARNING(vf, "Error when calling vdp_video_surface_put_bits_y_cb_cr");
|
||||
|
||||
mp_image_copy_attributes(hwmpi, mpi);
|
||||
|
||||
talloc_free(mpi);
|
||||
return hwmpi;
|
||||
}
|
||||
|
||||
static void forget_frames(struct vf_instance *vf)
|
||||
{
|
||||
struct vf_priv_s *p = vf->priv;
|
||||
|
@ -153,15 +124,13 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *mpi)
|
|||
int maxbuffer = p->opts.deint ? MP_ARRAY_SIZE(p->buffered) : 2;
|
||||
bool eof = !mpi;
|
||||
|
||||
if (mpi && mpi->imgfmt != IMGFMT_VDPAU) {
|
||||
mpi = upload(vf, mpi);
|
||||
if (mpi->imgfmt != IMGFMT_VDPAU) {
|
||||
talloc_free(mpi);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mpi) {
|
||||
struct mp_image *new = mp_vdpau_upload_video_surface(p->ctx, mpi);
|
||||
talloc_free(mpi);
|
||||
if (!new)
|
||||
return -1;
|
||||
mpi = new;
|
||||
|
||||
if (mpi->planes[2]) {
|
||||
MP_ERR(vf, "Can't apply vdpaupp filter multiple times.\n");
|
||||
vf_add_output_frame(vf, mpi);
|
||||
|
|
|
@ -926,9 +926,9 @@ static struct mp_image *filter_image(struct vo *vo, struct mp_image *mpi)
|
|||
struct mp_image *reserved_mpi = NULL;
|
||||
VdpStatus vdp_st;
|
||||
|
||||
if (vc->image_format == IMGFMT_VDPAU) {
|
||||
reserved_mpi = mp_image_new_ref(mpi);
|
||||
} else if (vc->rgb_mode) {
|
||||
handle_preemption(vo);
|
||||
|
||||
if (vc->rgb_mode) {
|
||||
reserved_mpi = get_rgb_surface(vo);
|
||||
if (!reserved_mpi)
|
||||
goto end;
|
||||
|
@ -942,23 +942,12 @@ static struct mp_image *filter_image(struct vo *vo, struct mp_image *mpi)
|
|||
"output_surface_put_bits_native");
|
||||
}
|
||||
} else {
|
||||
reserved_mpi = mp_vdpau_get_video_surface(vc->mpvdp, vc->vdp_chroma_type,
|
||||
mpi->w, mpi->h);
|
||||
if (!reserved_mpi)
|
||||
goto end;
|
||||
VdpVideoSurface surface = (VdpVideoSurface)(intptr_t)reserved_mpi->planes[3];
|
||||
if (handle_preemption(vo) >= 0) {
|
||||
const void *destdata[3] = {mpi->planes[0], mpi->planes[2],
|
||||
mpi->planes[1]};
|
||||
if (vc->image_format == IMGFMT_NV12)
|
||||
destdata[1] = destdata[2];
|
||||
vdp_st = vdp->video_surface_put_bits_y_cb_cr(surface,
|
||||
vc->vdp_pixel_format, destdata, mpi->stride);
|
||||
CHECK_VDP_WARNING(vo, "Error when calling "
|
||||
"vdp_video_surface_put_bits_y_cb_cr");
|
||||
}
|
||||
reserved_mpi = mp_vdpau_upload_video_surface(vc->mpvdp, mpi);
|
||||
}
|
||||
|
||||
if (!reserved_mpi)
|
||||
goto end;
|
||||
|
||||
mp_image_copy_attributes(reserved_mpi, mpi);
|
||||
|
||||
end:
|
||||
|
|
|
@ -273,3 +273,36 @@ bool mp_vdpau_get_format(int imgfmt, VdpChromaType *out_chroma_type,
|
|||
*out_pixel_format = ycbcr;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use mp_vdpau_get_video_surface, and upload mpi to it. Return NULL on failure.
|
||||
// If the image is already a vdpau video surface, just return a reference.
|
||||
struct mp_image *mp_vdpau_upload_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
struct mp_image *mpi)
|
||||
{
|
||||
struct vdp_functions *vdp = &ctx->vdp;
|
||||
VdpStatus vdp_st;
|
||||
|
||||
if (mpi->imgfmt == IMGFMT_VDPAU)
|
||||
return mp_image_new_ref(mpi);
|
||||
|
||||
VdpChromaType chroma_type;
|
||||
VdpYCbCrFormat pixel_format;
|
||||
if (!mp_vdpau_get_format(mpi->imgfmt, &chroma_type, &pixel_format))
|
||||
return NULL;
|
||||
|
||||
struct mp_image *hwmpi =
|
||||
mp_vdpau_get_video_surface(ctx, chroma_type, mpi->w, mpi->h);
|
||||
if (!hwmpi)
|
||||
return NULL;
|
||||
|
||||
VdpVideoSurface surface = (intptr_t)hwmpi->planes[3];
|
||||
const void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
|
||||
if (mpi->imgfmt == IMGFMT_NV12)
|
||||
destdata[1] = destdata[2];
|
||||
vdp_st = vdp->video_surface_put_bits_y_cb_cr(surface,
|
||||
pixel_format, destdata, mpi->stride);
|
||||
CHECK_VDP_WARNING(ctx, "Error when calling vdp_video_surface_put_bits_y_cb_cr");
|
||||
|
||||
mp_image_copy_attributes(hwmpi, mpi);
|
||||
return hwmpi;
|
||||
}
|
||||
|
|
|
@ -69,4 +69,7 @@ struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
|
|||
bool mp_vdpau_get_format(int imgfmt, VdpChromaType *out_chroma_type,
|
||||
VdpYCbCrFormat *out_pixel_format);
|
||||
|
||||
struct mp_image *mp_vdpau_upload_video_surface(struct mp_vdpau_ctx *ctx,
|
||||
struct mp_image *mpi);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue