summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-12-31 22:53:25 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-12-31 22:53:25 +0000
commita326622304cedacce34b31f47dafe7069e076e01 (patch)
treed4046032aae4527ec51bec2dd502b0c55991fc7e
parent498ad7ba573b80ac8740886b46f9f8e660647858 (diff)
downloadmpv-a326622304cedacce34b31f47dafe7069e076e01.tar.bz2
mpv-a326622304cedacce34b31f47dafe7069e076e01.tar.xz
Add support for 16-bit per component YUV formats.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30152 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--codec-cfg.c9
-rw-r--r--fmt-conversion.c6
-rw-r--r--libmpcodecs/img_format.c21
-rw-r--r--libmpcodecs/img_format.h20
-rw-r--r--libmpcodecs/mp_image.c13
-rw-r--r--libmpcodecs/mp_image.h6
-rw-r--r--libmpcodecs/vf.c15
-rw-r--r--libmpcodecs/vf_scale.c12
-rw-r--r--libvo/gl_common.c19
-rw-r--r--libvo/vo_gl.c3
-rw-r--r--libvo/vo_gl2.c3
-rw-r--r--m_option.c9
12 files changed, 117 insertions, 19 deletions
diff --git a/codec-cfg.c b/codec-cfg.c
index 8315ef7cf2..a0be5df810 100644
--- a/codec-cfg.c
+++ b/codec-cfg.c
@@ -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},
diff --git a/fmt-conversion.c b/fmt-conversion.c
index 14a1f2df6f..8455277164 100644
--- a/fmt-conversion.c
+++ b/fmt-conversion.c
@@ -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).
diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c
index bfdcf91b64..d29f47fb1c 100644
--- a/libmpcodecs/img_format.c
+++ b/libmpcodecs/img_format.c
@@ -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;
}
diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h
index bcbdf0b56e..5d3a48caaf 100644
--- a/libmpcodecs/img_format.h
+++ b/libmpcodecs/img_format.h
@@ -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 --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c
index 3eb524d491..3d73a2e3ed 100644
--- a/libmpcodecs/mp_image.c
+++ b/libmpcodecs/mp_image.c
@@ -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;
diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h
index bd750de9ca..c4773ce0da 100644
--- a/libmpcodecs/mp_image.h
+++ b/libmpcodecs/mp_image.h
@@ -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:
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index c2d50b870d..9a03634741 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -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])
diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c
index 000fbacb1b..d2917bffbd 100644
--- a/libmpcodecs/vf_scale.c
+++ b/libmpcodecs/vf_scale.c
@@ -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:
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index 2571959640..ffca3ac35f 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -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:
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index eb71149bbb..95a1b74167 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -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
diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c
index 1cdf7bf83f..626da44c2a 100644
--- a/libvo/vo_gl2.c
+++ b/libvo/vo_gl2.c
@@ -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) {
diff --git a/m_option.c b/m_option.c
index 752a7f1330..fbde88736b 100644
--- a/m_option.c
+++ b/m_option.c
@@ -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},