[MPlayer-dev-eng] Patch, allows subtitles out of film area

Tomas Konir moje at molly.vabo.cz
Thu Feb 28 09:21:58 CET 2002


Hi
I made small patch, which allows show subtitles out of film area. Anyone 
wrote a few time ago, that is not possible, because of library design or 
any other thing. I made it only for XV driver (i think, it can be 
made for other drivers too). This patch add posibility to create area 
(called sub_box) for subtitles under film area. Two options are privided. 
Using -subbox 'num' make sub_box area with num% size from film height. 
Using -autosubbox create sub_box area automatically to fill the screen.
As addon there are two keys 'r' and 't' to allow moving with subtitles up 
or down.

Patch is included as file and can be found on 
http://molly.vabo.cz/~moje/mplayer-subtitles.diff

	MOJE

-- 
Tomas Konir
Brno
ICQ 25849167

-------------- next part --------------
diff -Nur main/cfg-mplayer.h main_sub/cfg-mplayer.h
--- main/cfg-mplayer.h	Thu Feb 28 08:56:55 2002
+++ main_sub/cfg-mplayer.h	Thu Feb 28 08:56:39 2002
@@ -58,6 +58,8 @@
 extern char *sub_cp;
 #endif
 extern int sub_pos;
+extern int sub_box;
+extern int auto_sub_box;
 #endif
 
 #ifdef USE_OSD
