video: remove img_format compat hacks

Remove the strange things the old mp_image_setfmt() code did to the
image format parameters. This includes setting chroma shift to 31 for
gray (Y8) formats and more.

Y8 + vo_opengl_old didn't actually work for unknown reasons (regression
in this branch). Fix this. The difference is that Y8 is now interpreted
as gray RGB (LUMINANCE texture) instead of involving YUV (and levels)
conversion.

Get rid of distinguishing RGB and BGR. There wasn't really any good
reason for this.

Remove mp_get_chroma_shift() and IMGFMT_IS_YUVP16*(). mp_imgfmt_desc
gives the same information and more.
This commit is contained in:
wm4 2012-12-24 01:10:57 +01:00
parent 3791c226b7
commit 5830d639b8
10 changed files with 85 additions and 210 deletions

View File

@ -51,7 +51,7 @@ static int config(struct vf_instance *vf,
if(vf->priv->crop_x<0) vf->priv->crop_x=(width-vf->priv->crop_w)/2;
if(vf->priv->crop_y<0) vf->priv->crop_y=(height-vf->priv->crop_h)/2;
// rounding:
if(!IMGFMT_IS_RGB(outfmt) && !IMGFMT_IS_BGR(outfmt)){
if(!IMGFMT_IS_RGB(outfmt)){
switch(outfmt){
case IMGFMT_444P:
case IMGFMT_Y8:

View File

@ -108,7 +108,7 @@ static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
//===========================================================================//
static int query_format(struct vf_instance *vf, unsigned int fmt){
if(IMGFMT_IS_RGB(fmt) || IMGFMT_IS_BGR(fmt)) return vf_next_query_format(vf, fmt);
if(IMGFMT_IS_RGB(fmt)) return vf_next_query_format(vf, fmt);
// we can support only symmetric (chroma_x_shift==chroma_y_shift) YUV formats:
switch(fmt) {
case IMGFMT_Y8:

View File

@ -98,22 +98,6 @@ struct mp_imgfmt_entry mp_imgfmt_list[] = {
{0}
};
int mp_get_chroma_shift(int format, int *x_shift, int *y_shift,
int *component_bits)
{
struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(format);
if (fmt.id && (fmt.flags & MP_IMGFLAG_YUV_P)) {
if (x_shift)
*x_shift = fmt.xs[1];
if (y_shift)
*y_shift = fmt.ys[1];
if (component_bits)
*component_bits = fmt.plane_bits;
return fmt.avg_bpp;
}
return 0;
}
unsigned int mp_imgfmt_from_name(bstr name, bool allow_hwaccel)
{
for(struct mp_imgfmt_entry *p = mp_imgfmt_list; p->name; ++p) {
@ -136,21 +120,6 @@ const char *mp_imgfmt_to_name(unsigned int fmt)
return NULL;
}
static int comp_bit_order(const AVPixFmtDescriptor *pd, int bpp, int c)
{
int el_size = (pd->flags & PIX_FMT_BITSTREAM) ? 1 : 8;
// NOTE: offset_plus1 can be 0
int offset = (((int)pd->comp[c].offset_plus1) - 1) * el_size;
int read_depth = pd->comp[c].shift + pd->comp[c].depth_minus1 + 1;
if (read_depth <= 8 && !(pd->flags & PIX_FMT_BITSTREAM))
offset += 8 * !!(pd->flags & PIX_FMT_BE);
offset += pd->comp[c].shift;
// revert ffmpeg's bullshit hack that mixes byte and bit access
if ((pd->flags & PIX_FMT_BE) && bpp <= 16 && read_depth <= 8)
offset = (8 + offset) % 16;
return offset;
}
static struct mp_imgfmt_desc get_avutil_fmt(enum PixelFormat fmt)
{
const AVPixFmtDescriptor *pd = &av_pix_fmt_descriptors[fmt];
@ -201,11 +170,12 @@ static struct mp_imgfmt_desc get_avutil_fmt(enum PixelFormat fmt)
desc.plane_bits = planedepth[0];
if (!(pd->flags & PIX_FMT_RGB) && !(pd->flags & PIX_FMT_HWACCEL) &&
fmt != PIX_FMT_MONOWHITE && fmt != PIX_FMT_MONOBLACK &&
if (!(pd->flags & PIX_FMT_RGB) && fmt != PIX_FMT_MONOBLACK &&
fmt != PIX_FMT_PAL8)
{
desc.flags |= MP_IMGFLAG_YUV;
} else {
desc.flags |= MP_IMGFLAG_RGB;
}
#ifdef PIX_FMT_ALPHA
@ -229,61 +199,6 @@ static struct mp_imgfmt_desc get_avutil_fmt(enum PixelFormat fmt)
desc.flags |= MP_IMGFLAG_YUV_P;
}
if ((pd->flags & PIX_FMT_RGB) && desc.num_planes == 1
&& pd->nb_components >= 3)
{
// RGB vs. BGR component order, as distinguished by mplayer:
// - for byte accessed formats (RGB24, RGB48), the order of bytes
// determines RGB/BGR (e.g. R is first byte -> RGB)
// - for bit accessed formats (RGB32, RGB16, etc.), the order of bits
// determines BGR/RGB (e.g. R is LSB -> RGB)
// - formats like IMGFMT_RGBA are aliases to allow byte access to bit-
// accessed formats (IMGFMT_RGBA is RGB32 on LE, BGR32|128 on BE)
// (ffmpeg does it the other way around, and defines bit-access
// aliases to byte-accessed formats)
int b = desc.bpp[0];
bool swap = comp_bit_order(pd, b, 0) > comp_bit_order(pd, b, 1);
if ((desc.bpp[0] == 24 || desc.bpp[0] > 32) && BYTE_ORDER == BIG_ENDIAN)
swap = !swap; // byte accessed
if (swap)
desc.flags |= MP_IMGFLAG_SWAPPED;
}
// compatibility with old mp_image_setfmt()
switch (desc.id) {
case IMGFMT_UYVY:
desc.flags |= MP_IMGFLAG_SWAPPED; // for vf_mpi_clear()
/* fallthrough */
case IMGFMT_YUYV:
desc.chroma_ys = 1; // ???
break;
case IMGFMT_Y8:
case IMGFMT_Y16_LE:
case IMGFMT_Y16_BE:
// probably for vo_opengl, and possibly more code using Y8
desc.chroma_xs = desc.chroma_ys = 31;
break;
case IMGFMT_NV12:
desc.flags |= MP_IMGFLAG_SWAPPED; // completely pointless
/* fallthrough */
case IMGFMT_NV21:
// some hack to make cropping code etc. work? (doesn't work anyway)
desc.chroma_xs = 0;
desc.chroma_ys = 1;
break;
case IMGFMT_RGB4:
case IMGFMT_BGR4:
desc.flags ^= MP_IMGFLAG_SWAPPED; // ???
break;
case IMGFMT_BGR0:
desc.flags &= ~MP_IMGFLAG_SWAPPED; // not covered by IS_RGB/IS_BGR
break;
}
if (pd->flags & PIX_FMT_HWACCEL)
desc.chroma_xs = desc.chroma_ys = 0;
if (!(pd->flags & PIX_FMT_HWACCEL) && !(pd->flags & PIX_FMT_BITSTREAM)) {
desc.flags |= MP_IMGFLAG_BYTE_ALIGNED;
for (int p = 0; p < desc.num_planes; p++)

View File

@ -39,13 +39,14 @@
#define MP_IMGFLAG_PLANAR 0x100
// set if it's YUV colorspace
#define MP_IMGFLAG_YUV 0x200
// set if it's swapped (BGR or YVU) plane/byteorder
#define MP_IMGFLAG_SWAPPED 0x400
// set if it's RGB colorspace
#define MP_IMGFLAG_RGB 0x400
// set if the format is in a standard YUV format:
// - planar and yuv colorspace
// - chroma shift 0-2
// - 1-4 planes (1: gray, 2: gray/alpha, 3: yuv, 4: yuv/alpha)
// - 8-16 bit per pixel/plane, all planes have same depth
// - 8-16 bit per pixel/plane, all planes have same depth,
// each plane has exactly one component
#define MP_IMGFLAG_YUV_P 0x1000
// set if in little endian, or endian independent
#define MP_IMGFLAG_LE 0x2000
@ -240,51 +241,16 @@ enum mp_imgfmt {
static inline bool IMGFMT_IS_RGB(unsigned int fmt)
{
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
return !(desc.flags & MP_IMGFLAG_YUV) && !(desc.flags & MP_IMGFLAG_SWAPPED)
&& desc.num_planes == 1 && desc.id != IMGFMT_BGR0;
}
static inline bool IMGFMT_IS_BGR(unsigned int fmt)
{
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
return !(desc.flags & MP_IMGFLAG_YUV) && (desc.flags & MP_IMGFLAG_SWAPPED)
&& desc.num_planes == 1 && desc.id != IMGFMT_BGR0;
return (desc.flags & MP_IMGFLAG_RGB) && desc.num_planes == 1;
}
#define IMGFMT_RGB_DEPTH(fmt) (mp_imgfmt_get_desc(fmt).plane_bits)
#define IMGFMT_BGR_DEPTH(fmt) (mp_imgfmt_get_desc(fmt).plane_bits)
#if BYTE_ORDER == BIG_ENDIAN
#define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_BE(fmt)
#else
#define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_LE(fmt)
#endif
// These functions are misnamed - they actually match 9 to 16 bits (inclusive)
static inline bool IMGFMT_IS_YUVP16_LE(int fmt) {
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
return (desc.flags & MP_IMGFLAG_YUV_P) && desc.plane_bits > 8 &&
(desc.flags & MP_IMGFLAG_LE);
}
static inline bool IMGFMT_IS_YUVP16_BE(int fmt) {
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
return (desc.flags & MP_IMGFLAG_YUV_P) && desc.plane_bits > 8 &&
(desc.flags & MP_IMGFLAG_BE);
}
#define IMGFMT_IS_YUVP16(fmt) (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt))
#define IMGFMT_IS_VDPAU(fmt) \
(((fmt) >= IMGFMT_VDPAU_FIRST) && ((fmt) <= IMGFMT_VDPAU_LAST))
#define IMGFMT_IS_HWACCEL(fmt) IMGFMT_IS_VDPAU(fmt)
/**
* Calculates the scale shifts for the chroma planes for planar YUV
*
* \param component_bits bits per component
* \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise
*/
int mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits);
struct mp_imgfmt_entry {
const char *name;

View File

@ -368,17 +368,13 @@ void mp_image_clear(struct mp_image *mpi, int x0, int y0, int w, int h)
#define CLEAR_PACKEDYUV_PATTERN 0x80008000
#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080
#endif
if (mpi->flags & MP_IMGFLAG_SWAPPED) {
for (i = 0; i < size - 3; i += 4)
p[i] = p[i + 1] = p[i + 2] = p[i + 3] = CLEAR_PACKEDYUV_PATTERN_SWAPPED;
for (; i < size; i++)
p[i] = CLEAR_PACKEDYUV_PATTERN_SWAPPED;
} else {
for (i = 0; i < size - 3; i += 4)
p[i] = p[i + 1] = p[i + 2] = p[i + 3] = CLEAR_PACKEDYUV_PATTERN;
for (; i < size; i++)
p[i] = CLEAR_PACKEDYUV_PATTERN;
}
int clear = CLEAR_PACKEDYUV_PATTERN;
if (mpi->imgfmt == IMGFMT_UYVY)
clear = CLEAR_PACKEDYUV_PATTERN_SWAPPED;
for (i = 0; i < size - 3; i += 4)
p[i] = p[i + 1] = p[i + 2] = p[i + 3] = clear;
for (; i < size; i++)
p[i] = clear;
} else
memset(dst, 0, (mpi->bpp >> 3) * w);
}

View File

@ -110,7 +110,7 @@ void glAdjustAlignment(GL *gl, int stride)
*
* All parameters may be NULL.
* \param fmt MPlayer format to analyze.
* \param bpp [OUT] bits per pixel of that format.
* \param dummy reserved
* \param gl_texfmt [OUT] internal texture format that fits the
* image format, not necessarily the best for performance.
* \param gl_format [OUT] OpenGL format for this image format.
@ -118,15 +118,12 @@ void glAdjustAlignment(GL *gl, int stride)
* \return 1 if format is supported by OpenGL, 0 if not.
* \ingroup gltexture
*/
int glFindFormat(uint32_t fmt, int have_texture_rg, int *bpp, GLint *gl_texfmt,
int glFindFormat(uint32_t fmt, int have_texture_rg, int *dummy, GLint *gl_texfmt,
GLenum *gl_format, GLenum *gl_type)
{
int supported = 1;
int dummy1;
GLenum dummy2;
GLint dummy3;
if (!bpp)
bpp = &dummy1;
if (!gl_texfmt)
gl_texfmt = &dummy3;
if (!gl_format)
@ -134,17 +131,15 @@ int glFindFormat(uint32_t fmt, int have_texture_rg, int *bpp, GLint *gl_texfmt,
if (!gl_type)
gl_type = &dummy2;
if (mp_get_chroma_shift(fmt, NULL, NULL, NULL)) {
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
if (desc.flags & MP_IMGFLAG_YUV_P) {
// 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;
if (desc.plane_bits > 8)
fmt = IMGFMT_420P16;
else
fmt = IMGFMT_420P;
}
*bpp = IMGFMT_IS_BGR(fmt) ? IMGFMT_BGR_DEPTH(fmt) : IMGFMT_RGB_DEPTH(fmt);
*gl_texfmt = 3;
switch (fmt) {
case IMGFMT_RGB48:
@ -163,7 +158,6 @@ int glFindFormat(uint32_t fmt, int have_texture_rg, int *bpp, GLint *gl_texfmt,
case IMGFMT_420P16:
supported = 0; // no native YUV support
*gl_texfmt = have_texture_rg ? GL_R16 : GL_LUMINANCE16;
*bpp = 16;
*gl_format = have_texture_rg ? GL_RED : GL_LUMINANCE;
*gl_type = GL_UNSIGNED_SHORT;
break;
@ -171,13 +165,11 @@ int glFindFormat(uint32_t fmt, int have_texture_rg, int *bpp, GLint *gl_texfmt,
supported = 0; // no native YV12 support
case IMGFMT_Y8:
*gl_texfmt = 1;
*bpp = 8;
*gl_format = GL_LUMINANCE;
*gl_type = GL_UNSIGNED_BYTE;
break;
case IMGFMT_UYVY:
*gl_texfmt = GL_YCBCR_MESA;
*bpp = 16;
*gl_format = GL_YCBCR_MESA;
*gl_type = fmt == IMGFMT_UYVY ? GL_UNSIGNED_SHORT_8_8 : GL_UNSIGNED_SHORT_8_8_REV;
break;

View File

@ -961,14 +961,12 @@ static int get_chroma_clear_val(int bit_depth)
// this macro is supposed to work on all formats supported by 3D rendering, and
// that produce "reasonable" output (i.e. no mixed up colors)
#define IMGFMT_IS_ANY_RND(x) \
(IMGFMT_IS_BGR(x) || IMGFMT_IS_RGB(x) || IMGFMT_IS_Y(x))
(IMGFMT_IS_RGB(x) || IMGFMT_IS_Y(x))
// pixel size in bit for any IMGFMT_IS_ANY_RND(x)==true
// we assume that the actual pixel strides are always aligned on bytes
static int imgfmt_any_rnd_depth(int fmt)
{
if (IMGFMT_IS_BGR(fmt))
return IMGFMT_BGR_DEPTH(fmt);
if (IMGFMT_IS_RGB(fmt))
return IMGFMT_RGB_DEPTH(fmt);
if (IMGFMT_IS_Y(fmt))
@ -1033,9 +1031,12 @@ static D3DFORMAT check_shader_conversion(d3d_priv *priv, uint32_t fmt)
{
if (priv->opt_disable_shaders)
return 0;
int component_bits;
if (!mp_get_chroma_shift(fmt, NULL, NULL, &component_bits))
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
if (!(desc.flags & MP_IMGFLAG_YUV_P) || !(desc.flags & MP_IMGFLAG_NE))
return 0;
if (desc.num_planes != 3)
return 0;
int component_bits = desc.plane_bits;
if (component_bits < 8 || component_bits > 16)
return 0;
bool is_8bit = component_bits == 8;
@ -1116,17 +1117,15 @@ static bool init_rendering_mode(d3d_priv *priv, uint32_t fmt, bool initialize)
} else {
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Using YUV shaders.\n");
int sx, sy, component_bits;
mp_get_chroma_shift(priv->image_format, &sx, &sy, &component_bits);
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(priv->image_format);
priv->plane_count = 3;
for (n = 0; n < 3; n++) {
planes[n].d3d_format = shader_d3dfmt;
planes[n].bits_per_pixel = component_bits;
if (n > 0) {
planes[n].shift_x = sx;
planes[n].shift_y = sy;
planes[n].clearval = get_chroma_clear_val(component_bits);
}
planes[n].bits_per_pixel = desc.plane_bits;
planes[n].shift_x = desc.xs[n];
planes[n].shift_y = desc.ys[n];
if (n > 0)
planes[n].clearval = get_chroma_clear_val(desc.plane_bits);
}
if (shader_d3dfmt != D3DFMT_A8L8) {
priv->pixel_shader_data = d3d_shader_yuv;

View File

@ -1558,17 +1558,19 @@ static bool init_format(int fmt, struct gl_priv *init)
if (!init)
init = &dummy;
mp_image_t dummy_img = {0};
mp_image_setfmt(&dummy_img, fmt);
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
if (!desc.id)
return false;
init->image_format = fmt;
init->component_bits = -1;
init->plane_bits = desc.plane_bits;
// RGB/packed formats
for (const struct fmt_entry *e = mp_to_gl_formats; e->mp_format; e++) {
if (e->mp_format == fmt) {
supported = true;
init->plane_bits = dummy_img.bpp;
init->plane_bits = desc.bpp[0];
init->gl_format = e->format;
init->gl_internal_format = e->internal_format;
init->component_bits = e->component_bits;
@ -1578,14 +1580,14 @@ static bool init_format(int fmt, struct gl_priv *init)
}
// YUV/planar formats
if (!supported && mp_get_chroma_shift(fmt, NULL, NULL, &init->plane_bits)) {
if (!supported && (desc.flags & MP_IMGFLAG_YUV_P)) {
init->gl_format = GL_RED;
init->component_bits = init->plane_bits;
if (init->plane_bits == 8) {
supported = true;
init->gl_internal_format = GL_RED;
init->gl_type = GL_UNSIGNED_BYTE;
} else if (IMGFMT_IS_YUVP16_NE(fmt)) {
} else if (init->plane_bits <= 16 && (desc.flags & MP_IMGFLAG_NE)) {
supported = true;
init->gl_internal_format = GL_R16;
init->gl_type = GL_UNSIGNED_SHORT;
@ -1605,19 +1607,19 @@ static bool init_format(int fmt, struct gl_priv *init)
return false;
init->plane_bytes = (init->plane_bits + 7) / 8;
init->is_yuv = dummy_img.flags & MP_IMGFLAG_YUV;
init->is_yuv = desc.flags & MP_IMGFLAG_YUV;
init->is_linear_rgb = false;
// NOTE: we throw away the additional alpha plane, if one exists.
init->plane_count = dummy_img.num_planes > 2 ? 3 : 1;
assert(dummy_img.num_planes >= init->plane_count);
assert(dummy_img.num_planes <= init->plane_count + 1);
init->plane_count = desc.num_planes > 2 ? 3 : 1;
assert(desc.num_planes >= init->plane_count);
assert(desc.num_planes <= init->plane_count + 1);
for (int n = 0; n < init->plane_count; n++) {
struct texplane *plane = &init->planes[n];
plane->shift_x = n > 0 ? dummy_img.chroma_x_shift : 0;
plane->shift_y = n > 0 ? dummy_img.chroma_y_shift : 0;
plane->shift_x = desc.xs[n];
plane->shift_y = desc.ys[n];
}
return true;

View File

@ -169,7 +169,6 @@ static void update_yuvconv(struct vo *vo)
struct gl_priv *p = vo->priv;
GL *gl = p->gl;
int xs, ys, depth;
struct mp_csp_params cparams = { .colorspace = p->colorspace };
mp_csp_copy_equalizer_values(&cparams, &p->video_eq);
gl_conversion_params_t params = {
@ -177,9 +176,10 @@ static void update_yuvconv(struct vo *vo)
p->texture_width, p->texture_height, 0, 0, p->filter_strength,
p->noise_strength
};
mp_get_chroma_shift(p->image_format, &xs, &ys, &depth);
params.chrom_texw = params.texw >> xs;
params.chrom_texh = params.texh >> ys;
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->image_format);
int depth = desc.plane_bits;
params.chrom_texw = params.texw >> desc.chroma_xs;
params.chrom_texh = params.texh >> desc.chroma_ys;
params.csp_params.input_bits = depth;
params.csp_params.texture_bits = depth+7 & ~7;
glSetupYUVConversion(gl, &params);
@ -427,10 +427,10 @@ static int initGl(struct vo *vo, uint32_t d_width, uint32_t d_height)
gl->TexParameteri(p->target, GL_GENERATE_MIPMAP, GL_TRUE);
if (p->is_yuv) {
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->image_format);
int i;
int xs, ys, depth;
int xs = desc.chroma_xs, ys = desc.chroma_ys, depth = desc.plane_bits;
scale_type = get_scale_type(vo, 1);
mp_get_chroma_shift(p->image_format, &xs, &ys, &depth);
int clear = get_chroma_clear_val(depth);
gl->GenTextures(21, p->default_texs);
p->default_texs[21] = 0;
@ -502,12 +502,15 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
{
struct gl_priv *p = vo->priv;
int xs, ys;
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(format);
p->image_height = height;
p->image_width = width;
p->image_format = format;
p->is_yuv = mp_get_chroma_shift(p->image_format, &xs, &ys, NULL) > 0;
p->is_yuv |= (xs << 8) | (ys << 16);
p->is_yuv = !!(desc.flags & MP_IMGFLAG_YUV_P);
p->is_yuv |= (desc.chroma_xs << 8) | (desc.chroma_ys << 16);
if (format == IMGFMT_Y8)
p->is_yuv = 0;
glFindFormat(format, p->have_texture_rg, NULL, &p->texfmt, &p->gl_format,
&p->gl_type);
@ -630,9 +633,9 @@ static bool get_image(struct vo *vo, mp_image_t *mpi, int *th, bool *cplane)
}
if (p->is_yuv) {
// planar YUV
int xs, ys, component_bits;
mp_get_chroma_shift(p->image_format, &xs, &ys, &component_bits);
int bp = (component_bits + 7) / 8;
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->image_format);
int xs = desc.chroma_xs, ys = desc.chroma_ys, depth = desc.plane_bits;
int bp = (depth + 7) / 8;
common_plane = true;
mpi->stride[0] = width * bp;
mpi->planes[1] = mpi->planes[0] + mpi->stride[0] * height;
@ -702,11 +705,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
if (p->force_pbo && !p->bufferptr
&& get_image(vo, &mpi2, &th, &common_plane))
{
int bp = mpi->bpp / 8;
int xs, ys, component_bits;
mp_get_chroma_shift(p->image_format, &xs, &ys, &component_bits);
if (p->is_yuv)
bp = (component_bits + 7) / 8;
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->image_format);
int bp = desc.bytes[0];
int xs = desc.chroma_xs, ys = desc.chroma_ys, depth = desc.plane_bits;
memcpy_pic(mpi2.planes[0], mpi->planes[0], mpi->w * bp, mpi->h,
mpi2.stride[0], mpi->stride[0]);
int uv_bytes = (mpi->w >> xs) * bp;
@ -721,7 +722,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
clear_border(vo, mpi2.planes[0], mpi->w * bp, mpi2.stride[0],
mpi->h, th, 0);
if (p->is_yuv) {
int clear = get_chroma_clear_val(component_bits);
int clear = get_chroma_clear_val(depth);
clear_border(vo, mpi2.planes[1], uv_bytes, mpi2.stride[1],
mpi->h >> ys, th >> ys, clear);
clear_border(vo, mpi2.planes[2], uv_bytes, mpi2.stride[2],
@ -759,8 +760,8 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
glUploadTex(gl, p->target, p->gl_format, p->gl_type, planes[0],
stride[0], 0, 0, w, h, slice);
if (p->is_yuv) {
int xs, ys;
mp_get_chroma_shift(p->image_format, &xs, &ys, NULL);
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->image_format);
int xs = desc.chroma_xs, ys = desc.chroma_ys;
if (pbo && !common_plane) {
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, p->buffer_uv[0]);
gl->UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@ -818,16 +819,18 @@ static int query_format(struct vo *vo, uint32_t format)
{
struct gl_priv *p = vo->priv;
int depth;
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(format);
int depth = desc.plane_bits;
int caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIP;
if (p->use_osd)
caps |= VFCAP_OSD;
if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA)
return caps;
if (p->use_yuv && mp_get_chroma_shift(format, NULL, NULL, &depth) &&
if (p->use_yuv && (desc.flags & MP_IMGFLAG_YUV_P) &&
(depth == 8 || depth == 16 ||
p->max_tex_component_size >= 16 && glYUVLargeRange(p->use_yuv)) &&
(IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
(depth <= 16 && (desc.flags & MP_IMGFLAG_NE)))
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

View File

@ -524,15 +524,17 @@ static int query_format(struct vo *vo, uint32_t format)
mp_msg(MSGT_VO, MSGL_DBG2,
"vo_x11: query_format was called: %x (%s)\n", format,
vo_format_name(format));
if (IMGFMT_IS_BGR(format)) {
if (IMGFMT_BGR_DEPTH(format) < 8)
return 0;
if (IMGFMT_BGR_DEPTH(format) == vo->x11->depthonscreen)
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
VFCAP_OSD | VFCAP_FLIP;
else
return VFCAP_CSP_SUPPORTED | VFCAP_OSD |
VFCAP_FLIP;
if (IMGFMT_IS_RGB(format)) {
for (int n = 0; fmt2Xfmt[n].mpfmt; n++) {
if (fmt2Xfmt[n].mpfmt == format) {
if (IMGFMT_RGB_DEPTH(format) == vo->x11->depthonscreen) {
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
VFCAP_OSD | VFCAP_FLIP;
} else {
return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_FLIP;
}
}
}
}
switch (format) {