1
mirror of https://github.com/mpv-player/mpv synced 2024-08-24 07:21:49 +02:00

mp_image: fix copy_mpi() with 16 bit formats, add helper macros

Merged by wm4.

copy_mpi() assumed that planar YUV formats always used 1 byte per
component, which is not true for 9/10/16 bit YUV formats.
This commit is contained in:
Rudolf Polzer 2012-10-24 19:05:49 +02:00 committed by wm4
parent 64ac38c4d3
commit 1282f9d79e
2 changed files with 17 additions and 5 deletions

View File

@ -40,7 +40,9 @@ void mp_image_alloc_planes(mp_image_t *mpi) {
if (!mpi->planes[0])
abort(); //out of memory
if (mpi->flags&MP_IMGFLAG_PLANAR) {
int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
// FIXME this code only supports same bpp for all planes, and bpp divisible
// by 8. Currently the case for all planar formats.
int bpp = MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, 0) / 8;
// YV12/I420/YVU9/IF09. feel free to add other planar formats here...
mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
if(mpi->num_planes > 2){
@ -82,15 +84,15 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
if(mpi->flags&MP_IMGFLAG_PLANAR){
memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h,
memcpy_pic(dmpi->planes[0],mpi->planes[0], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 0), mpi->h,
dmpi->stride[0],mpi->stride[0]);
memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
memcpy_pic(dmpi->planes[1],mpi->planes[1], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 1), mpi->chroma_height,
dmpi->stride[1],mpi->stride[1]);
memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
memcpy_pic(dmpi->planes[2], mpi->planes[2], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 2), mpi->chroma_height,
dmpi->stride[2],mpi->stride[2]);
} else {
memcpy_pic(dmpi->planes[0],mpi->planes[0],
mpi->w*(dmpi->bpp/8), mpi->h,
MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 0), mpi->h,
dmpi->stride[0],mpi->stride[0]);
}
}

View File

@ -130,4 +130,14 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt);
void mp_image_alloc_planes(mp_image_t *mpi);
void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi);
// this macro requires img_format.h to be included too:
#define MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, p) \
(IMGFMT_IS_YUVP16((mpi)->imgfmt) ? 16 : 8)
#define MP_IMAGE_BITS_PER_PIXEL_ON_PLANE(mpi, p) \
(((mpi)->flags & MP_IMGFLAG_PLANAR) \
? MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, p) \
: (mpi)->bpp)
#define MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, p) \
((MP_IMAGE_BITS_PER_PIXEL_ON_PLANE(mpi, p) * ((mpi)->w >> (p ? mpi->chroma_x_shift : 0)) + 7) / 8)
#endif /* MPLAYER_MP_IMAGE_H */