summaryrefslogtreecommitdiffstats
path: root/libvo/vo_gl.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-12-30 11:32:24 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-12-30 11:32:24 +0000
commit8e35068138e7e6398c03b6b38a69be9aaef426c7 (patch)
tree335c8b3999441654916fd8b6ca4701888ab2aa40 /libvo/vo_gl.c
parent92f20f876f7efac016d9b69aa01fe3d2f0fc6f68 (diff)
downloadmpv-8e35068138e7e6398c03b6b38a69be9aaef426c7.tar.bz2
mpv-8e35068138e7e6398c03b6b38a69be9aaef426c7.tar.xz
Support all planar YUV formats in OpenGL vos.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30139 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo/vo_gl.c')
-rw-r--r--libvo/vo_gl.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 5ea2c3c726..058cfb614f 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -93,6 +93,7 @@ static int use_ycbcr;
#define MASK_NOT_COMBINERS (~((1 << YUV_CONVERSION_NONE) | (1 << YUV_CONVERSION_COMBINERS) | (1 << YUV_CONVERSION_COMBINERS_ATI)))
#define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT))
static int use_yuv;
+static int is_yuv;
static int lscale;
static int cscale;
static float filter_strength;
@@ -206,6 +207,7 @@ static void texSize(int w, int h, int *texw, int *texh) {
//! maximum size of custom fragment program
#define MAX_CUSTOM_PROG_SIZE (1024 * 1024)
static void update_yuvconv(void) {
+ int xs, ys;
float bri = eq_bri / 100.0;
float cont = (eq_cont + 100) / 100.0;
float hue = eq_hue / 100.0 * 3.1415927;
@@ -215,7 +217,10 @@ static void update_yuvconv(void) {
float bgamma = exp(log(8.0) * eq_bgamma / 100.0);
gl_conversion_params_t params = {gl_target, yuvconvtype,
bri, cont, hue, sat, rgamma, ggamma, bgamma,
- texture_width, texture_height, filter_strength};
+ texture_width, texture_height, 0, 0, filter_strength};
+ mp_get_chroma_shift(image_format, &xs, &ys);
+ params.chrom_texw = params.texw >> xs;
+ params.chrom_texh = params.texh >> ys;
glSetupYUVConversion(&params);
if (custom_prog) {
FILE *f = fopen(custom_prog, "r");
@@ -478,8 +483,10 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
texture_width, texture_height);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
GenTextures(21, default_texs);
default_texs[21] = 0;
for (i = 0; i < 7; i++) {
@@ -490,18 +497,18 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
}
ActiveTexture(GL_TEXTURE1);
glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
if (mipmap_gen)
TexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE);
ActiveTexture(GL_TEXTURE2);
glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
if (mipmap_gen)
TexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE);
ActiveTexture(GL_TEXTURE0);
BindTexture(gl_target, 0);
}
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
{
if ((MASK_NOT_COMBINERS & (1 << use_yuv)) || custom_prog) {
if (!GenPrograms || !BindProgram) {
@@ -533,9 +540,12 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
static int
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
{
+ int xs, ys;
image_height = height;
image_width = width;
image_format = format;
+ is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+ is_yuv |= (xs << 8) | (ys << 16);
glFindFormat(format, NULL, &gl_texfmt, &gl_format, &gl_type);
int_pause = 0;
@@ -712,14 +722,14 @@ static void do_render(void) {
// BindTexture(GL_TEXTURE_2D, texture_id);
Color3f(1,1,1);
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
glEnableYUVConversion(gl_target, yuvconvtype);
glDrawTex(0, 0, image_width, image_height,
0, 0, image_width, image_height,
texture_width, texture_height,
- use_rectangle == 1, image_format == IMGFMT_YV12,
+ use_rectangle == 1, is_yuv,
mpi_flipped ^ vo_flipped);
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
glDisableYUVConversion(gl_target, yuvconvtype);
}
@@ -748,13 +758,15 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
mpi_flipped = stride[0] < 0;
glUploadTex(gl_target, gl_format, gl_type, src[0], stride[0],
x, y, w, h, slice_height);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
ActiveTexture(GL_TEXTURE1);
glUploadTex(gl_target, gl_format, gl_type, src[1], stride[1],
- x / 2, y / 2, w / 2, h / 2, slice_height);
+ x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
ActiveTexture(GL_TEXTURE2);
glUploadTex(gl_target, gl_format, gl_type, src[2], stride[2],
- x / 2, y / 2, w / 2, h / 2, slice_height);
+ x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
ActiveTexture(GL_TEXTURE0);
}
return 0;
@@ -812,14 +824,16 @@ static uint32_t get_image(mp_image_t *mpi) {
err_shown = 1;
return VO_FALSE;
}
- if (mpi->imgfmt == IMGFMT_YV12) {
- // YV12
+ if (is_yuv) {
+ // planar YUV
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
mpi->flags |= MP_IMGFLAG_COMMON_STRIDE | MP_IMGFLAG_COMMON_PLANE;
mpi->stride[0] = mpi->width;
mpi->planes[1] = mpi->planes[0] + mpi->stride[0] * mpi->height;
- mpi->stride[1] = mpi->width >> 1;
- mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> 1);
- mpi->stride[2] = mpi->width >> 1;
+ mpi->stride[1] = mpi->width >> xs;
+ mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> ys);
+ mpi->stride[2] = mpi->width >> xs;
if (ati_hack && !mesa_buffer) {
mpi->flags &= ~MP_IMGFLAG_COMMON_PLANE;
if (!gl_buffer_uv[0]) GenBuffers(2, gl_buffer_uv);
@@ -869,17 +883,19 @@ static uint32_t draw_image(mp_image_t *mpi) {
mpi2.flags = 0; mpi2.type = MP_IMGTYPE_TEMP;
mpi2.width = mpi2.w; mpi2.height = mpi2.h;
if (force_pbo && !(mpi->flags & MP_IMGFLAG_DIRECT) && !gl_bufferptr && get_image(&mpi2) == VO_TRUE) {
- int bpp = mpi->imgfmt == IMGFMT_YV12 ? 8 : mpi->bpp;
+ int bpp = is_yuv ? 8 : mpi->bpp;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
memcpy_pic(mpi2.planes[0], mpi->planes[0], mpi->w * bpp / 8, mpi->h, mpi2.stride[0], mpi->stride[0]);
- if (mpi->imgfmt == IMGFMT_YV12) {
- memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> 1, mpi->h >> 1, mpi2.stride[1], mpi->stride[1]);
- memcpy_pic(mpi2.planes[2], mpi->planes[2], mpi->w >> 1, mpi->h >> 1, mpi2.stride[2], mpi->stride[2]);
+ if (is_yuv) {
+ memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> xs, mpi->h >> ys, mpi2.stride[1], mpi->stride[1]);
+ memcpy_pic(mpi2.planes[2], mpi->planes[2], mpi->w >> xs, mpi->h >> ys, mpi2.stride[2], mpi->stride[2]);
}
if (ati_hack) { // since we have to do a full upload we need to clear the borders
clear_border(mpi2.planes[0], mpi->w * bpp / 8, mpi2.stride[0], mpi->h, mpi2.height, 0);
- if (mpi->imgfmt == IMGFMT_YV12) {
- clear_border(mpi2.planes[1], mpi->w >> 1, mpi2.stride[1], mpi->h >> 1, mpi2.height >> 1, 128);
- clear_border(mpi2.planes[2], mpi->w >> 1, mpi2.stride[2], mpi->h >> 1, mpi2.height >> 1, 128);
+ if (is_yuv) {
+ clear_border(mpi2.planes[1], mpi->w >> xs, mpi2.stride[1], mpi->h >> ys, mpi2.height >> ys, 128);
+ clear_border(mpi2.planes[2], mpi->w >> xs, mpi2.stride[2], mpi->h >> ys, mpi2.height >> ys, 128);
}
}
mpi = &mpi2;
@@ -909,7 +925,9 @@ static uint32_t draw_image(mp_image_t *mpi) {
}
glUploadTex(gl_target, gl_format, gl_type, planes[0], stride[0],
mpi->x, mpi->y, w, h, slice);
- if (mpi->imgfmt == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]);
UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -917,7 +935,7 @@ static uint32_t draw_image(mp_image_t *mpi) {
}
ActiveTexture(GL_TEXTURE1);
glUploadTex(gl_target, gl_format, gl_type, planes[1], stride[1],
- mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
+ mpi->x >> xs, mpi->y >> ys, w >> xs, h >> ys, slice);
if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[1]);
UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -925,7 +943,7 @@ static uint32_t draw_image(mp_image_t *mpi) {
}
ActiveTexture(GL_TEXTURE2);
glUploadTex(gl_target, gl_format, gl_type, planes[2], stride[2],
- mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
+ mpi->x >> xs, mpi->y >> ys, w >> xs, h >> ys, slice);
ActiveTexture(GL_TEXTURE0);
}
if (mpi->flags & MP_IMGFLAG_DIRECT) {
@@ -953,7 +971,7 @@ 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 && format == IMGFMT_YV12)
+ if (use_yuv && mp_get_chroma_shift(format, NULL, NULL))
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
@@ -1184,7 +1202,7 @@ static int control(uint32_t request, void *data, ...)
resize(vo_dwidth, vo_dheight);
return VO_TRUE;
case VOCTRL_GET_EQUALIZER:
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
va_list va;
int *value;
@@ -1200,7 +1218,7 @@ static int control(uint32_t request, void *data, ...)
}
break;
case VOCTRL_SET_EQUALIZER:
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
va_list va;
int value;