# HG changeset patch # User arpi # Date 1018898232 0 # Node ID 86663f1b9b003d590b26c61c73c9f2b4df78aad4 # Parent 6890819bc0dcca8f81a9707ca9e13df82a920492 new osd code, use osd objs to follow changes and do minimal updates diff -r 6890819bc0dc -r 86663f1b9b00 find_sub.c --- a/find_sub.c Mon Apr 15 18:04:18 2002 +0000 +++ b/find_sub.c Mon Apr 15 19:17:12 2002 +0000 @@ -36,7 +36,7 @@ // sub changed! /* Tell the OSD subsystem that the OSD contents will change soon */ - vo_osd_changed(1); + vo_osd_changed(OSDTYPE_SUBTITLE); if(key<=0){ vo_sub=NULL; // no sub here diff -r 6890819bc0dc -r 86663f1b9b00 libvo/sub.c --- a/libvo/sub.c Mon Apr 15 18:04:18 2002 +0000 +++ b/libvo/sub.c Mon Apr 15 19:17:12 2002 +0000 @@ -3,6 +3,7 @@ #include #include "config.h" +#include "mp_msg.h" #include "video_out.h" #include "font_load.h" #include "sub.h" @@ -63,12 +64,17 @@ // // the above schema is rescalled to n=elems bars -inline static void vo_draw_text_progbar(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ - unsigned char *s; - unsigned char *sa; - int i,w,h,st,mark; +inline static void vo_update_text_progbar(mp_osd_obj_t* obj,int dxs,int dys){ + + obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; + + if(vo_osd_progbar_type<0 || !vo_font){ + obj->flags&=~OSDFLAG_VISIBLE; + return; + } + + { int y=(dys-vo_font->height)/2; - int c,font; int delimw=vo_font->width[OSD_PB_START] +vo_font->width[OSD_PB_END] +vo_font->charspace; @@ -76,6 +82,24 @@ int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; int elems=width/charw; int x=(dxs-elems*charw-delimw)/2; + obj->bbox.x1=obj->x=x; + obj->bbox.y1=obj->y=y; + obj->bbox.x2=x+width+delimw; + obj->bbox.y2=y+vo_font->height; + obj->params.progbar.elems=elems; + } + +} + +inline static void vo_draw_text_progbar(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ + unsigned char *s; + unsigned char *sa; + int i,w,h,st,mark; + int x=obj->x; + int y=obj->y; + int c,font; + int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; + int elems=obj->params.progbar.elems; if (vo_osd_progbar_value<=0) mark=0; @@ -153,19 +177,9 @@ subtitle* vo_sub=NULL; -#define MAX_UCS 1600 -#define MAX_UCSLINES 16 - +// vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) -inline static void vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ - static int utbl[MAX_UCS+1]; - static int xtbl[MAX_UCSLINES]; - static int lines; - static subtitle *memsub=NULL; - static int memy; - static int memdxs; - static int memdys; - +inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ unsigned char *t; int c,i,j,l,x,y,font; int len; @@ -174,14 +188,18 @@ int xsize,lastxsize; int h,lasth; - if ((memsub!=vo_sub)||(memdxs!=dxs)||(memdys!=dys)){ - - memsub=vo_sub; - memdxs=dxs; - memdys=memy=dys; - + obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; + + if(!vo_sub || !vo_font){ + obj->flags&=~OSDFLAG_VISIBLE; + return; + } + + obj->y=dys; + obj->params.subtitle.lines=0; + // too long lines divide into a smaller ones - i=k=lines=lasth=0; + i=k=lasth=0; h=vo_font->height; xsize=-vo_font->charspace; lastStripPosition=-1; @@ -208,7 +226,7 @@ } if (k==MAX_UCS){ len=j; // end here - printf ("\nMAX_UCS exceeded!\n"); + mp_msg(MSGT_OSD,MSGL_WARN,"\nMAX_UCS exceeded!\n"); } if (!c) c++; // avoid UCS 0 if (c==' '){ @@ -220,7 +238,7 @@ h=vo_font->pic_a[font]->h; } } - utbl[k++]=c; + obj->params.subtitle.utbl[k++]=c; xsize+=vo_font->width[c]+vo_font->charspace; if (dxs0){ @@ -234,14 +252,14 @@ } } else if (jmemy){ // out of the screen so end parsing - memy -= lasth - vo_font->height; // correct the y position + if (h>obj->y){ // out of the screen so end parsing + obj->y -= lasth - vo_font->height; // correct the y position l=0; break; } - utbl[k++]=0; - xtbl[lines++]=(dxs-xsize)/2; - if (lines==MAX_UCSLINES||k>MAX_UCS){ + obj->params.subtitle.utbl[k++]=0; + obj->params.subtitle.xtbl[obj->params.subtitle.lines++]=(dxs-xsize)/2; + if (obj->params.subtitle.lines==MAX_UCSLINES||k>MAX_UCS){ l=0; len=j; // end parsing } else if(l || jheight; } // printf("h: %d -> %d \n",vo_font->height,h); - memy -=h; // according to max of vo_font->pic_a[font]->h + obj->y -=h; // according to max of vo_font->pic_a[font]->h } } - } - - if (memy < (dys * sub_pos / 100)) { y = memy; } else { y = dys * sub_pos /100;}; + + // TODO: calculate bbox + +} + +inline static void vo_draw_text_sub(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ + int y,i,j,c,x,l,font; + + // FIXME (bbox): + if (obj->y < (obj->dys * sub_pos / 100)) { y = obj->y; } else { y = obj->dys * sub_pos /100;}; // printf("lines=%d y=%d\n",lines,y); i=j=0; - if ((l=lines)) for (;;) { - x=xtbl[i++]; - while ((c=utbl[j++])){ + if ((l=obj->params.subtitle.lines)) for (;;) { + x=obj->params.subtitle.xtbl[i++]; + while ((c=obj->params.subtitle.utbl[j++])){ if ((font=vo_font->font[c])>=0) draw_alpha(x,y, vo_font->width[c], - vo_font->pic_a[font]->h+ypic_a[font]->h : dys-y, + vo_font->pic_a[font]->h+ydys ? vo_font->pic_a[font]->h : obj->dys-y, vo_font->pic_b[font]->bmp+vo_font->start[c], vo_font->pic_a[font]->bmp+vo_font->start[c], vo_font->pic_a[font]->w); x+=vo_font->width[c]+vo_font->charspace; } - if (!--l) - return; + if (!--l) break; y+=vo_font->height; } } void *vo_spudec=NULL; void *vo_vobsub=NULL; -inline static void vo_draw_spudec(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ - spudec_draw_scaled(vo_spudec, dxs, dys, draw_alpha); -} -inline static void vo_draw_vobsub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ - vobsub_draw(vo_vobsub, dxs, dys, draw_alpha); -} static int draw_alpha_init_flag=0; extern void vo_draw_alpha_init(); -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)){ +static mp_osd_obj_t* vo_osd_list=NULL; - if(vo_spudec){ - vo_draw_spudec(dxs,dys,draw_alpha); +mp_osd_obj_t* new_osd_obj(int type){ + mp_osd_obj_t* osd=malloc(sizeof(mp_osd_obj_t)); + memset(osd,0,sizeof(mp_osd_obj_t)); + osd->next=vo_osd_list; + vo_osd_list=osd; + osd->type=type; + return osd; +} + +void free_osd_list(){ + mp_osd_obj_t* obj=vo_osd_list; + while(obj){ + mp_osd_obj_t* next=obj->next; + free(obj); + obj=next; } + vo_osd_list=NULL; +} - if(vo_vobsub){ - vo_draw_vobsub(dxs,dys,draw_alpha); +int vo_update_osd(int dxs,int dys){ + mp_osd_obj_t* obj=vo_osd_list; + int chg=0; + while(obj){ + if(dxs!=obj->dxs || dys!=obj->dys || obj->flags&OSDFLAG_FORCE_UPDATE){ + int vis=obj->flags&OSDFLAG_VISIBLE; + switch(obj->type){ + case OSDTYPE_SUBTITLE: + vo_update_text_sub(obj,dxs,dys); + break; + case OSDTYPE_PROGBAR: + vo_update_text_progbar(obj,dxs,dys); + break; + case OSDTYPE_SPU: + if(vo_spudec && spudec_visible(vo_spudec)) + obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; + else + obj->flags&=~OSDFLAG_VISIBLE; + break; + case OSDTYPE_VOBSUB: + if(vo_vobsub) + obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; + else + obj->flags&=~OSDFLAG_VISIBLE; + break; + case OSDTYPE_OSD: + if(vo_font && vo_osd_text && vo_osd_text[0]) + obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; + else + obj->flags&=~OSDFLAG_VISIBLE; + break; + } + // check if visibility changed: + if(vis != (obj->flags&OSDFLAG_VISIBLE) ) obj->flags|=OSDFLAG_CHANGED; + // remove the cause of updating: + obj->dxs=dxs; obj->dys=dys; + obj->flags&=~OSDFLAG_FORCE_UPDATE; + } + if(obj->flags&OSDFLAG_CHANGED){ + chg|=1<type; + mp_msg(MSGT_OSD,MSGL_DBG2,"OSD chg: %d V: %s pb:%d \n",obj->type,(obj->flags&OSDFLAG_VISIBLE)?"yes":"no",vo_osd_progbar_type); + } + obj=obj->next; } + return chg; +} - if(!vo_font) return; // no font - +void vo_init_osd(){ if(!draw_alpha_init_flag){ draw_alpha_init_flag=1; vo_draw_alpha_init(); } + if(vo_osd_list) free_osd_list; + // temp hack, should be moved to mplayer/mencoder later + new_osd_obj(OSDTYPE_OSD); + new_osd_obj(OSDTYPE_SUBTITLE); + new_osd_obj(OSDTYPE_PROGBAR); + new_osd_obj(OSDTYPE_SPU); + new_osd_obj(OSDTYPE_VOBSUB); +} - if(vo_osd_text){ - vo_draw_text_osd(dxs,dys,draw_alpha); - } +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)){ + mp_osd_obj_t* obj=vo_osd_list; + + vo_update_osd(dxs,dys); - if(vo_sub){ - vo_draw_text_sub(dxs,dys,draw_alpha); + while(obj){ + if(obj->flags&OSDFLAG_VISIBLE) + switch(obj->type){ + case OSDTYPE_SPU: + spudec_draw_scaled(vo_spudec, dxs, dys, draw_alpha); // FIXME + break; + case OSDTYPE_VOBSUB: + vobsub_draw(vo_vobsub, dxs, dys, draw_alpha); // FIXME + break; + case OSDTYPE_OSD: + vo_draw_text_osd(dxs,dys,draw_alpha); + break; + case OSDTYPE_SUBTITLE: + vo_draw_text_sub(obj,draw_alpha); + break; + case OSDTYPE_PROGBAR: + vo_draw_text_progbar(obj,draw_alpha); + break; + } + obj->old_bbox=obj->bbox; + obj->flags&=~OSDFLAG_CHANGED; + + obj=obj->next; } - - if(vo_osd_progbar_type>=0 && vo_font->font[OSD_PB_0]>=0){ - vo_draw_text_progbar(dxs,dys,draw_alpha); - } +} -} - static int vo_osd_changed_status = 0; int vo_osd_changed(int new_value) { + mp_osd_obj_t* obj=vo_osd_list; int ret = vo_osd_changed_status; vo_osd_changed_status = new_value; + + while(obj){ + if(obj->type==new_value) obj->flags|=OSDFLAG_FORCE_UPDATE; + obj=obj->next; + } + return ret; } + diff -r 6890819bc0dc -r 86663f1b9b00 libvo/sub.h --- a/libvo/sub.h Mon Apr 15 18:04:18 2002 +0000 +++ b/libvo/sub.h Mon Apr 15 19:17:12 2002 +0000 @@ -2,6 +2,48 @@ #ifndef __MPLAYER_SUB_H #define __MPLAYER_SUB_H +typedef struct mp_osd_bbox_s { + int x1,y1,x2,y2; +} mp_osd_bbox_t; + +#define OSDTYPE_OSD 1 +#define OSDTYPE_SUBTITLE 2 +#define OSDTYPE_PROGBAR 3 +#define OSDTYPE_SPU 4 +#define OSDTYPE_VOBSUB 5 + +#define OSDFLAG_VISIBLE 1 +#define OSDFLAG_CHANGED 2 +#define OSDFLAG_BBOX 4 +#define OSDFLAG_OLD_BBOX 8 +#define OSDFLAG_FORCE_UPDATE 16 + +#define MAX_UCS 1600 +#define MAX_UCSLINES 16 + +typedef struct mp_osd_obj_s { + struct mp_osd_obj_s* next; + unsigned char type; + unsigned char alignment; // 2 bits: x;y percents, 2 bits: x;y relative to parent; 2 bits: alignment left/right/center + unsigned short flags; + int x,y; + int dxs,dys; + mp_osd_bbox_t bbox; // bounding box + mp_osd_bbox_t old_bbox; // the renderer will save bbox here + union { + struct { + void* sub; // value of vo_sub at last update + int utbl[MAX_UCS+1]; // subtitle text + int xtbl[MAX_UCSLINES]; // x positions + int lines; // no. of lines + } subtitle; + struct { + int elems; + } progbar; + } params; +} mp_osd_obj_t; + + #if 0 // disable subtitles: @@ -48,6 +90,8 @@ //extern void vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); extern 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_init_osd(); +int vo_update_osd(int dxs,int dys); int vo_osd_changed(int new_value); #endif diff -r 6890819bc0dc -r 86663f1b9b00 mp_msg.h --- a/mp_msg.h Mon Apr 15 18:04:18 2002 +0000 +++ b/mp_msg.h Mon Apr 15 19:17:12 2002 +0000 @@ -68,6 +68,8 @@ #define MSGT_VFILTER 29 +#define MSGT_OSD 30 + #define MSGT_MAX 64 void mp_msg_init(); diff -r 6890819bc0dc -r 86663f1b9b00 mplayer.c --- a/mplayer.c Mon Apr 15 18:04:18 2002 +0000 +++ b/mplayer.c Mon Apr 15 19:17:12 2002 +0000 @@ -669,6 +669,8 @@ } #endif + vo_init_osd(); + #if defined(HAVE_LIRC) && ! defined(HAVE_NEW_INPUT) lirc_mp_setup(); inited_flags|=INITED_LIRC; @@ -1798,7 +1800,9 @@ #ifdef USE_OSD if(osd_visible){ - if (!--osd_visible){ vo_osd_progbar_type=-1; // disable + if (!--osd_visible){ + vo_osd_progbar_type=-1; // disable + vo_osd_changed(OSDTYPE_PROGBAR); if (osd_function != OSD_PAUSE) osd_function = OSD_PLAY; } @@ -2038,6 +2042,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_VOLUME; vo_osd_progbar_value=(mixer_getbothvolume()*256.0)/100.0; + vo_osd_changed(OSDTYPE_PROGBAR); //printf("volume: %d\n",vo_osd_progbar_value); } #endif @@ -2086,6 +2091,7 @@ vo_osd_progbar_type=OSD_CONTRAST; vo_osd_progbar_value=((v_cont)<<8)/100; if(v_hw_equ_cap) vo_osd_progbar_value = ((v_cont+100)<<8)/200; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2114,6 +2120,7 @@ vo_osd_progbar_type=OSD_BRIGHTNESS; vo_osd_progbar_value=((v_bright)<<8)/100; if(v_hw_equ_cap) vo_osd_progbar_value = ((v_bright+100)<<8)/200; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2142,6 +2149,7 @@ vo_osd_progbar_type=OSD_HUE; vo_osd_progbar_value=((v_hue)<<8)/100; if(v_hw_equ_cap) vo_osd_progbar_value = ((v_hue+100)<<8)/200; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2170,6 +2178,7 @@ vo_osd_progbar_type=OSD_SATURATION; vo_osd_progbar_value=((v_saturation)<<8)/100; if(v_hw_equ_cap) vo_osd_progbar_value = ((v_saturation+100)<<8)/200; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2302,6 +2311,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_VOLUME; vo_osd_progbar_value=(mixer_getbothvolume()*256.0)/100.0; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } break; @@ -2322,6 +2332,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_CONTRAST; vo_osd_progbar_value=((v_cont)<<8)/100; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2344,6 +2355,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_BRIGHTNESS; vo_osd_progbar_value=((v_bright)<<8)/100; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2366,6 +2378,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_HUE; vo_osd_progbar_value=((v_hue)<<8)/100; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2388,6 +2401,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_SATURATION; vo_osd_progbar_value=((v_saturation)<<8)/100; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2701,6 +2715,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=0; vo_osd_progbar_value=(demuxer->filepos-demuxer->movi_start)/len; + vo_osd_changed(OSDTYPE_PROGBAR); } } #endif @@ -2745,6 +2760,7 @@ osd_visible=sh_video->fps; // 1 sec vo_osd_progbar_type=OSD_VOLUME; vo_osd_progbar_value=( ( guiIntfStruct.Volume ) * 256.0 ) / 100.0; + vo_osd_changed(OSDTYPE_PROGBAR); } #endif } @@ -2787,12 +2803,12 @@ if(strcmp(vo_osd_text, osd_text_tmp)) { strcpy(vo_osd_text, osd_text_tmp); - vo_osd_changed(1); + vo_osd_changed(OSDTYPE_OSD); } } else { if(vo_osd_text) { vo_osd_text=NULL; - vo_osd_changed(1); + vo_osd_changed(OSDTYPE_OSD); } } // for(i=1;i<=11;i++) osd_text_buffer[10+i]=i;osd_text_buffer[10+i]=0; @@ -2821,7 +2837,7 @@ vobsub_process(vo_vobsub,d_video->pts+sub_delay); /* Don't know how to detect wether the sub has changed or not */ - vo_osd_changed(1); + vo_osd_changed(OSDTYPE_VOBSUB); current_module=NULL; } @@ -2846,7 +2862,7 @@ spudec_heartbeat(vo_spudec,90000*d_video->pts); /* Don't know how to detect wether the sub has changed or not */ - vo_osd_changed(1); + vo_osd_changed(OSDTYPE_SPU); current_module=NULL; } diff -r 6890819bc0dc -r 86663f1b9b00 spudec.c --- a/spudec.c Mon Apr 15 18:04:18 2002 +0000 +++ b/spudec.c Mon Apr 15 19:17:12 2002 +0000 @@ -368,6 +368,13 @@ ((spudec_handle_t *)this)->now_pts = pts100; } +int spudec_visible(void *this){ + spudec_handle_t *spu = (spudec_handle_t *)this; + int ret=(spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts); +// printf("spu visible: %d \n",ret); + return ret; +} + void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) { spudec_handle_t *spu = (spudec_handle_t *)this; diff -r 6890819bc0dc -r 86663f1b9b00 spudec.h --- a/spudec.h Mon Apr 15 18:04:18 2002 +0000 +++ b/spudec.h Mon Apr 15 19:17:12 2002 +0000 @@ -10,6 +10,7 @@ void *spudec_new(unsigned int *palette); void spudec_free(void *this); void spudec_reset(void *this); // called after seek +int spudec_visible(void *this); // check if spu is visible #endif