Mercurial > mplayer.hg
changeset 34983:0034a2bf7b42
Support interleaving the two frame halves from a 3D video
by an arbitrary 4x4 pattern.
This should allow direct playback on some 3D TVs.
author | reimar |
---|---|
date | Sun, 12 Aug 2012 17:15:35 +0000 |
parents | df138f843ebc |
children | c24d1a0c7665 |
files | DOCS/man/en/mplayer.1 libvo/gl_common.c libvo/gl_common.h libvo/vo_gl.c libvo/vo_gl2.c |
diffstat | 5 files changed, 122 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1 Sun Aug 12 13:24:54 2012 +0000 +++ b/DOCS/man/en/mplayer.1 Sun Aug 12 17:15:35 2012 +0000 @@ -4301,7 +4301,16 @@ .IPs 3 Convert side by side input to quadbuffered stereo. Only supported by very few OpenGL cards. -.RE +.IPs 4 +Mix left and right in a pixel pattern. +Pattern is given by stipple option. +.RE +.IPs stipple=<bit pattern> +Lowest 16 bit give the 4x4 pattern to use (default: 0x0f0f). +Examples to try: +0x0f0f, 0xf0f0: horizontal lines; +0xaaaa, 0x5555: vertical lines; +0xa5a5, 0x5a5a: checkerboard pattern .RE .sp 1 .RS
--- a/libvo/gl_common.c Sun Aug 12 13:24:54 2012 +0000 +++ b/libvo/gl_common.c Sun Aug 12 17:15:35 2012 +0000 @@ -1394,7 +1394,7 @@ "TEMP coord, coord2, cdelta, parmx, parmy, a, b, yuv;\n"; int prog_remain; char *yuv_prog, *prog_pos; - int cur_texu = 3; + int cur_texu = 3 + params->has_alpha_tex; char lum_scale_texs[1]; char chrom_scale_texs[1]; char conv_texs[1]; @@ -1486,6 +1486,11 @@ prog_remain -= strlen(prog_pos); prog_pos += strlen(prog_pos); } + if (params->has_alpha_tex) { + snprintf(prog_pos, prog_remain, "TEX result.color.a, fragment.texcoord[3], texture[3], 2D;\n"); + prog_remain -= strlen(prog_pos); + prog_pos += strlen(prog_pos); + } snprintf(prog_pos, prog_remain, "MOV result.color.rgb, res;\nEND"); mp_msg(MSGT_VO, MSGL_DBG2, "[gl] generated fragment program:\n%s\n", yuv_prog); @@ -1634,6 +1639,24 @@ } } +void glSetupAlphaStippleTex(unsigned pattern) { + int i; + uint8_t stipple[16]; + for (i = 0; i < 16; i++) { + stipple[i] = (pattern & 1) * 0xff; + pattern >>= 1; + } + mpglActiveTexture(GL_TEXTURE3); + glAdjustAlignment(2); + mpglPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + mpglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, stipple); + mpglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + mpglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mpglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + mpglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + mpglActiveTexture(GL_TEXTURE0); +} + void glEnable3DLeft(int type) { GLint buffer; if (type & GL_3D_SWAP) @@ -1661,6 +1684,13 @@ } mpglDrawBuffer(buffer); break; + case GL_3D_STIPPLE: + mpglActiveTexture(GL_TEXTURE3); + mpglEnable(GL_TEXTURE_2D); + mpglActiveTexture(GL_TEXTURE0); + mpglEnable(GL_BLEND); + mpglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; } } @@ -1691,6 +1721,13 @@ } mpglDrawBuffer(buffer); break; + case GL_3D_STIPPLE: + mpglActiveTexture(GL_TEXTURE3); + mpglEnable(GL_TEXTURE_2D); + mpglActiveTexture(GL_TEXTURE0); + mpglEnable(GL_BLEND); + mpglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); + break; } } @@ -1718,6 +1755,12 @@ } mpglDrawBuffer(buffer); break; + case GL_3D_STIPPLE: + mpglActiveTexture(GL_TEXTURE3); + mpglDisable(GL_TEXTURE_2D); + mpglActiveTexture(GL_TEXTURE0); + mpglDisable(GL_BLEND); + break; } } @@ -1737,13 +1780,16 @@ * \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 + * \param use_stipple overlay texture 3 as 4x4 alpha stipple * \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) { + int sx, int sy, int rect_tex, int is_yv12, int flip, + int use_stipple) { int chroma_x_shift = (is_yv12 >> 8) & 31; int chroma_y_shift = (is_yv12 >> 16) & 31; + GLfloat texcoords3[8] = {vo_dx / 4.0, vo_dy / 4.0, vo_dx / 4.0, (vo_dy + vo_dheight) / 4.0, (vo_dx + vo_dwidth) / 4.0, vo_dy / 4.0, (vo_dx + vo_dwidth) / 4.0, (vo_dy + vo_dheight) / 4.0}; 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; @@ -1764,6 +1810,11 @@ mpglVertexPointer(2, GL_FLOAT, 0, vertices); mpglEnableClientState(GL_TEXTURE_COORD_ARRAY); mpglTexCoordPointer(2, GL_FLOAT, 0, texcoords); + if (use_stipple) { + mpglClientActiveTexture(GL_TEXTURE3); + mpglEnableClientState(GL_TEXTURE_COORD_ARRAY); + mpglTexCoordPointer(2, GL_FLOAT, 0, texcoords3); + } if (is_yv12) { mpglClientActiveTexture(GL_TEXTURE1); mpglEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1774,6 +1825,10 @@ mpglClientActiveTexture(GL_TEXTURE0); } mpglDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (use_stipple) { + mpglClientActiveTexture(GL_TEXTURE3); + mpglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } if (is_yv12) { mpglClientActiveTexture(GL_TEXTURE1); mpglDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1791,24 +1846,32 @@ mpglMultiTexCoord2f(GL_TEXTURE1, tx2, ty2); mpglMultiTexCoord2f(GL_TEXTURE2, tx2, ty2); } + if (use_stipple) + mpglMultiTexCoord2f(GL_TEXTURE3, texcoords3[0], texcoords3[1]); mpglVertex2f(x, y); mpglTexCoord2f(tx, ty + th); if (is_yv12) { mpglMultiTexCoord2f(GL_TEXTURE1, tx2, ty2 + th2); mpglMultiTexCoord2f(GL_TEXTURE2, tx2, ty2 + th2); } + if (use_stipple) + mpglMultiTexCoord2f(GL_TEXTURE3, texcoords3[2], texcoords3[3]); mpglVertex2f(x, y + h); mpglTexCoord2f(tx + tw, ty + th); if (is_yv12) { mpglMultiTexCoord2f(GL_TEXTURE1, tx2 + tw2, ty2 + th2); mpglMultiTexCoord2f(GL_TEXTURE2, tx2 + tw2, ty2 + th2); } + if (use_stipple) + mpglMultiTexCoord2f(GL_TEXTURE3, texcoords3[6], texcoords3[7]); mpglVertex2f(x + w, y + h); mpglTexCoord2f(tx + tw, ty); if (is_yv12) { mpglMultiTexCoord2f(GL_TEXTURE1, tx2 + tw2, ty2); mpglMultiTexCoord2f(GL_TEXTURE2, tx2 + tw2, ty2); } + if (use_stipple) + mpglMultiTexCoord2f(GL_TEXTURE3, texcoords3[4], texcoords3[5]); mpglVertex2f(x + w, y); mpglEnd(); }
--- a/libvo/gl_common.h Sun Aug 12 13:24:54 2012 +0000 +++ b/libvo/gl_common.h Sun Aug 12 17:15:35 2012 +0000 @@ -320,7 +320,8 @@ int x, int y, int w, int h, int slice); 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); + int sx, int sy, int rect_tex, int is_yv12, int flip, + int use_stipple); int loadGPUProgram(GLenum target, char *prog); /** \addtogroup glconversion @@ -382,6 +383,18 @@ } return 1; } + +static inline int glYUVSupportsAlphaTex(int conv) +{ + switch (conv) + { + case YUV_CONVERSION_COMBINERS: + case YUV_CONVERSION_COMBINERS_ATI: + case YUV_CONVERSION_TEXT_FRAGMENT: + return 0; + } + return 1; +} /** \} */ typedef struct { @@ -394,6 +407,7 @@ int chrom_texh; float filter_strength; float noise_strength; + int has_alpha_tex; } gl_conversion_params_t; int glAutodetectYUVConversion(void); @@ -405,7 +419,9 @@ #define GL_3D_RED_CYAN 1 #define GL_3D_GREEN_MAGENTA 2 #define GL_3D_QUADBUFFER 3 +#define GL_3D_STIPPLE 4 +void glSetupAlphaStippleTex(unsigned pattern); void glEnable3DLeft(int type); void glEnable3DRight(int type); void glDisable3D(int type);
--- a/libvo/vo_gl.c Sun Aug 12 13:24:54 2012 +0000 +++ b/libvo/vo_gl.c Sun Aug 12 17:15:35 2012 +0000 @@ -147,6 +147,7 @@ static int custom_trect; static int mipmap_gen; static int stereo_mode; +static int stipple; static enum MPGLType backend; static int int_pause; @@ -250,7 +251,8 @@ float bgamma = exp(log(8.0) * eq_bgamma / 100.0); gl_conversion_params_t params = {gl_target, yuvconvtype, {colorspace, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma, 0}, - texture_width, texture_height, 0, 0, filter_strength, noise_strength}; + texture_width, texture_height, 0, 0, filter_strength, noise_strength, + stereo_mode == GL_3D_STIPPLE}; mp_get_chroma_shift(image_format, &xs, &ys, &depth); params.chrom_texw = params.texw >> xs; params.chrom_texh = params.texh >> ys; @@ -436,7 +438,7 @@ texSize(i->w, i->h, &sx, &sy); mpglBindTexture(gl_target, *curtex++); } - glDrawTex(i->dst_x, i->dst_y, i->w, i->h, x, y, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0); + glDrawTex(i->dst_x, i->dst_y, i->w, i->h, x, y, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0, 0); } mpglEndList(); mpglBindTexture(gl_target, 0); @@ -515,8 +517,12 @@ } if (use_osd == -1) use_osd = mpglBindTexture != NULL; - if (use_yuv == -1) + if (use_yuv == -1) { use_yuv = glAutodetectYUVConversion(); + if (stereo_mode == GL_3D_STIPPLE && + !glYUVSupportsAlphaTex(use_yuv)) + use_yuv = 0; + } if (is_ati && (lscale == 1 || lscale == 2 || cscale == 1 || cscale == 2)) mp_msg(MSGT_VO, MSGL_WARN, "[gl] Selected scaling mode may be broken on ATI cards.\n" "Tell _them_ to fix GL_REPEAT if you have issues.\n"); @@ -562,13 +568,8 @@ if (mipmap_gen) mpglTexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE); - if (is_yuv) { + if (is_yuv || stereo_mode == GL_3D_STIPPLE) { int i; - int xs, ys, depth; - int chroma_clear_val = 128; - scale_type = get_scale_type(1); - mp_get_chroma_shift(image_format, &xs, &ys, &depth); - chroma_clear_val >>= -depth & 7; mpglGenTextures(21, default_texs); default_texs[21] = 0; for (i = 0; i < 7; i++) { @@ -577,6 +578,15 @@ mpglBindTexture(GL_TEXTURE_RECTANGLE, default_texs[i + 7]); mpglBindTexture(GL_TEXTURE_3D, default_texs[i + 14]); } + } + if (stereo_mode == GL_3D_STIPPLE) + glSetupAlphaStippleTex(stipple); + if (is_yuv) { + int xs, ys, depth; + int chroma_clear_val = 128; + scale_type = get_scale_type(1); + mp_get_chroma_shift(image_format, &xs, &ys, &depth); + chroma_clear_val >>= -depth & 7; mpglActiveTexture(GL_TEXTURE1); glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type, texture_width >> xs, texture_height >> ys, @@ -776,14 +786,14 @@ mpglNewList(osdaDispList[osdtexCnt], GL_COMPILE); // render alpha mpglBindTexture(gl_target, osdatex[osdtexCnt]); - glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0); + glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0, 0); mpglEndList(); #endif osdDispList[osdtexCnt] = mpglGenLists(1); mpglNewList(osdDispList[osdtexCnt], GL_COMPILE); // render OSD mpglBindTexture(gl_target, osdtex[osdtexCnt]); - glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0); + glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0, 0); mpglEndList(); osdtexCnt++; @@ -863,20 +873,20 @@ 0, 0, image_width >> 1, image_height, texture_width, texture_height, use_rectangle == 1, is_yuv, - mpi_flipped ^ vo_flipped); + mpi_flipped ^ vo_flipped, stereo_mode == GL_3D_STIPPLE); glEnable3DRight(stereo_mode); glDrawTex(0, 0, image_width, image_height, image_width >> 1, 0, image_width >> 1, image_height, texture_width, texture_height, use_rectangle == 1, is_yuv, - mpi_flipped ^ vo_flipped); + mpi_flipped ^ vo_flipped, stereo_mode == GL_3D_STIPPLE); glDisable3D(stereo_mode); } else { glDrawTex(0, 0, image_width, image_height, 0, 0, image_width, image_height, texture_width, texture_height, use_rectangle == 1, is_yuv, - mpi_flipped ^ vo_flipped); + mpi_flipped ^ vo_flipped, 0); } if (is_yuv || custom_prog) glDisableYUVConversion(gl_target, yuvconvtype); @@ -1206,6 +1216,7 @@ {"mipmapgen", OPT_ARG_BOOL, &mipmap_gen, NULL}, {"osdcolor", OPT_ARG_INT, &osd_color, NULL}, {"stereo", OPT_ARG_INT, &stereo_mode, NULL}, + {"stipple", OPT_ARG_INT, &stipple, NULL}, {"backend", OPT_ARG_INT, &backend, valid_backend}, {NULL} }; @@ -1240,6 +1251,7 @@ mipmap_gen = 0; osd_color = 0xffffff; stereo_mode = 0; + stipple = 0x0f0f; if (subopt_parse(arg, subopts) != 0) { mp_msg(MSGT_VO, MSGL_FATAL, "\n-vo gl command line help:\n" @@ -1320,6 +1332,9 @@ " 1: side-by-side to red-cyan stereo\n" " 2: side-by-side to green-magenta stereo\n" " 3: side-by-side to quadbuffer stereo\n" + " 4: side-by-side to pixel pattern\n" + " stipple=<0xBBBB>\n" + " 16 bits representing 4x4 pattern to use for stereo=4\n" " backend=<n>\n" " -1: auto-select\n" " 0: Win32/WGL\n"
--- a/libvo/vo_gl2.c Sun Aug 12 13:24:54 2012 +0000 +++ b/libvo/vo_gl2.c Sun Aug 12 17:15:35 2012 +0000 @@ -412,7 +412,7 @@ glDrawTex(square->fx, square->fy, square->fw, square->fh, 0, 0, texture_width, texture_height, texture_width, texture_height, - 0, is_yuv, 0); + 0, is_yuv, 0, 0); square++; } /* for all texnumx */ } /* for all texnumy */