@@ -177,6 +179,8 @@
 	{"utf8", &sub_utf8, CONF_TYPE_FLAG, 0, 0, 1, NULL},
 	{"noutf8", &sub_utf8, CONF_TYPE_FLAG, 0, 1, 0, NULL},
  	{"subpos",&sub_pos,  CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+	{"subbox",&sub_box,  CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+	{"autosubbox",&auto_sub_box,  CONF_TYPE_FLAG, 0, 0, 1, NULL},
 #endif
 #ifdef USE_OSD
 	{"font", &font_name, CONF_TYPE_STRING, 0, 0, 0, NULL},
diff -Nur main/input/input.c main_sub/input/input.c
--- main/input/input.c	Thu Feb 28 08:56:55 2002
+++ main_sub/input/input.c	Thu Feb 28 08:56:39 2002
@@ -49,6 +49,7 @@
   { MP_CMD_HUE, "hue",1,  { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
   { MP_CMD_SATURATION, "saturation",1,  { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} }  },
   { MP_CMD_FRAMEDROPPING, "frame_drop",0, { { MP_CMD_ARG_INT,{-1} }, {-1,{0}} } },
+  { MP_CMD_SUB_POS, "sub_pos", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
 #ifdef USE_TV
   { MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", 1,  { { MP_CMD_ARG_INT ,{0}}, {-1,{0}} }},
   { MP_CMD_TV_STEP_NORM, "tv_step_norm",0, { {-1,{0}} }  },
@@ -174,6 +175,8 @@
   { { '7', 0 }, "saturation -1" },
   { { '8', 0 }, "saturation 1" },
   { { 'd', 0 }, "frame_drop" },
+  { { 'r', 0 }, "sub_pos +5" },
+  { { 't', 0 }, "sub_pos -5" },
 #ifdef USE_TV
   { { 'h', 0 }, "tv_step_channel 1" },
   { { 'k', 0 }, "tv_step_channel -1" },
diff -Nur main/input/input.h main_sub/input/input.h
--- main/input/input.h	Thu Feb 28 08:56:55 2002
+++ main_sub/input/input.h	Thu Feb 28 08:56:39 2002
@@ -22,6 +22,7 @@
 #define MP_CMD_TV_STEP_NORM 18
 #define MP_CMD_TV_STEP_CHANNEL_LIST 19
 #define MP_CMD_VO_FULLSCREEN 20
+#define MP_CMD_SUB_POS 21
 
 #define MP_CMD_GUI_EVENTS       5000
 #define MP_CMD_GUI_LOADFILE     5001
diff -Nur main/libvo/sub.c main_sub/libvo/sub.c
--- main/libvo/sub.c	Thu Feb 28 08:56:55 2002
+++ main_sub/libvo/sub.c	Thu Feb 28 08:56:39 2002
@@ -171,6 +171,7 @@
    int lastStripPosition;
    int xsize,lastxsize;
    int h,lasth;
+   extern int sub_y_start,sub_y_end;
    
    if ((memsub!=vo_sub)||(memdxs!=dxs)||(memdys!=dys)){
       
@@ -257,6 +258,7 @@
    
 //   printf("lines=%d  y=%d\n",lines,y);
 
+   sub_y_start=y;
    i=j=0;
    if ((l=lines)) for (;;) {
  	 x=xtbl[i++]; 
@@ -270,10 +272,13 @@
 			     vo_font->pic_a[font]->w);
 	          x+=vo_font->width[c]+vo_font->charspace;
 	 }
-         if (!--l) 
+         if (!--l){
+			 sub_y_end=y+vo_font->height+10; /*need to add 10 because any chars are below and there are artefacts*/
 	    return;
+		 }
          y+=vo_font->height;
    }
+   
 }
 
 void *vo_spudec=NULL;
diff -Nur main/libvo/vo_xv.c main_sub/libvo/vo_xv.c
--- main/libvo/vo_xv.c	Thu Feb 28 08:56:55 2002
+++ main_sub/libvo/vo_xv.c	Thu Feb 28 08:56:39 2002
@@ -70,6 +70,13 @@
 static XvAdaptorInfo        *ai;
 static XvImageFormatValues  *fo;
 
+int	sub_box=0;
+int auto_sub_box=0;
+int	sub_y_start=0;
+int	sub_y_end=0;
+int sub_clear=0;
+extern float monitor_aspect;
+
 static int current_buf=0;
 static int num_buffers=1; // default
 static XvImage* xvimage[NUM_BUFFERS];
@@ -97,6 +104,8 @@
  static uint32_t               mdwidth,mdheight;
 #endif
 
+static uint32_t clear_region(int w,int h,int x,int y);
+
 static void (*draw_alpha_fnc)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride);
 
 static void draw_alpha_yv12(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
@@ -328,23 +337,37 @@
  static uint32_t vm_height;
 #endif
 
- aspect_save_orig(width,height);
- aspect_save_prescale(d_width,d_height);
-
  image_height = height;
  image_width = width;
  image_format=format;
 
-#ifdef HAVE_NEW_GUI
- mdwidth=width;
- mdheight=height;
-#endif
-
  mFullscreen=flags&1;
  if( flags&0x02 ) vm = 1;
  flip_flag=flags&8;
  num_buffers=vo_doublebuffering?NUM_BUFFERS:1;
+
+ sub_box=(sub_box*image_height)/100;
+ 
+ if(auto_sub_box){
+	 sub_box=((float)image_width/monitor_aspect)-image_height;
+ }
+
+ printf("SUB_BOX value: %i\n",sub_box);
+ if(sub_box<10 || sub_box>image_height) sub_box=0; /*to small and not need*/
+ sub_box=(sub_box>>1)<<1;
+ sub_y_start=image_height;
+ sub_y_end=image_height+sub_box;
+ 
+ if(mFullscreen)d_height=(d_height*(height+sub_box))/height;
  
+ aspect_save_orig(width,height);
+ aspect_save_prescale(d_width,d_height);
+ 
+#ifdef HAVE_NEW_GUI
+ mdwidth=width;
+ mdheight=height;
+#endif
+
  if (!vo_init()) return -1;
 
  aspect_save_screenres(vo_screenwidth,vo_screenheight);
@@ -407,7 +430,7 @@
     } else 
 
    vo_window = XCreateWindow(mDisplay, RootWindow(mDisplay,mScreen),
-       hint.x, hint.y, hint.width, hint.height,
+       hint.x, hint.y , hint.width, hint.height + sub_box, /*MOJE*/
        0, depth,CopyFromParent,vinfo.visual,xswamask,&xswa);
 
    vo_x11_classhint( mDisplay,vo_window,"xv" );
@@ -478,7 +501,8 @@
    if (xv_port != 0)
     {
      printf( "using Xvideo port %d for hw scaling\n",xv_port );
-       
+		
+   
        switch (xv_format){
 	case IMGFMT_YV12:  
 	case IMGFMT_I420:
@@ -545,7 +569,7 @@
   * allocate XvImages.  FIXME: no error checking, without
   * mit-shm this will bomb...
   */
- xvimage[foo] = XvShmCreateImage(mDisplay, xv_port, xv_format, 0, image_width, image_height, &Shminfo[foo]);
+ xvimage[foo] = XvShmCreateImage(mDisplay, xv_port, xv_format, 0, image_width, image_height+sub_box, &Shminfo[foo]); /*MOJE*/
 
  Shminfo[foo].shmid    = shmget(IPC_PRIVATE, xvimage[foo]->data_size, IPC_CREAT | 0777);
  Shminfo[foo].shmaddr  = (char *) shmat(Shminfo[foo].shmid, 0, 0);
@@ -612,13 +636,90 @@
   }
 }
 
+static uint32_t clear_region(int w,int h,int x,int y)
+{
+ uint8_t *dst;
+ uint16_t count;
+ int i;
+
+switch (image_format) {
+ case IMGFMT_YUY2:
+ case IMGFMT_UYVY:
+ case IMGFMT_YVYU:	
+	dst=xvimage[current_buf]->data+image_width*y*2;
+    count=(image_width*h)>>1;
+#ifdef ARCH_X86 
+	 //longset(dst,2130738944,count); /*WARNING This routine clear full lines (need to upgrade)*/
+	 asm volatile(
+	"rep\n"
+	"stosl":
+	"=D" (dst), "=c" (count) :
+	"0" (dst), "1" (count), "a" (2130738944) :
+	"memory");
+#else
+	for(i=0;i<image_width*h*2;i+=2){ 
+                dst[i]=(uint16_t)(32512);
+        } 
+#endif
+	 
+     break;
+
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ 
+ image_height+=sub_box; /*MOJE*/
+ 
+ dst = xvimage[current_buf]->data + image_width * y + x;
+  if(w==image_width) memset(dst,0,w*h);
+   else
+    for(i=0;i<h;i++){
+	  memset(dst,0,w);
+      dst+=image_width;
+     }
+
+ x/=2;y/=2;w/=2;h/=2;
+
+ dst = xvimage[current_buf]->data + image_width * image_height + image_width/2 * y + x;
+  if(w==image_width/2) memset(dst,127,w*h);
+   else
+   for(i=0;i<h;i++){
+	 memset(dst,127,w);
+     dst+=image_width/2;
+   }
+
+ dst = xvimage[current_buf]->data + image_width * image_height * 5 / 4 + image_width/2 * y + x;
+  if(w==image_width/2) memset(dst,127,w*h);
+   else
+   for(i=0;i<h;i++){
+	 memset(dst,127,w);
+     dst+=image_width/2;
+    }
+	
+	image_height-=sub_box; /*MOJE*/
+	
+ break;   
+}
+    
+ return 0;
+}
+
+
 static void draw_osd(void)
-{ vo_draw_text(image_width,image_height,draw_alpha_fnc);}
+{ 
+  if(sub_clear){
+	 if(sub_y_start<image_height) sub_y_start=image_height;
+	 if(sub_y_end>sub_y_start) clear_region(image_width,sub_y_end-sub_y_start,0,sub_y_start);
+	 sub_y_start=sub_y_end=0;
+	 sub_clear=0;
+ }
+ vo_draw_text(image_width,image_height+sub_box,draw_alpha_fnc);
+}
 
 static void flip_page(void)
 {
  XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, xvimage[current_buf],
-         0, 0,  image_width, image_height,
+         0, 0,  image_width, image_height+sub_box, /*MOJE*/
          drwX,drwY,drwWidth,(mFullscreen?drwHeight - 1:drwHeight),
          False);
  if (num_buffers>1){
@@ -637,6 +738,8 @@
  uint8_t *dst;
  int i;
 
+image_height+=sub_box; /*MOJE*/
+
  dst = xvimage[current_buf]->data + image_width * y + x;
  src = image[0];
  if(w==stride[0] && w==image_width) memcpy(dst,src,w*h);
@@ -670,6 +773,9 @@
      src+=stride[1];
      dst+=image_width/2;
     }
+    
+    image_height-=sub_box; /*MOJE*/
+    
  return 0;
 }
 
diff -Nur main/mplayer.c main_sub/mplayer.c
--- main/mplayer.c	Thu Feb 28 08:56:55 2002
+++ main_sub/mplayer.c	Thu Feb 28 08:56:39 2002
@@ -1673,6 +1673,7 @@
   
     float frame_time=0;
     int blit_frame=0;
+	extern int sub_clear;
     
     //--------------------  Decode a frame: -----------------------
     vdecode_time=video_time_usage;
@@ -1690,7 +1691,8 @@
     }
     vdecode_time=video_time_usage-vdecode_time;
     //------------------------ frame decoded. --------------------
-    
+	
+	sub_clear=1;    
 //------------------------ add OSD to frame contents ---------
 #ifndef USE_LIBVO2
     current_module="draw_osd";
@@ -2645,6 +2647,15 @@
 #endif
 	video_out->control(VOCTRL_FULLSCREEN, 0);
     } break;
+    case MP_CMD_SUB_POS:
+    {
+        int v;
+	v = cmd->args[0].v.i;
+    
+	sub_pos+=v;
+	if(sub_pos >100) sub_pos=100;
+	if(sub_pos <0) sub_pos=0;
+    }	break;
     default : {
 #ifdef HAVE_NEW_GUI
       if ( ( use_gui )&&( cmd->id > MP_CMD_GUI_EVENTS ) ) guiGetEvent( guiIEvent,(char *)cmd->id );


More information about the MPlayer-dev-eng mailing list