# HG changeset patch # User reimar # Date 1262300005 0 # Node ID 19414a60569554e8a369f78df5573e09d0facb85 # Parent 0f25d30629873cb1877620c4c0ff4fda24bebbd0 Add support for 16-bit per component YUV formats. diff -r 0f25d3062987 -r 19414a605695 codec-cfg.c --- a/codec-cfg.c Thu Dec 31 19:59:58 2009 +0000 +++ b/codec-cfg.c Thu Dec 31 22:53:25 2009 +0000 @@ -152,6 +152,15 @@ {"NV21", IMGFMT_NV21}, {"YVU9", IMGFMT_YVU9}, {"IF09", IMGFMT_IF09}, + {"444P16LE", IMGFMT_444P16_LE}, + {"444P16BE", IMGFMT_444P16_BE}, + {"422P16LE", IMGFMT_422P16_LE}, + {"422P16BE", IMGFMT_422P16_BE}, + {"420P16LE", IMGFMT_420P16_LE}, + {"420P16BE", IMGFMT_420P16_BE}, + {"444P16", IMGFMT_444P16}, + {"422P16", IMGFMT_422P16}, + {"420P16", IMGFMT_420P16}, {"444P", IMGFMT_444P}, {"422P", IMGFMT_422P}, {"411P", IMGFMT_411P}, diff -r 0f25d3062987 -r 19414a605695 fmt-conversion.c --- a/fmt-conversion.c Thu Dec 31 19:59:58 2009 +0000 +++ b/fmt-conversion.c Thu Dec 31 22:53:25 2009 +0000 @@ -59,6 +59,12 @@ {IMGFMT_422P, PIX_FMT_YUV422P}, {IMGFMT_444P, PIX_FMT_YUV444P}, {IMGFMT_440P, PIX_FMT_YUV440P}, + {IMGFMT_420P16_LE, PIX_FMT_YUV420P16LE}, + {IMGFMT_420P16_BE, PIX_FMT_YUV420P16BE}, + {IMGFMT_422P16_LE, PIX_FMT_YUV422P16LE}, + {IMGFMT_422P16_BE, PIX_FMT_YUV422P16BE}, + {IMGFMT_444P16_LE, PIX_FMT_YUV444P16LE}, + {IMGFMT_444P16_BE, PIX_FMT_YUV444P16BE}, // YUVJ are YUV formats that use the full Y range and not just // 16 - 235 (see colorspaces.txt). diff -r 0f25d3062987 -r 19414a605695 libmpcodecs/img_format.c --- a/libmpcodecs/img_format.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libmpcodecs/img_format.c Thu Dec 31 22:53:25 2009 +0000 @@ -37,6 +37,12 @@ case IMGFMT_CLPL: return "Planar CLPL"; case IMGFMT_Y800: return "Planar Y800"; case IMGFMT_Y8: return "Planar Y8"; + case IMGFMT_420P16_LE: return "Planar 420P 16-bit little-endian"; + case IMGFMT_420P16_BE: return "Planar 420P 16-bit big-endian"; + case IMGFMT_422P16_LE: return "Planar 422P 16-bit little-endian"; + case IMGFMT_422P16_BE: return "Planar 422P 16-bit big-endian"; + case IMGFMT_444P16_LE: return "Planar 444P 16-bit little-endian"; + case IMGFMT_444P16_BE: return "Planar 444P 16-bit big-endian"; case IMGFMT_444P: return "Planar 444P"; case IMGFMT_422P: return "Planar 422P"; case IMGFMT_411P: return "Planar 411P"; @@ -83,8 +89,13 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift) { int xs = 0, ys = 0; + int bpp; + int bpp_factor = 1; int err = 0; switch (format) { + case IMGFMT_420P16_LE: + case IMGFMT_420P16_BE: + bpp_factor = 2; case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: @@ -96,10 +107,16 @@ xs = 2; ys = 2; break; + case IMGFMT_444P16_LE: + case IMGFMT_444P16_BE: + bpp_factor = 2; case IMGFMT_444P: xs = 0; ys = 0; break; + case IMGFMT_422P16_LE: + case IMGFMT_422P16_BE: + bpp_factor = 2; case IMGFMT_422P: xs = 1; ys = 0; @@ -118,5 +135,7 @@ } if (x_shift) *x_shift = xs; if (y_shift) *y_shift = ys; - return err ? 0 : 8 + (16 >> (xs + ys)); + bpp = 8 + (16 >> (xs + ys)); + bpp *= bpp_factor; + return err ? 0 : bpp; } diff -r 0f25d3062987 -r 19414a605695 libmpcodecs/img_format.h --- a/libmpcodecs/img_format.h Thu Dec 31 19:59:58 2009 +0000 +++ b/libmpcodecs/img_format.h Thu Dec 31 22:53:25 2009 +0000 @@ -73,6 +73,26 @@ #define IMGFMT_411P 0x50313134 #define IMGFMT_440P 0x50303434 #define IMGFMT_HM12 0x32314D48 +#define IMGFMT_444P16_LE 0x51343434 +#define IMGFMT_444P16_BE 0x34343451 +#define IMGFMT_422P16_LE 0x51323234 +#define IMGFMT_422P16_BE 0x34323251 +#define IMGFMT_420P16_LE 0x51303234 +#define IMGFMT_420P16_BE 0x34323051 +#if HAVE_BIGENDIAN +#define IMGFMT_444P16 IMGFMT_444P16_BE +#define IMGFMT_422P16 IMGFMT_422P16_BE +#define IMGFMT_420P16 IMGFMT_420P16_BE +#else +#define IMGFMT_444P16 IMGFMT_444P16_LE +#define IMGFMT_422P16 IMGFMT_422P16_LE +#define IMGFMT_420P16 IMGFMT_420P16_LE +#endif + +#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt ^ IMGFMT_420P16_LE) & 0xff0000ff) == 0) +#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt ^ IMGFMT_420P16_BE) & 0xff0000ff) == 0) +#define IMGFMT_IS_YUVP16_NE(fmt) (((fmt ^ IMGFMT_420P16 ) & 0xff0000ff) == 0) +#define IMGFMT_IS_YUVP16(fmt) (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt)) /* Packed YUV Formats */ diff -r 0f25d3062987 -r 19414a605695 libmpcodecs/mp_image.c --- a/libmpcodecs/mp_image.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libmpcodecs/mp_image.c Thu Dec 31 22:53:25 2009 +0000 @@ -29,17 +29,18 @@ else mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8); if(mpi->flags&MP_IMGFLAG_PLANAR){ + int bpp = IMGFMT_IS_YUVP16(fmt)? 2 : 1; // YV12/I420/YVU9/IF09. feel free to add other planar formats here... - if(!mpi->stride[0]) mpi->stride[0]=mpi->width; - if(!mpi->stride[1]) mpi->stride[1]=mpi->stride[2]=mpi->chroma_width; + if(!mpi->stride[0]) mpi->stride[0]=bpp*mpi->width; + if(!mpi->stride[1]) mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width; if(mpi->flags&MP_IMGFLAG_SWAPPED){ // I420/IYUV (Y,U,V) - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; } else { // YV12,YVU9,IF09 (Y,V,U) - mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height; + mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; } } else { if(!mpi->stride[0]) mpi->stride[0]=mpi->width*mpi->bpp/8; diff -r 0f25d3062987 -r 19414a605695 libmpcodecs/mp_image.h --- a/libmpcodecs/mp_image.h Thu Dec 31 19:59:58 2009 +0000 +++ b/libmpcodecs/mp_image.h Thu Dec 31 22:53:25 2009 +0000 @@ -152,6 +152,12 @@ case IMGFMT_422P: case IMGFMT_411P: case IMGFMT_440P: + case IMGFMT_444P16_LE: + case IMGFMT_444P16_BE: + case IMGFMT_422P16_LE: + case IMGFMT_422P16_BE: + case IMGFMT_420P16_LE: + case IMGFMT_420P16_BE: return; case IMGFMT_Y800: case IMGFMT_Y8: diff -r 0f25d3062987 -r 19414a605695 libmpcodecs/vf.c --- a/libmpcodecs/vf.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libmpcodecs/vf.c Thu Dec 31 22:53:25 2009 +0000 @@ -383,25 +383,26 @@ else mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8); if(mpi->flags&MP_IMGFLAG_PLANAR){ + int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; // YV12/I420/YVU9/IF09. feel free to add other planar formats here... //if(!mpi->stride[0]) - mpi->stride[0]=mpi->width; + mpi->stride[0]=bpp*mpi->width; //if(!mpi->stride[1]) if(mpi->num_planes > 2){ - mpi->stride[1]=mpi->stride[2]=mpi->chroma_width; + mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width; if(mpi->flags&MP_IMGFLAG_SWAPPED){ // I420/IYUV (Y,U,V) - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; } else { // YV12,YVU9,IF09 (Y,V,U) - mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height; + mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; } } else { // NV12/NV21 mpi->stride[1]=mpi->chroma_width; - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; } } else { //if(!mpi->stride[0]) diff -r 0f25d3062987 -r 19414a605695 libmpcodecs/vf_scale.c --- a/libmpcodecs/vf_scale.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libmpcodecs/vf_scale.c Thu Dec 31 22:53:25 2009 +0000 @@ -64,6 +64,12 @@ IMGFMT_YUY2, IMGFMT_UYVY, IMGFMT_440P, + IMGFMT_444P16_LE, + IMGFMT_444P16_BE, + IMGFMT_422P16_LE, + IMGFMT_422P16_BE, + IMGFMT_420P16_LE, + IMGFMT_420P16_BE, // RGB and grayscale (Y8 and Y800): IMGFMT_BGR32, IMGFMT_RGB32, @@ -474,6 +480,12 @@ case IMGFMT_422P: case IMGFMT_411P: case IMGFMT_440P: + case IMGFMT_444P16_LE: + case IMGFMT_444P16_BE: + case IMGFMT_422P16_LE: + case IMGFMT_422P16_BE: + case IMGFMT_420P16_LE: + case IMGFMT_420P16_BE: case IMGFMT_BGR8: case IMGFMT_RGB8: case IMGFMT_BG4B: diff -r 0f25d3062987 -r 19414a605695 libvo/gl_common.c --- a/libvo/gl_common.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libvo/gl_common.c Thu Dec 31 22:53:25 2009 +0000 @@ -234,9 +234,15 @@ if (!gl_format) gl_format = &dummy2; if (!gl_type) gl_type = &dummy2; - // these are all the same for our purpose - if (mp_get_chroma_shift(fmt, NULL, NULL)) - fmt = IMGFMT_YV12; + if (mp_get_chroma_shift(fmt, NULL, NULL)) { + // reduce the possible cases a bit + if (IMGFMT_IS_YUVP16_LE(fmt)) + fmt = IMGFMT_420P16_LE; + else if (IMGFMT_IS_YUVP16_BE(fmt)) + fmt = IMGFMT_420P16_BE; + else + fmt = IMGFMT_YV12; + } *bpp = IMGFMT_IS_BGR(fmt)?IMGFMT_BGR_DEPTH(fmt):IMGFMT_RGB_DEPTH(fmt); *gl_texfmt = 3; @@ -254,6 +260,13 @@ *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_BYTE; break; + case IMGFMT_420P16: + supported = 0; // no native YUV support + *gl_texfmt = 1; + *bpp = 16; + *gl_format = GL_LUMINANCE; + *gl_type = GL_UNSIGNED_SHORT; + break; case IMGFMT_YV12: supported = 0; // no native YV12 support case IMGFMT_Y800: diff -r 0f25d3062987 -r 19414a605695 libvo/vo_gl.c --- a/libvo/vo_gl.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libvo/vo_gl.c Thu Dec 31 22:53:25 2009 +0000 @@ -971,7 +971,8 @@ caps |= VFCAP_OSD | VFCAP_EOSD | (scaled_osd ? 0 : VFCAP_EOSD_UNSCALED); if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA) return caps; - if (use_yuv && mp_get_chroma_shift(format, NULL, NULL)) + if (use_yuv && mp_get_chroma_shift(format, NULL, NULL) && + (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format))) return caps; // HACK, otherwise we get only b&w with some filters (e.g. -vf eq) // ideally MPlayer should be fixed instead not to use Y800 when it has the choice diff -r 0f25d3062987 -r 19414a605695 libvo/vo_gl2.c --- a/libvo/vo_gl2.c Thu Dec 31 19:59:58 2009 +0000 +++ b/libvo/vo_gl2.c Thu Dec 31 22:53:25 2009 +0000 @@ -822,7 +822,8 @@ static int query_format(uint32_t format) { - if (use_yuv && mp_get_chroma_shift(format, NULL, NULL)) + if (use_yuv && mp_get_chroma_shift(format, NULL, NULL) && + (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format))) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; switch(format) { diff -r 0f25d3062987 -r 19414a605695 m_option.c --- a/m_option.c Thu Dec 31 19:59:58 2009 +0000 +++ b/m_option.c Thu Dec 31 22:53:25 2009 +0000 @@ -1032,6 +1032,15 @@ const char* name; unsigned int fmt; } mp_imgfmt_list[] = { + {"444p16le", IMGFMT_444P16_LE}, + {"444p16be", IMGFMT_444P16_BE}, + {"422p16le", IMGFMT_422P16_LE}, + {"422p16be", IMGFMT_422P16_BE}, + {"420p16le", IMGFMT_420P16_LE}, + {"420p16be", IMGFMT_420P16_BE}, + {"444p16", IMGFMT_444P16}, + {"422p16", IMGFMT_422P16}, + {"420p16", IMGFMT_420P16}, {"444p", IMGFMT_444P}, {"422p", IMGFMT_422P}, {"411p", IMGFMT_411P},