diff options
author | Reinhard Nißl <rnissl@gmx.de> | 2011-01-28 23:44:07 +0100 |
---|---|---|
committer | Reinhard Nißl <rnissl@gmx.de> | 2011-01-28 23:44:07 +0100 |
commit | 08712b40469e88b9642ce9c67465789f326b7cc4 (patch) | |
tree | ff5a508a39320e6b441cff4ff37c580e06d7bd09 /src | |
parent | e75518a44700ac544b60863fdfc23d2761f14c5d (diff) | |
download | xine-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.c | 31 |
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; |