[MPlayer-dev-eng] [PATCH] Teletext support try3 (5/5, rendering)
Vladimir Voroshilov
voroshil at gmail.com
Mon Jul 16 20:45:14 CEST 2007
2007/7/15, Michael Niedermayer <michaelni at gmx.at>:
> Hi
>
> On Sun, Jul 15, 2007 at 05:59:49PM +0700, Vladimir Voroshilov wrote:
> [...]
> > 2. Troubles with transparent mode rendering (funny colors, looks like
> > overflow somewhere at alpha calculation).
>
> IIRC you MUST scale your color down so it cant overflow with the selected
> alpha so with 50% alpha you can just use 0..127
>
Added color scale.
No more alpha overflow.
Updated version is attached.
--
Regards,
Vladimir Voroshilov mailto:voroshil at gmail.com
JID: voroshil at gmail.com, voroshil at jabber.ru
ICQ: 95587719
-------------- next part --------------
Index: libvo/sub.h
===================================================================
--- libvo/sub.h (revision 23790)
+++ libvo/sub.h (working copy)
@@ -2,6 +2,10 @@
#ifndef MPLAYER_SUB_H
#define MPLAYER_SUB_H
+#ifdef HAVE_TV_TELETEXT
+#include "libmpcodecs/mp_image.h"
+#endif
+
typedef struct mp_osd_bbox_s {
int x1,y1,x2,y2;
} mp_osd_bbox_t;
@@ -11,6 +15,7 @@
#define OSDTYPE_PROGBAR 3
#define OSDTYPE_SPU 4
#define OSDTYPE_DVDNAV 5
+#define OSDTYPE_TELETEXT 6
#define OSDFLAG_VISIBLE 1
#define OSDFLAG_CHANGED 2
@@ -64,6 +69,12 @@
extern unsigned char* vo_osd_text;
+#ifdef HAVE_TV_TELETEXT
+extern void* vo_osd_teletext_page;
+extern int vo_osd_teletext_half;
+extern int vo_osd_teletext_mode;
+#endif
+
extern int vo_osd_progbar_type;
extern int vo_osd_progbar_value; // 0..255
Index: libvo/sub.c
===================================================================
--- libvo/sub.c (revision 23790)
+++ libvo/sub.c (working copy)
@@ -14,6 +14,10 @@
#define OSD_NAV_BOX_ALPHA 0x7f
#endif
+#ifdef HAVE_TV_TELETEXT
+#include "stream/tv.h"
+#endif
+
#include "mplayer.h"
#include "mp_msg.h"
#include "help_mp.h"
@@ -68,6 +72,11 @@
font_desc_t* sub_font=NULL;
unsigned char* vo_osd_text=NULL;
+#ifdef HAVE_TV_TELETEXT
+void* vo_osd_teletext_page=NULL;
+int vo_osd_teletext_half = 0;
+int vo_osd_teletext_mode=0;
+#endif
int sub_unicode=0;
int sub_utf8=0;
int sub_pos=100;
@@ -230,6 +239,234 @@
}
#endif
+#ifdef HAVE_TV_TELETEXT
+inline static void vo_update_text_teletext(mp_osd_obj_t *obj, int dxs, int dys)
+{
+ int h=0,w=0,i,j,font;
+ int wm,hm;
+ int color;
+ int x,y,x0,y0;
+ int cols,rows;
+ int wm12;
+ int hm13;
+ int hm23;
+ int start_row,max_rows;
+ int b,ax[6],ay[6],aw[6],ah[6];
+ tt_char tc;
+ tt_page* tp=vo_osd_teletext_page;
+ unsigned char colors[8]={1,85,150,226,70,105,179,254};
+ char* buf[9];
+
+ obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE;
+ if (!tp || !vo_osd_teletext_mode || !tp->active) {
+ obj->flags&=~OSDFLAG_VISIBLE;
+ return;
+ }
+ switch(vo_osd_teletext_half){
+ case TT_ZOOM_TOP_HALF:
+ start_row=0;
+ max_rows=VBI_ROWS/2;
+ break;
+ case TT_ZOOM_BOTTOM_HALF:
+ start_row=VBI_ROWS/2;
+ max_rows=VBI_ROWS/2;
+ break;
+ default:
+ start_row=0;
+ max_rows=VBI_ROWS;
+ break;
+ }
+ wm=0;
+ hm=vo_font->height;
+ for(i=start_row;i<max_rows;i++){
+ for(j=0;j<VBI_COLUMNS;j++){
+ tc=tp->text[i*VBI_COLUMNS+j];
+ if(!tc.ctl && !tc.gfx)
+ {
+ render_one_glyph(vo_font, tc.unicode);
+ if (wm<vo_font->width[tc.unicode])
+ wm=vo_font->width[tc.unicode];
+ }
+ }
+ }
+ wm+=vo_font->charspace;
+
+#if 0
+ hm=3*wm/2;
+ if(hm<vo_font->height){
+ hm=vo_font->height;
+ wm=2*hm/3;
+ }
+#else
+
+// if(2*hm/3<wm){
+// hm=3*wm/2;
+// }else{
+ wm=2*hm/3;
+ hm=vo_font->height+1;
+// }
+#endif
+
+ cols=dxs/wm;
+ rows=dys/hm;
+
+ if(cols>VBI_COLUMNS)
+ cols=VBI_COLUMNS;
+ if(rows>max_rows)
+ rows=max_rows;
+ w=cols*wm-vo_font->charspace;
+ h=rows*hm-vo_font->charspace;
+
+ if(w<dxs)
+ x0=(dxs-w)/2;
+ else
+ x0=0;
+ y0=0;
+
+ wm12=wm>>1;
+ hm13=hm/3;
+ hm23=hm13<<1;
+
+ ax[0]=0;
+ ay[0]=0;
+ aw[0]=wm12;
+ ah[0]=hm13;
+ ax[1]=wm12;
+ ay[1]=0;
+ aw[1]=wm-wm12;
+ ah[1]=hm13;
+ ax[2]=0;
+ ay[2]=hm13;
+ aw[2]=wm12;
+ ah[2]=hm-hm23;
+ ax[3]=wm12;
+ ay[3]=hm13;
+ aw[3]=wm-wm12;
+ ah[3]=hm-hm23;
+ ax[4]=0;
+ ay[4]=hm-hm13;
+ aw[4]=wm12;
+ ah[4]=hm13;
+ ax[5]=wm12;
+ ay[5]=hm-hm13;
+ aw[5]=wm-wm12;
+ ah[5]=hm13;
+
+ obj->x = 0;
+ obj->y = 0;
+ obj->bbox.x1 = x0;
+ obj->bbox.y1 = 0;
+ obj->bbox.x2 = x0+w+wm;
+ obj->bbox.y2 = h;
+ obj->flags |= OSDFLAG_BBOX;
+ alloc_buf(obj);
+
+ for(i=0;i<9;i++)
+ buf[i]=malloc(wm*hm*4);
+
+ //alpha
+ if(vo_osd_teletext_mode==TT_MODE_OPAQUE ||vo_osd_teletext_mode==TT_MODE_OPAQUE_INV)
+ color=1;
+ else
+ color=200;
+ memset(buf[8],color,4*wm*hm);
+ //colors
+ if(vo_osd_teletext_mode==TT_MODE_OPAQUE ||vo_osd_teletext_mode==TT_MODE_TRANSPARENT){
+ //sorted by luma // BGR
+ for(i=0;i<8;i++)
+ memset(buf[i],1.0*(255-color)*colors[i]/255,4*wm*hm);
+ }else{
+ for(i=0;i<8;i++)
+ memset(buf[i],1.0*(255-color)*colors[7-i]/255,4*wm*hm);
+ }
+ y=-vo_font->charspace;
+ for(i=0;i<rows;i++){
+ x=x0;
+ for(j=0;j<cols;j++){
+ tc=tp->text[(i+start_row)*VBI_COLUMNS+j];
+ if(!tc.gfx){
+/* Rendering one text character */
+ draw_alpha_buf(obj,x,y,wm,hm,buf[tc.bg],buf[8],0);
+ if(tc.unicode==0x20 || tc.unicode==0x00 || tc.ctl){ //space
+ draw_alpha_buf(obj,x,y,wm,hm,buf[tc.bg],buf[8],0);
+ }else{
+ if ((font=vo_font->font[tc.unicode])>=0 && y+hm<dys){
+ draw_alpha_buf(obj,
+ x,y+vo_font->charspace,
+ wm-vo_font->charspace/2,hm-vo_font->charspace,
+ vo_font->pic_b[font]->bmp+vo_font->start[tc.unicode],
+ vo_font->pic_a[font]->bmp+vo_font->start[tc.unicode],
+ vo_font->pic_a[font]->w);
+ }
+ }
+ }else{
+/*
+Rendering one graphics character
+TODO: support for separated graphics symbols (where six rectangles does not touch each other)
+
+ +--+ +--+ 87654321
+ |01| |12| --------
+ |10| <= |34| <= 00100110 <= 0x26
+ |01| |56|
+ +--+ +--+
+
+(0:wm/2) (wm/2:wm-wm/2)
+
+********** *********** (0:hm/3)
+*** **** **** ****
+*** 1 **** **** 2 ****
+*** **** **** ****
+********** ***********
+********** ***********
+
+********** *********** (hm/3:hm-2*hm/3)
+********** ***********
+*** **** **** ****
+*** 3 **** **** 4 ****
+*** **** **** ****
+********** ***********
+********** ***********
+********** ***********
+
+********** *********** (hm-hm/3:hm/3)
+*** **** **** ****
+*** 5 **** **** 6 ****
+*** **** **** ****
+********** ***********
+********** ***********
+
+*/
+ if(tc.gfx>1){ //separated gfx
+ for(b=0;b<6;b++){
+ color=(tc.unicode>>b)&1?tc.fg:tc.bg;
+ draw_alpha_buf(obj,x+ax[b]+1,y+ay[b]+1,aw[b]-2,ah[b]-2,buf[color],buf[8],0);
+ }
+ //separated gfx (background borders)
+ //vertical
+ draw_alpha_buf(obj,x ,y,1,hm,buf[tc.bg],buf[8],0);
+ draw_alpha_buf(obj,x+ax[1]-1,y,2,hm,buf[tc.bg],buf[8],0);
+ draw_alpha_buf(obj,x+ax[1]+aw[1]-1,y,wm-ax[1]-aw[1]+1,hm,buf[tc.bg],buf[8],0);
+ //horizontal
+ draw_alpha_buf(obj,x,y ,wm,1,buf[tc.bg],buf[8],0);
+ draw_alpha_buf(obj,x,y+ay[0]+ah[0]-1,wm,2,buf[tc.bg],buf[8],0);
+ draw_alpha_buf(obj,x,y+ay[2]+ah[2]-1,wm,2,buf[tc.bg],buf[8],0);
+ draw_alpha_buf(obj,x,y+ay[4]+ah[4]-1,wm,hm-ay[4]-ah[4]+1,buf[tc.bg],buf[8],0);
+ }else{
+ for(b=0;b<6;b++){
+ color=(tc.unicode>>b)&1?tc.fg:tc.bg;
+ draw_alpha_buf(obj,x+ax[b],y+ay[b],aw[b],ah[b],buf[color],buf[8],0);
+ }
+ }
+ }
+ x+=wm;
+ }
+ y+=hm;
+ }
+ for(i=0;i<9;i++)
+ free(buf[i]);
+}
+#endif
+
int vo_osd_progbar_type=-1;
int vo_osd_progbar_value=100; // 0..256
@@ -866,6 +1103,11 @@
case OSDTYPE_SUBTITLE:
vo_update_text_sub(obj,dxs,dys);
break;
+#ifdef HAVE_TV_TELETEXT
+ case OSDTYPE_TELETEXT:
+ vo_update_text_teletext(obj,dxs,dys);
+ break;
+#endif
case OSDTYPE_PROGBAR:
vo_update_text_progbar(obj,dxs,dys);
break;
@@ -933,6 +1175,9 @@
#ifdef USE_DVDNAV
new_osd_obj(OSDTYPE_DVDNAV);
#endif
+#if HAVE_TV_TELETEXT
+ new_osd_obj(OSDTYPE_TELETEXT);
+#endif
#ifdef HAVE_FREETYPE
force_load_font = 1;
#endif
@@ -971,6 +1216,9 @@
#ifdef USE_DVDNAV
case OSDTYPE_DVDNAV:
#endif
+#ifdef HAVE_TV_TELETEXT
+ case OSDTYPE_TELETEXT:
+#endif
case OSDTYPE_OSD:
case OSDTYPE_SUBTITLE:
case OSDTYPE_PROGBAR:
Index: mplayer.c
===================================================================
--- mplayer.c (revision 23790)
+++ mplayer.c (working copy)
@@ -1622,6 +1622,7 @@
decoded_frame = decode_video(sh_video, start, in_size, 0, pts);
if (decoded_frame) {
update_subtitles(sh_video, mpctx->d_sub, 0);
+ update_teletext(sh_video, mpctx->demuxer, 0);
update_osd_msg();
current_module = "filter video";
if (filter_video(sh_video, decoded_frame, sh_video->pts))
@@ -2036,6 +2037,7 @@
++total_frame_cnt;
}
update_subtitles(sh_video, mpctx->d_sub, 0);
+ update_teletext(sh_video, mpctx->demuxer, 0);
update_osd_msg();
current_module = "decode_video";
decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
@@ -2249,6 +2251,7 @@
// be completely wrong (probably 0).
mpctx->sh_video->pts = mpctx->d_video->pts;
update_subtitles(mpctx->sh_video, mpctx->d_sub, 1);
+ update_teletext(mpctx->sh_video, mpctx->demuxer, 1);
}
if (mpctx->sh_audio) {
Index: mpcommon.c
===================================================================
--- mpcommon.c (revision 23790)
+++ mpcommon.c (working copy)
@@ -7,6 +7,9 @@
#include "libvo/video_out.h"
#include "spudec.h"
#include "vobsub.h"
+#ifdef HAVE_TV_TELETEXT
+#include "stream/tv.h"
+#endif
double sub_last_pts = -303;
@@ -138,3 +141,19 @@
}
current_module=NULL;
}
+
+void update_teletext(sh_video_t *sh_video, demuxer_t *demuxer, int reset)
+{
+#ifdef HAVE_TV_TELETEXT
+ tvi_handle_t* tvh=demuxer->priv;
+ if (demuxer->type != DEMUXER_TYPE_TV || !tvh) return;
+
+ if(tvh->functions->control(tvh->priv,TV_VBI_CONTROL_GET_VBIPAGE,&vo_osd_teletext_page)!=TVI_CONTROL_TRUE)
+ vo_osd_teletext_page=NULL;
+ if(tvh->functions->control(tvh->priv,TV_VBI_CONTROL_GET_HALF_PAGE,&vo_osd_teletext_half)!=TVI_CONTROL_TRUE)
+ vo_osd_teletext_half=0;
+ if(tvh->functions->control(tvh->priv,TV_VBI_CONTROL_GET_MODE,&vo_osd_teletext_mode)!=TVI_CONTROL_TRUE)
+ vo_osd_teletext_mode=0;
+ vo_osd_changed(OSDTYPE_TELETEXT);
+#endif
+}
More information about the MPlayer-dev-eng
mailing list