mirror of
https://github.com/mpv-player/mpv
synced 2025-03-20 02:09:52 +00:00
Add support for 16-bit per component YUV formats.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30152 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
498ad7ba57
commit
a326622304
@ -152,6 +152,15 @@ static int add_to_format(char *s, char *alias,unsigned int *fourcc, unsigned int
|
||||
{"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},
|
||||
|
@ -59,6 +59,12 @@ static const struct {
|
||||
{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).
|
||||
|
@ -37,6 +37,12 @@ const char *vo_format_name(int format)
|
||||
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 @@ const char *vo_format_name(int format)
|
||||
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 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift)
|
||||
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 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift)
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -29,17 +29,18 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
|
||||
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;
|
||||
|
@ -152,6 +152,12 @@ static inline void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
|
||||
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:
|
||||
|
@ -383,25 +383,26 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype,
|
||||
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])
|
||||
|
@ -64,6 +64,12 @@ static unsigned int outfmt_list[]={
|
||||
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 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){
|
||||
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:
|
||||
|
@ -234,9 +234,15 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt,
|
||||
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 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt,
|
||||
*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:
|
||||
|
@ -971,7 +971,8 @@ query_format(uint32_t format)
|
||||
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
|
||||
|
@ -822,7 +822,8 @@ draw_frame(uint8_t *src[])
|
||||
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) {
|
||||
|
@ -1032,6 +1032,15 @@ static struct {
|
||||
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},
|
||||
|
Loading…
Reference in New Issue
Block a user