summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_out/video_out_vdpau.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c
index 0268e8e0d..45fa0c7e2 100644
--- a/src/video_out/video_out_vdpau.c
+++ b/src/video_out/video_out_vdpau.c
@@ -121,6 +121,7 @@ VdpVideoSurfaceCreate *vdp_video_surface_create;
VdpVideoSurfaceDestroy *vdp_video_surface_destroy;
VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_putbits_ycbcr;
VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_getbits_ycbcr;
+VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters;
VdpOutputSurfaceCreate *vdp_output_surface_create;
VdpOutputSurfaceDestroy *vdp_output_surface_destroy;
@@ -1034,6 +1035,8 @@ static void vdpau_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_
{
vdpau_driver_t *this = (vdpau_driver_t *) this_gen;
vdpau_frame_t *frame = VDPAU_FRAME(frame_gen);
+ uint32_t requested_width = width;
+ uint32_t requested_height = height;
int clear = 0;
@@ -1051,6 +1054,15 @@ static void vdpau_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_
}
}
+ /* adjust width and height to meet xine and VDPAU constraints */
+ width = (width + ((flags & VO_CHROMA_422) ? 3 : 15)) & ~((flags & VO_CHROMA_422) ? 3 : 15); /* xine constraint */
+ height = (height + 3) & ~3; /* VDPAU constraint */
+ /* any excess pixels from the adjustment will be cropped away */
+ frame->vo_frame.width = width;
+ frame->vo_frame.height = height;
+ frame->vo_frame.crop_right += width - requested_width;
+ frame->vo_frame.crop_bottom += height - requested_height;
+
/* Check frame size and format and reallocate if necessary */
if ( (frame->width != width) || (frame->height != height) || (frame->format != format) || (frame->format==XINE_IMGFMT_VDPAU && frame->vdpau_accel_data.chroma!=chroma) ||
(frame->vdpau_accel_data.vdp_runtime_nr != this->vdp_runtime_nr)) {
@@ -1101,6 +1113,22 @@ static void vdpau_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_
++this->allocated_surfaces;
frame->vo_frame.proc_duplicate_frame_data = vdpau_duplicate_frame_data;
frame->vo_frame.proc_provide_standard_frame_data = vdpau_provide_standard_frame_data;
+
+ /* check whether allocated surface matches constraints */
+ {
+ VdpChromaType ct = (VdpChromaType)-1;
+ int w = -1;
+ int h = -1;
+
+ st = vdp_video_surface_get_parameters(frame->vdpau_accel_data.surface, &ct, &w, &h);
+ if (st != VDP_STATUS_OK)
+ fprintf(stderr, "vo_vdpau: failed to get parameters !! %s\n", vdp_get_error_string(st));
+ else if (w != width || h != height) {
+
+ fprintf(stderr, "vo_vdpau: video surface doesn't match size contraints (%d x %d) -> (%d x %d) != (%d x %d). Segfaults ahead!\n"
+ , requested_width, requested_height, width, height, w, h);
+ }
+ }
}
}
@@ -2469,6 +2497,9 @@ static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const vo
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR , (void*)&vdp_video_surface_getbits_ycbcr );
if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_GET_BITS_Y_CB_CR proc address !!", &this->vo_driver, 1 ) )
return NULL;
+ st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS , (void*)&vdp_video_surface_get_parameters );
+ if ( vdpau_init_error( st, "Can't get VIDEO_SURFACE_GET_PARAMETERS proc address !!", &this->vo_driver, 1 ) )
+ return NULL;
st = vdp_get_proc_address( vdp_device, VDP_FUNC_ID_OUTPUT_SURFACE_CREATE , (void*)&orig_vdp_output_surface_create ); vdp_output_surface_create = guarded_vdp_output_surface_create;
if ( vdpau_init_error( st, "Can't get OUTPUT_SURFACE_CREATE proc address !!", &this->vo_driver, 1 ) )
return NULL;