mirror of
https://github.com/mpv-player/mpv
synced 2025-02-18 13:47:04 +00:00
Support all planar YUV formats in OpenGL vos.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30139 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
92f20f876f
commit
8e35068138
@ -234,6 +234,10 @@ 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;
|
||||
|
||||
*bpp = IMGFMT_IS_BGR(fmt)?IMGFMT_BGR_DEPTH(fmt):IMGFMT_RGB_DEPTH(fmt);
|
||||
*gl_texfmt = 3;
|
||||
switch (fmt) {
|
||||
@ -1323,9 +1327,9 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) {
|
||||
add_scaler(YUV_LUM_SCALER(type), &prog_pos, &prog_remain, lum_scale_texs,
|
||||
'0', 'r', rect, texw, texh, params->filter_strength);
|
||||
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
|
||||
'1', 'g', rect, texw / 2, texh / 2, params->filter_strength);
|
||||
'1', 'g', rect, params->chrom_texw, params->chrom_texh, params->filter_strength);
|
||||
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
|
||||
'2', 'b', rect, texw / 2, texh / 2, params->filter_strength);
|
||||
'2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength);
|
||||
get_yuv2rgb_coeffs(params, yuv2rgb);
|
||||
switch (YUV_CONVERSION(type)) {
|
||||
case YUV_CONVERSION_FRAGMENT:
|
||||
@ -1496,14 +1500,19 @@ void glDisableYUVConversion(GLenum target, int type) {
|
||||
* \param sx width of texture in pixels
|
||||
* \param sy height of texture in pixels
|
||||
* \param rect_tex whether this texture uses texture_rectangle extension
|
||||
* \param is_yv12 if set, also draw the textures from units 1 and 2
|
||||
* \param is_yv12 if != 0, also draw the textures from units 1 and 2,
|
||||
* bits 8 - 15 and 16 - 23 specify the x and y scaling of those textures
|
||||
* \param flip flip the texture upside down
|
||||
* \ingroup gltexture
|
||||
*/
|
||||
void glDrawTex(GLfloat x, GLfloat y, GLfloat w, GLfloat h,
|
||||
GLfloat tx, GLfloat ty, GLfloat tw, GLfloat th,
|
||||
int sx, int sy, int rect_tex, int is_yv12, int flip) {
|
||||
GLfloat tx2 = tx / 2, ty2 = ty / 2, tw2 = tw / 2, th2 = th / 2;
|
||||
int chroma_x_shift = (is_yv12 >> 8) & 31;
|
||||
int chroma_y_shift = (is_yv12 >> 16) & 31;
|
||||
GLfloat xscale = 1 << chroma_x_shift;
|
||||
GLfloat yscale = 1 << chroma_y_shift;
|
||||
GLfloat tx2 = tx / xscale, ty2 = ty / yscale, tw2 = tw / xscale, th2 = th / yscale;
|
||||
if (!rect_tex) {
|
||||
tx /= sx; ty /= sy; tw /= sx; th /= sy;
|
||||
tx2 = tx, ty2 = ty, tw2 = tw, th2 = th;
|
||||
|
@ -339,6 +339,8 @@ typedef struct {
|
||||
float bgamma;
|
||||
int texw;
|
||||
int texh;
|
||||
int chrom_texw;
|
||||
int chrom_texh;
|
||||
float filter_strength;
|
||||
} gl_conversion_params_t;
|
||||
|
||||
|
@ -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(¶ms);
|
||||
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;
|
||||
|
@ -88,6 +88,7 @@ static int isGL12 = GL_FALSE;
|
||||
static int gl_bilinear=1;
|
||||
static int gl_antialias=0;
|
||||
static int use_yuv;
|
||||
static int is_yuv;
|
||||
static int use_glFinish;
|
||||
|
||||
static void (*draw_alpha_fnc)
|
||||
@ -184,7 +185,7 @@ static int initTextures(void)
|
||||
s*=2;
|
||||
texture_height=s;
|
||||
|
||||
if (image_format != IMGFMT_YV12)
|
||||
if (!is_yuv)
|
||||
gl_internal_format = getInternalFormat();
|
||||
|
||||
/* Test the max texture size */
|
||||
@ -263,7 +264,7 @@ static int initTextures(void)
|
||||
glGenTextures (1, &(tsq->texobj));
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, tsq->texobj);
|
||||
if (image_format == IMGFMT_YV12) {
|
||||
if (is_yuv) {
|
||||
glGenTextures(2, tsq->uvtexobjs);
|
||||
ActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]);
|
||||
@ -276,13 +277,15 @@ static int initTextures(void)
|
||||
texture_width, texture_height, 0);
|
||||
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
if (image_format == IMGFMT_YV12) {
|
||||
if (is_yuv) {
|
||||
int xs, ys;
|
||||
mp_get_chroma_shift(image_format, &xs, &ys);
|
||||
ActiveTexture(GL_TEXTURE1);
|
||||
glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR,
|
||||
texture_width / 2, texture_height / 2, 128);
|
||||
texture_width >> xs, texture_height >> ys, 128);
|
||||
ActiveTexture(GL_TEXTURE2);
|
||||
glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR,
|
||||
texture_width / 2, texture_height / 2, 128);
|
||||
texture_width >> xs, texture_height >> ys, 128);
|
||||
ActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
@ -381,7 +384,7 @@ static void drawTextureDisplay (void)
|
||||
|
||||
glColor3f(1.0,1.0,1.0);
|
||||
|
||||
if (image_format == IMGFMT_YV12)
|
||||
if (is_yuv)
|
||||
glEnableYUVConversion(GL_TEXTURE_2D, use_yuv);
|
||||
for (y = 0; y < texnumy; y++) {
|
||||
int thish = texture_height;
|
||||
@ -392,7 +395,7 @@ static void drawTextureDisplay (void)
|
||||
if (x == texnumx - 1 && image_width % texture_width)
|
||||
thisw = image_width % texture_width;
|
||||
glBindTexture (GL_TEXTURE_2D, square->texobj);
|
||||
if (image_format == IMGFMT_YV12) {
|
||||
if (is_yuv) {
|
||||
ActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]);
|
||||
ActiveTexture(GL_TEXTURE2);
|
||||
@ -409,11 +412,11 @@ static void drawTextureDisplay (void)
|
||||
glDrawTex(square->fx, square->fy, square->fw, square->fh,
|
||||
0, 0, texture_width, texture_height,
|
||||
texture_width, texture_height,
|
||||
0, image_format == IMGFMT_YV12, 0);
|
||||
0, is_yuv, 0);
|
||||
square++;
|
||||
} /* for all texnumx */
|
||||
} /* for all texnumy */
|
||||
if (image_format == IMGFMT_YV12)
|
||||
if (is_yuv)
|
||||
glDisableYUVConversion(GL_TEXTURE_2D, use_yuv);
|
||||
texdirty = 0;
|
||||
}
|
||||
@ -565,10 +568,11 @@ static int initGl(uint32_t d_width, uint32_t d_height)
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
if (image_format == IMGFMT_YV12) {
|
||||
if (is_yuv) {
|
||||
int xs, ys;
|
||||
gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv,
|
||||
0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
|
||||
texture_width, texture_height};
|
||||
texture_width, texture_height, 0, 0, 0};
|
||||
switch (use_yuv) {
|
||||
case YUV_CONVERSION_FRAGMENT_LOOKUP:
|
||||
glGenTextures(1, &lookupTex);
|
||||
@ -586,6 +590,9 @@ static int initGl(uint32_t d_width, uint32_t d_height)
|
||||
BindProgram(GL_FRAGMENT_PROGRAM, fragprog);
|
||||
break;
|
||||
}
|
||||
mp_get_chroma_shift(image_format, &xs, &ys);
|
||||
params.chrom_texw = params.texw >> xs;
|
||||
params.chrom_texh = params.texh >> ys;
|
||||
glSetupYUVConversion(¶ms);
|
||||
}
|
||||
|
||||
@ -613,11 +620,14 @@ 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;
|
||||
const unsigned char * glVersion;
|
||||
|
||||
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);
|
||||
|
||||
int_pause = 0;
|
||||
|
||||
@ -750,6 +760,8 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
|
||||
int rem_h = h;
|
||||
struct TexSquare *texline = &texgrid[y / texture_height * texnumx];
|
||||
int subtex_y = y % texture_width;
|
||||
int xs, ys;
|
||||
mp_get_chroma_shift(image_format, &xs, &ys);
|
||||
while (rem_h > 0) {
|
||||
int rem_w = w;
|
||||
struct TexSquare *tsq = &texline[x / texture_width];
|
||||
@ -769,24 +781,24 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
|
||||
ActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[0]);
|
||||
glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type,
|
||||
uptr, ustride, subtex_x / 2, subtex_y / 2,
|
||||
subtex_w / 2, subtex_h / 2, 0);
|
||||
uptr, ustride, subtex_x >> xs, subtex_y >> ys,
|
||||
subtex_w >> xs, subtex_h >> ys, 0);
|
||||
ActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[1]);
|
||||
glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type,
|
||||
vptr, vstride, subtex_x / 2, subtex_y / 2,
|
||||
subtex_w / 2, subtex_h / 2, 0);
|
||||
vptr, vstride, subtex_x >> xs, subtex_y >> ys,
|
||||
subtex_w >> xs, subtex_h >> ys, 0);
|
||||
subtex_x = 0;
|
||||
yptr += subtex_w;
|
||||
uptr += subtex_w / 2;
|
||||
vptr += subtex_w / 2;
|
||||
uptr += subtex_w >> xs;
|
||||
vptr += subtex_w >> xs;
|
||||
tsq++;
|
||||
rem_w -= subtex_w;
|
||||
}
|
||||
subtex_y = 0;
|
||||
yptr += subtex_h * ystride - w;
|
||||
uptr += subtex_h / 2 * ustride - w / 2;
|
||||
vptr += subtex_h / 2 * vstride - w / 2;
|
||||
uptr += (subtex_h >> ys) * ustride - (w >> xs);
|
||||
vptr += (subtex_h >> ys) * vstride - (w >> xs);
|
||||
texline += texnumx;
|
||||
rem_h -= subtex_h;
|
||||
}
|
||||
@ -797,7 +809,7 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
|
||||
static int
|
||||
draw_frame(uint8_t *src[])
|
||||
{
|
||||
if (image_format == IMGFMT_YV12) {
|
||||
if (is_yuv) {
|
||||
mp_msg(MSGT_VO, MSGL_ERR, "[gl2] error: draw_frame called for YV12!\n");
|
||||
return 0;
|
||||
}
|
||||
@ -810,12 +822,10 @@ draw_frame(uint8_t *src[])
|
||||
static int
|
||||
query_format(uint32_t format)
|
||||
{
|
||||
if (use_yuv && mp_get_chroma_shift(format, NULL, NULL))
|
||||
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
|
||||
VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
|
||||
switch(format) {
|
||||
case IMGFMT_YV12:
|
||||
if (use_yuv)
|
||||
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
|
||||
VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
|
||||
break;
|
||||
#ifdef __APPLE__
|
||||
case IMGFMT_RGB32:
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user