diff options
author | Christian König <[email protected]> | 2012-06-06 17:53:58 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2012-06-14 17:54:04 +0200 |
commit | eb024c74885778ab1ffa6dc590116959bb526c2e (patch) | |
tree | 764d8ff5e4eeeb83cd471f96a334b1000b7680e8 /src/gallium/state_trackers/vdpau/surface.c | |
parent | cb3054c849d8485af53da6a61b31b5c4e4eeb95d (diff) |
st/vdpau: fix YCbCr down/up-loads for buffers larger than requested
When the video buffer turns out to be larger than
requested by the application we shouldn't upload
or download more data into / from it original requested.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=39309
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/vdpau/surface.c')
-rw-r--r-- | src/gallium/state_trackers/vdpau/surface.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c index ab6960732f7..fde2336ca11 100644 --- a/src/gallium/state_trackers/vdpau/surface.c +++ b/src/gallium/state_trackers/vdpau/surface.c @@ -164,6 +164,25 @@ vlVdpVideoSurfaceGetParameters(VdpVideoSurface surface, return VDP_STATUS_OK; } +static void +vlVdpVideoSurfaceSize(vlVdpSurface *p_surf, int component, + unsigned *width, unsigned *height) +{ + *width = p_surf->templat.width; + *height = p_surf->templat.height; + + if (component > 0) { + if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { + *width /= 2; + *height /= 2; + } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { + *height /= 2; + } + if (p_surf->templat.interlaced) + *height /= 2; + } +} + /** * Copy image data from a VdpVideoSurface to application memory in a specified * YCbCr format. @@ -203,13 +222,16 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface, } for (i = 0; i < 3; ++i) { + unsigned width, height; struct pipe_sampler_view *sv = sampler_views[i]; if (!sv) continue; + vlVdpVideoSurfaceSize(vlsurface, i, &width, &height); + for (j = 0; j < sv->texture->depth0; ++j) { struct pipe_box box = { 0, 0, j, - sv->texture->width0, sv->texture->height0, 1 + width, height, 1 }; struct pipe_transfer *transfer; uint8_t *map; @@ -294,13 +316,16 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface, } for (i = 0; i < 3; ++i) { + unsigned width, height; struct pipe_sampler_view *sv = sampler_views[i]; if (!sv || !source_pitches[i]) continue; + vlVdpVideoSurfaceSize(p_surf, i, &width, &height); + for (j = 0; j < sv->texture->depth0; ++j) { struct pipe_box dst_box = { 0, 0, j, - sv->texture->width0, sv->texture->height0, 1 + width, height, 1 }; pipe->transfer_inline_write(pipe, sv->texture, 0, |