[MPlayer-dev-eng] [PATCH] libass support in vf_vo

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Fri Aug 25 22:29:46 CEST 2006


Hello,
On Fri, Aug 25, 2006 at 08:38:45PM +0200, Reimar D?ffinger wrote:
> On Fri, Aug 25, 2006 at 10:07:16PM +0400, Evgeniy Stepanov wrote:
> > +        if (video_out->control(VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) {
> > +            settings.frame_width = res.w;
> > +            settings.frame_height = res.h;
> > +        } else {
> > +            settings.frame_width = d_width;
> > +            settings.frame_height = d_height;
> > +        }
> 
> To actually be useful (at least for vo_gl) something like this needs to
> be done for every VFCTRL_DRAW_EOSD, otherwise when you start playing at
> normal resolution and switch to fullscreen the OSD will still look bad
> (well, of course -vo gl could just always return the screen resolution,
> but that would be a waste of CPU power when the window is small, and it
> would still look bad when resizing the window beyond the size of the
> screen, although this is unlikely to happen often)

See attach for something to test. It still needs some cleanup, fixing,
ifdefs etc. but still.
And you explain how the color entry in ass_imag e_t is exactly defined?
I have no clue if my way is correct for bigendian, and the alpha value
does not at all work as expected.

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: libvo/vo_gl.c
===================================================================
--- libvo/vo_gl.c	(revision 19534)
+++ libvo/vo_gl.c	(working copy)
@@ -16,6 +16,7 @@
 #ifdef HAVE_NEW_GUI
 #include "Gui/interface.h"
 #endif
+#include "libass/ass.h"
 
 static vo_info_t info = 
 {
@@ -51,13 +52,16 @@
 //! Alpha textures for OSD
 static GLuint osdatex[MAX_OSD_PARTS];
 #endif
+static GLuint eosdtex[MAX_OSD_PARTS];
 //! Display lists that draw the OSD parts
 static GLuint osdDispList[MAX_OSD_PARTS];
 #ifndef FAST_OSD
 static GLuint osdaDispList[MAX_OSD_PARTS];
 #endif
+static GLuint eosdDispList;
 //! How many parts the OSD currently consists of
 static int osdtexCnt;
+static int eosdtexCnt;
 static int osd_color;
 
 static int use_aspect;
@@ -222,6 +226,47 @@
   osdtexCnt = 0;
 }
 
+static void clearEOSD(void) {
+  if (!eosdtexCnt)
+    return;
+  glDeleteTextures(eosdtexCnt, eosdtex);
+  glDeleteLists(eosdDispList, 1);
+  eosdtexCnt = 0;
+}
+
+static void genEOSD(ass_image_t *img) {
+  int sx = 8, sy = 8;
+  GLint scale_type = (scaled_osd) ? GL_LINEAR : GL_NEAREST;
+  ass_image_t *i;
+  clearEOSD();
+  eosdDispList = glGenLists(1);
+  glNewList(eosdDispList, GL_COMPILE);
+  for (i = img; i; i = i->next) {
+    if (eosdtexCnt >= MAX_OSD_PARTS) {
+      mp_msg(MSGT_VO, MSGL_ERR, "Too many OSD parts, contact the developers!\n");
+      break;
+    }
+    if (i->w <= 0 || i->h <= 0 || i->stride < i->w) {
+      mp_msg(MSGT_VO, MSGL_V, "Invalid dimensions OSD for part!\n");
+      continue;
+    }
+    glGenTextures(1, &eosdtex[eosdtexCnt]);
+    BindTexture(gl_target, eosdtex[eosdtexCnt]);
+    texSize(i->w, i->h, &sx, &sy);
+    glCreateClearTex(gl_target, GL_ALPHA, scale_type, sx, sy, 255);
+    glUploadTex(gl_target, GL_ALPHA, GL_UNSIGNED_BYTE, i->bitmap, i->stride,
+                0, 0, i->w, i->h, 0);
+    BindTexture(gl_target, eosdtex[eosdtexCnt]);
+// FIXME: OSD disappears completely if we respect alpha value of color
+//    glColor4ub(i->color >> 24, (i->color >> 16) & 0xff, (i->color >> 8) & 0xff, i->color & 0xff);
+    glColor3ub(i->color >> 24, (i->color >> 16) & 0xff, (i->color >> 8) & 0xff);
+    glDrawTex(i->dst_x, i->dst_y, i->w, i->h, 0, 0, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0);
+    eosdtexCnt++;
+  }
+  glEndList();
+  BindTexture(gl_target, 0);
+}
+
 /**
  * \brief uninitialize OpenGL context, freeing textures, buffers etc.
  */
@@ -248,6 +293,7 @@
  */
 static int initGl(uint32_t d_width, uint32_t d_height) {
   osdtexCnt = 0; gl_buffer = 0; gl_buffersize = 0; err_shown = 0;
+  eosdtexCnt = 0;
   fragprog = 0;
   texSize(image_width, image_height, &texture_width, &texture_height);
 
@@ -555,6 +601,12 @@
     glPopMatrix();
     BindTexture(gl_target, 0);
   }
+  if (eosdtexCnt > 0) {
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glCallList(eosdDispList);
+    glDisable (GL_BLEND);
+  }
 
   if (use_glFinish)
   glFinish();
@@ -674,7 +726,7 @@
                VFCAP_FLIP |
                VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
     if (use_osd)
-      caps |= VFCAP_OSD;
+      caps |= VFCAP_OSD | VFCAP_EOSD;
     if ((format == IMGFMT_RGB24) || (format == IMGFMT_RGBA))
         return caps;
     if (use_yuv && format == IMGFMT_YV12)
@@ -818,6 +870,15 @@
     return get_image(data);
   case VOCTRL_DRAW_IMAGE:
     return draw_image(data);
+  case VOCTRL_DRAW_EOSD:
+    genEOSD(data);
+    return VO_TRUE;
+  case VOCTRL_GET_EOSD_RES:
+    {
+      mp_eosd_res_t *r = data;
+      r->w = vo_dwidth; r->h = vo_dheight;
+    }
+    return VO_TRUE;
   case VOCTRL_GUISUPPORT:
     return VO_TRUE;
   case VOCTRL_ONTOP:


More information about the MPlayer-dev-eng mailing list