summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReinhard Nißl <rnissl@gmx.de>2011-01-28 23:44:07 +0100
committerReinhard Nißl <rnissl@gmx.de>2011-01-28 23:44:07 +0100
commit08712b40469e88b9642ce9c67465789f326b7cc4 (patch)
treeff5a508a39320e6b441cff4ff37c580e06d7bd09 /src
parente75518a44700ac544b60863fdfc23d2761f14c5d (diff)
downloadxine-lib-08712b40469e88b9642ce9c67465789f326b7cc4.tar.gz
xine-lib-08712b40469e88b9642ce9c67465789f326b7cc4.tar.bz2
Improve stability when decoding bad streams.
VDPAU applies different constraints to surface size and memory consumption than xine. Hence, when decoding bad streams (due to receptions issues for examples) with broken image sizes, it is likely that segfaults happen due to different memory size assumptions. So by adjusting image size to meet xine and VDPAU constraints, segfaults can be avoided. --HG-- extra : rebase_source : c493fac162bb34ab357783821bc72be85682c1eb
Diffstat (limited to 'src')
-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;