[MPlayer-dev-eng] [PATCH] fix dvdnav highlight position with full-res OSD (-vo gl)

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Fri Jan 9 13:48:27 CET 2009


Hello,
currently the dvdnav highlight is always at the position given on the
DVD, which is based on the movie resolution.
This is obviously completely wrong once the OSD has a different size
from the movie.
Attached patch fixes that by giving the functions all necessary data to
do the proper scaling/coordinate adjustment.
In case of vo_gl, of course the vo could do the scaling/coordinate
adjustment, but I don't think it would be more complex and for the
general case (e.g. when some kind of overlay is used that can not do any
scaling, or when an approach like in vo_direct3d is used) this
approach seems better to me.

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: libvo/sub.c
===================================================================
--- libvo/sub.c	(revision 28284)
+++ libvo/sub.c	(working copy)
@@ -224,13 +224,32 @@
   nav_hl.ey = ey;
 }
 
-inline static void vo_update_nav (mp_osd_obj_t *obj, int dxs, int dys) {
+inline static void vo_update_nav (mp_osd_obj_t *obj, int dxs, int dys, int left_border, int top_border,
+                      int right_border, int bottom_border, int orig_w, int orig_h) {
   int len;
+  int sx = nav_hl.sx, sy = nav_hl.sy;
+  int ex = nav_hl.ex, ey = nav_hl.ey;
+  int scaled_w = dxs - left_border - right_border;
+  int scaled_h = dys - top_border - bottom_border;
+  if (scaled_w != orig_w) {
+    sx = sx * scaled_w / orig_w;
+    ex = ex * scaled_w / orig_w;
+  }
+  if (scaled_h != orig_h) {
+    sy = sy * scaled_h / orig_h;
+    ey = ey * scaled_h / orig_h;
+  }
+  sx += left_border; ex += left_border;
+  sy += top_border;  ey += top_border;
+  sx = FFMIN(FFMAX(sx, 0), dxs);
+  ex = FFMIN(FFMAX(ex, 0), dxs);
+  sy = FFMIN(FFMAX(sy, 0), dys);
+  ey = FFMIN(FFMAX(ey, 0), dys);
 
-  obj->bbox.x1 = obj->x = nav_hl.sx;
-  obj->bbox.y1 = obj->y = nav_hl.sy;
-  obj->bbox.x2 = nav_hl.ex;
-  obj->bbox.y2 = nav_hl.ey;
+  obj->bbox.x1 = obj->x = sx;
+  obj->bbox.y1 = obj->y = sy;
+  obj->bbox.x2 = ex;
+  obj->bbox.y2 = ey;
   
   alloc_buf (obj);
   len = obj->stride * (obj->bbox.y2 - obj->bbox.y1);
@@ -1060,7 +1079,8 @@
 
 #define FONT_LOAD_DEFER 6
 
-int vo_update_osd(int dxs,int dys){
+int vo_update_osd_ext(int dxs,int dys, int left_border, int top_border,
+                      int right_border, int bottom_border, int orig_w, int orig_h){
     mp_osd_obj_t* obj=vo_osd_list;
     int chg=0;
 #ifdef CONFIG_FREETYPE
@@ -1115,7 +1135,7 @@
 	switch(obj->type){
 #ifdef CONFIG_DVDNAV
         case OSDTYPE_DVDNAV:
-           vo_update_nav(obj,dxs,dys);
+           vo_update_nav(obj,dxs,dys, left_border, top_border, right_border, bottom_border, orig_w, orig_h);
            break;
 #endif
 	case OSDTYPE_SUBTITLE:
@@ -1179,6 +1199,10 @@
     return chg;
 }
 
+int vo_update_osd(int dxs, int dys) {
+    return vo_update_osd_ext(dxs, dys, 0, 0, 0, 0, dxs, dys);
+}
+
 void vo_init_osd(void){
     if(!draw_alpha_init_flag){
 	draw_alpha_init_flag=1;
@@ -1221,9 +1245,11 @@
     }
 }
 
-void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
+void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border,
+                      int right_border, int bottom_border, int orig_w, int orig_h,
+                      void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) {
     mp_osd_obj_t* obj=vo_osd_list;
-    vo_update_osd(dxs,dys);
+    vo_update_osd_ext(dxs, dys, left_border, top_border, right_border, bottom_border, orig_w, orig_h);
     while(obj){
       if(obj->flags&OSDFLAG_VISIBLE){
 	vo_osd_changed_flag=obj->flags&OSDFLAG_CHANGED;	// temp hack
@@ -1251,6 +1277,10 @@
     }
 }
 
+void vo_draw_text(int dxs, int dys, void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) {
+  vo_draw_text_ext(dxs, dys, 0, 0, 0, 0, dxs, dys, draw_alpha);
+}
+
 static int vo_osd_changed_status = 0;
 
 int vo_osd_changed(int new_value)
Index: libvo/sub.h
===================================================================
--- libvo/sub.h	(revision 28284)
+++ libvo/sub.h	(working copy)
@@ -106,6 +106,9 @@
 extern float spu_gaussvar;
 
 void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
+void vo_draw_text_ext(int dxs, int dys, int left_border, int top_border,
+                      int right_border, int bottom_border, int orig_w, int orig_h,
+                      void (*draw_alpha)(int x0, int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 void vo_remove_text(int dxs,int dys,void (*remove)(int x0,int y0, int w,int h));
 
 void vo_init_osd(void);
Index: libvo/vo_gl.c
===================================================================
--- libvo/vo_gl.c	(revision 28284)
+++ libvo/vo_gl.c	(working copy)
@@ -612,7 +612,8 @@
     clearOSD();
     osd_w = scaled_osd ? image_width : vo_dwidth;
     osd_h = scaled_osd ? image_height : vo_dheight;
-    vo_draw_text(osd_w, osd_h, create_osd_texture);
+    vo_draw_text_ext(osd_w, osd_h, ass_border_x, ass_border_y, ass_border_x, ass_border_y,
+                     image_width, image_height, create_osd_texture);
   }
   if (vo_doublebuffering) do_render_osd();
 }


More information about the MPlayer-dev-eng mailing list