mirror of
https://github.com/mpv-player/mpv
synced 2024-12-18 21:06:00 +00:00
Teletext support for tv:// (v4l and v4l2 only)
modified patch from Otvos Attila oattila at chello dot hu Module uses zvbi library for all low-level VBI operations (like I/O with vbi device, converting vbi pages into usefull vbi_page stuctures, rendering them into RGB32 images). All teletext related stuff (except properties, slave commands and rendering osd in text mode or RGB32 rendered teletext pages in spu mode) is implemented in tvi_vbi.c New properties: teletext_page - switching between pages teletext_mode - switch between on/off/opaque/transparent modes teletext_format - (currently read-only) allows to get format info (black/white,gray,text) teletext_half_page - trivial zooming (displaying top/bottom half of teletext page) New slave commands: teletext_add_dec - user interface for jumping to any page by editing page number interactively teletext_go_link - goes though links, specified on current page git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@23530 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
990b33b1c2
commit
83a2c50ef9
@ -51,6 +51,7 @@ MPlayer (1.0)
|
||||
* support H.264 over RTSP
|
||||
* "device" and "adevice" suboptions now works for *BSD BT848 tv driver too
|
||||
* dvdnav:// now depends on mplayer's fork of libdvdnav
|
||||
* Teletext support for tv:// (v4l and v4l2 only)
|
||||
|
||||
FFmpeg/libavcodec:
|
||||
* Intel Music coder audio decoder
|
||||
|
@ -421,6 +421,26 @@ Confirm choice.
|
||||
.PP
|
||||
.RS
|
||||
.
|
||||
(The following keys are only valid if teletext support is enabled during
|
||||
compilation: they are used for controlling TV teletext)
|
||||
.RE
|
||||
.PP
|
||||
.PD 0
|
||||
.RS
|
||||
.IPs "X"
|
||||
Switch teletext between on, off and transparent mode.
|
||||
.IPs "Q"
|
||||
Next teletext page.
|
||||
.IPs "W"
|
||||
Previous teletext page.
|
||||
.IPs "E"
|
||||
In text mode flips top or bottom piece of page otherwise
|
||||
zooms teletext page: top or bottom or normal.
|
||||
.RE
|
||||
.PD 1
|
||||
.PP
|
||||
.RS
|
||||
.
|
||||
.TP
|
||||
.B mouse control
|
||||
.PD 0
|
||||
@ -1851,6 +1871,12 @@ MJPEG compression:
|
||||
.IPs quality=<0\-100>
|
||||
Choose the quality of the JPEG compression
|
||||
(< 60 recommended for full size).
|
||||
.IPs tdevice=<value> (default: none)
|
||||
Specify TV teletext device (example: /dev/\:vbi0).
|
||||
.IPs tformat=<text|bw|gray|color> (default: gray)
|
||||
Specify TV teletext display mode. (Note: color mode requires color SPU support.)
|
||||
.IPs tpage=<100-999> (default: 100)
|
||||
Specify starting TV teletext page number .
|
||||
.RE
|
||||
.
|
||||
.TP
|
||||
|
@ -77,6 +77,7 @@ MPlayer code:
|
||||
* libmpdemux: Roberto Togni, Nico Sabbi
|
||||
* libmpcodecs: Roberto Togni
|
||||
* TV input/capture: Vladimir Voroshilov
|
||||
* TV teletext: Vladimir Voroshilov
|
||||
* network streaming: Roberto Togni, Nico Sabbi, Benjamin Zores
|
||||
* DVD/VOB subtitles: None
|
||||
* config files & commandline parser: Alban Bedel
|
||||
|
@ -314,6 +314,19 @@ switch_vsync [value]
|
||||
Toggle vsync (1 == on, 0 == off). If [value] is not provided,
|
||||
vsync status is inverted.
|
||||
|
||||
teletext_add_dec <value>
|
||||
On/off teletext page number editing mode and append given digit to
|
||||
previously entered one
|
||||
0..9 - append apropriate digit (enables editing mode if called from normal mode, and
|
||||
switches to normal mode when third digit is entered.
|
||||
- - delete last digit from page number (backspace amulation, works only in page number
|
||||
editing mode)
|
||||
|
||||
teletext_go_link <value>
|
||||
Follow given links on current teletext page
|
||||
0 - go to initial page (specified by -tv tpage= parameter)
|
||||
1..6 - follow given link
|
||||
|
||||
tv_step_channel <channel>
|
||||
Select next/previous TV channel.
|
||||
|
||||
@ -446,4 +459,8 @@ tv_brightness int -100 100 X X X
|
||||
tv_contrast int -100 100 X X X
|
||||
tv_saturation int -100 100 X X X
|
||||
tv_hue int -100 100 X X X
|
||||
|
||||
teletext_page int 100 999 X X X
|
||||
teletext_mode int 0 3 X X X 0 - off, 1 - opaque, 2 - transparent,
|
||||
3 - transparent inverted (bw format)
|
||||
teletext_format int 0 3 X 0 - text, 1 - b/w, 2 - gray, 3 - color
|
||||
teletext_half_page int 0 2 X X X 0 - off, 1 - top half, 2- bottom half
|
||||
|
@ -459,6 +459,11 @@ m_option_t tvopts_conf[]={
|
||||
{"alsa", &tv_param_alsa, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
#endif
|
||||
{"adevice", &tv_param_adevice, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
#endif
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
{"tdevice", &tv_param_tdevice, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{"tformat", &tv_param_tformat, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{"tpage", &tv_param_tpage, CONF_TYPE_INT, CONF_RANGE, 100, 999, NULL},
|
||||
#endif
|
||||
{"audioid", &tv_param_audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
|
||||
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||
|
149
command.c
149
command.c
@ -1415,6 +1415,134 @@ static int mp_property_tv_color(m_option_t * prop, int action, void *arg,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
/// teletext page (RW)
|
||||
static int mp_property_teletext_page(m_option_t * prop, int action, void *arg,
|
||||
MPContext * mpctx)
|
||||
{
|
||||
int val,result;
|
||||
tvi_handle_t *tvh = mpctx->demuxer->priv;
|
||||
if (mpctx->demuxer->type != DEMUXER_TYPE_TV || !tvh || !tvh->priv_vbi)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
M_PROPERTY_CLAMP(prop, *(int *) arg);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_SET_PAGE, arg);
|
||||
break;
|
||||
case M_PROPERTY_GET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_GET_PAGE, arg);
|
||||
break;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
val = (arg ? *(int *) arg : 1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_STEP_PAGE, &val);
|
||||
break;
|
||||
default:
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
return (result==TVI_CONTROL_TRUE?M_PROPERTY_OK:M_PROPERTY_ERROR);
|
||||
}
|
||||
/// VBI teletext mode (RW)
|
||||
static int mp_property_teletext_mode(m_option_t * prop, int action, void *arg,
|
||||
MPContext * mpctx)
|
||||
{
|
||||
int val,result;
|
||||
tvi_handle_t *tvh = mpctx->demuxer->priv;
|
||||
if (mpctx->demuxer->type != DEMUXER_TYPE_TV || !tvh || !tvh->priv_vbi)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
M_PROPERTY_CLAMP(prop, *(int *) arg);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_SET_MODE, arg);
|
||||
break;
|
||||
case M_PROPERTY_GET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_GET_MODE, arg);
|
||||
break;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
val = (arg ? *(int *) arg : 1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_STEP_MODE, &val);
|
||||
break;
|
||||
default:
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
return (result==TVI_CONTROL_TRUE?M_PROPERTY_OK:M_PROPERTY_ERROR);
|
||||
}
|
||||
/// VBI teletext format (R)
|
||||
static int mp_property_teletext_format(m_option_t * prop, int action, void *arg,
|
||||
MPContext * mpctx)
|
||||
{
|
||||
int val,result;
|
||||
tvi_handle_t *tvh = mpctx->demuxer->priv;
|
||||
if (mpctx->demuxer->type != DEMUXER_TYPE_TV || !tvh || !tvh->priv_vbi)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_GET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_GET_FORMAT, arg);
|
||||
break;
|
||||
case M_PROPERTY_SET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
M_PROPERTY_CLAMP(prop, *(int *) arg);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_SET_FORMAT, arg);
|
||||
break;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
val = (arg ? *(int *) arg : 1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_STEP_FORMAT, &val);
|
||||
break;
|
||||
default:
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
return (result==TVI_CONTROL_TRUE?M_PROPERTY_OK:M_PROPERTY_ERROR);
|
||||
}
|
||||
|
||||
/// VBI teletext half-page mode (RW)
|
||||
static int mp_property_teletext_half_page(m_option_t * prop, int action, void *arg,
|
||||
MPContext * mpctx)
|
||||
{
|
||||
int val,result;
|
||||
tvi_handle_t *tvh = mpctx->demuxer->priv;
|
||||
if (mpctx->demuxer->type != DEMUXER_TYPE_TV || !tvh || !tvh->priv_vbi)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_GET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_GET_HALF_PAGE, arg);
|
||||
break;
|
||||
case M_PROPERTY_SET:
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
M_PROPERTY_CLAMP(prop, *(int *) arg);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_SET_HALF_PAGE, arg);
|
||||
break;
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
val = (arg ? *(int *) arg : 1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
|
||||
result=tv_teletext_control(tvh, TVI_CONTROL_VBI_STEP_HALF_PAGE, &val);
|
||||
break;
|
||||
default:
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
return (result==TVI_CONTROL_TRUE?M_PROPERTY_OK:M_PROPERTY_ERROR);
|
||||
}
|
||||
#endif /* HAVE_TV_TELETEXT */
|
||||
|
||||
///@}
|
||||
|
||||
/// All properties available in MPlayer.
|
||||
@ -1540,6 +1668,17 @@ static m_option_t mp_properties[] = {
|
||||
M_OPT_RANGE, -100, 100, (void *) TV_COLOR_HUE },
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
{ "teletext_page", mp_property_teletext_page, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, -999, 999, NULL },
|
||||
{ "teletext_mode", mp_property_teletext_mode, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, 0, 3, NULL },
|
||||
{ "teletext_format", mp_property_teletext_format, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, 0, 3, NULL },
|
||||
{ "teletext_half_page", mp_property_teletext_half_page, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, 0, 2, NULL },
|
||||
#endif
|
||||
|
||||
{ NULL, NULL, NULL, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
@ -2233,6 +2372,16 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd)
|
||||
if (mpctx->file_format == DEMUXER_TYPE_TV)
|
||||
tv_step_chanlist((tvi_handle_t *) (mpctx->demuxer->priv));
|
||||
break;
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
case MP_CMD_TV_TELETEXT_ADD_DEC:
|
||||
if (mpctx->file_format == DEMUXER_TYPE_TV)
|
||||
tv_teletext_add_dec((tvi_handle_t *) (mpctx->demuxer->priv),cmd->args[0].v.s);
|
||||
break;
|
||||
case MP_CMD_TV_TELETEXT_GO_LINK:
|
||||
if (mpctx->file_format == DEMUXER_TYPE_TV)
|
||||
tv_teletext_go_link((tvi_handle_t *) (mpctx->demuxer->priv),cmd->args[0].v.i);
|
||||
break;
|
||||
#endif /* HAVE_TV_TELETEXT */
|
||||
#endif /* USE_TV */
|
||||
|
||||
case MP_CMD_SUB_LOAD:
|
||||
|
30
configure
vendored
30
configure
vendored
@ -240,6 +240,7 @@ Optional features:
|
||||
--disable-tv-v4l1 disable Video4Linux TV interface [autodetect]
|
||||
--disable-tv-v4l2 disable Video4Linux2 TV interface [autodetect]
|
||||
--disable-tv-bsdbt848 disable BSD BT848 interface [autodetect]
|
||||
--disable-tv-teletex disable TV teletext interface [autodetect]
|
||||
--disable-pvr disable Video4Linux2 MPEG PVR [autodetect]
|
||||
--disable-rtc disable RTC (/dev/rtc) on Linux [autodetect]
|
||||
--disable-network disable networking [enable]
|
||||
@ -588,6 +589,7 @@ _tv=yes
|
||||
_tv_v4l1=auto
|
||||
_tv_v4l2=auto
|
||||
_tv_bsdbt848=auto
|
||||
_tv_teletext=auto
|
||||
_pvr=auto
|
||||
_network=yes
|
||||
_winsock2=auto
|
||||
@ -935,6 +937,8 @@ for ac_option do
|
||||
--disable-tv-v4l1) _tv_v4l1=no ;;
|
||||
--enable-tv-v4l2) _tv_v4l2=yes ;;
|
||||
--disable-tv-v4l2) _tv_v4l2=no ;;
|
||||
--enable-tv-teletext) _tv_teletext=yes ;;
|
||||
--disable-tv-teletext) _tv_teletext=no ;;
|
||||
--enable-radio) _radio=yes ;;
|
||||
--enable-radio-capture) _radio_capture=yes ;;
|
||||
--disable-radio-capture) _radio_capture=no ;;
|
||||
@ -6685,6 +6689,28 @@ else
|
||||
fi
|
||||
echores "$_tv_v4l2"
|
||||
|
||||
echocheck "TV teletext interface"
|
||||
if test "$_tv_teletext" = auto ; then
|
||||
_tv_teletext=no
|
||||
if test linux ; then
|
||||
cat > $TMPC <<EOF
|
||||
#include <stdlib.h>
|
||||
#include <libzvbi.h>
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
cc_check && _tv_teletext=yes
|
||||
fi
|
||||
fi
|
||||
if test "$_tv_teletext" = yes ; then
|
||||
_def_tv_teletext='#define HAVE_TV_TELETEXT 1'
|
||||
_ld_extra="$_ld_extra -lzvbi"
|
||||
_inputmodules="tv-teletext $_inputmodules"
|
||||
else
|
||||
_noinputmodules="tv-teletext $_noinputmodules"
|
||||
_def_tv_teletext='#undef HAVE_TV_TELETEXT'
|
||||
fi
|
||||
echores "$_tv_teletext"
|
||||
|
||||
|
||||
echocheck "Radio interface"
|
||||
if test "$_radio" = yes ; then
|
||||
@ -7546,6 +7572,7 @@ TV_V4L = $_tv_v4l
|
||||
TV_V4L1 = $_tv_v4l1
|
||||
TV_V4L2 = $_tv_v4l2
|
||||
TV_BSDBT848 = $_tv_bsdbt848
|
||||
TV_TELETEXT = $_tv_teletext
|
||||
AUDIO_INPUT = $_audio_input
|
||||
PVR = $_pvr
|
||||
VCD = $_vcd
|
||||
@ -8098,6 +8125,9 @@ $_def_ioctl_bt848_h_name
|
||||
/* Enable *BSD BrookTree TV interface support */
|
||||
$_def_tv_bsdbt848
|
||||
|
||||
/* Enable TV Teletext Interface support */
|
||||
$_def_tv_teletext
|
||||
|
||||
/* Enable Radio Interface support */
|
||||
$_def_radio
|
||||
|
||||
|
@ -136,6 +136,10 @@ static mp_cmd_t mp_cmds[] = {
|
||||
{ MP_CMD_LOADLIST, "loadlist", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_RUN, "run", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_VF_CHANGE_RECTANGLE, "change_rectangle", 2, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}}}},
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
{ MP_CMD_TV_TELETEXT_ADD_DEC, "teletext_add_dec", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_TV_TELETEXT_GO_LINK, "teletext_go_link",1, { { MP_CMD_ARG_INT ,{0}}, { MP_CMD_ARG_INT ,{0}}, {-1,{0}} } },
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NEW_GUI
|
||||
{ MP_CMD_GUI_LOADFILE, "gui_loadfile", 0, { {-1,{0}} } },
|
||||
@ -386,6 +390,12 @@ static mp_cmd_bind_t def_cmd_binds[] = {
|
||||
{ { 'n', 0 }, "tv_step_norm" },
|
||||
{ { 'u', 0 }, "tv_step_chanlist" },
|
||||
#endif
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
{ { 'X', 0 }, "step_property teletext_mode 1" },
|
||||
{ { 'E', 0 }, "step_property teletext_half_page 1" },
|
||||
{ { 'W', 0 }, "step_property teletext_page 1" },
|
||||
{ { 'Q', 0 }, "step_property teletext_page -1" },
|
||||
#endif
|
||||
#ifdef HAVE_JOYSTICK
|
||||
{ { JOY_AXIS0_PLUS, 0 }, "seek 10" },
|
||||
{ { JOY_AXIS0_MINUS, 0 }, "seek -10" },
|
||||
|
@ -93,6 +93,8 @@
|
||||
#define MP_CMD_STEP_PROPERTY 91
|
||||
#define MP_CMD_RADIO_STEP_FREQ 92
|
||||
#define MP_CMD_TV_STEP_FREQ 93
|
||||
#define MP_CMD_TV_TELETEXT_ADD_DEC 94
|
||||
#define MP_CMD_TV_TELETEXT_GO_LINK 95
|
||||
|
||||
#define MP_CMD_GUI_EVENTS 5000
|
||||
#define MP_CMD_GUI_LOADFILE 5001
|
||||
|
130
libvo/sub.c
130
libvo/sub.c
@ -67,6 +67,10 @@ font_desc_t* vo_font=NULL;
|
||||
font_desc_t* sub_font=NULL;
|
||||
|
||||
unsigned char* vo_osd_text=NULL;
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
unsigned char* vo_osd_teletex_text=NULL;
|
||||
int vo_osd_teletext_flip = 0;
|
||||
#endif
|
||||
int sub_unicode=0;
|
||||
int sub_utf8=0;
|
||||
int sub_pos=100;
|
||||
@ -229,6 +233,121 @@ inline static void vo_update_nav (mp_osd_obj_t *obj, int dxs, int dys) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
inline static void vo_update_text_teletext(mp_osd_obj_t *obj, int dxs, int dys)
|
||||
{
|
||||
char *p,*pe;
|
||||
char line[256];
|
||||
int h=0,w=0,i,c,w1,font,lines,endline;
|
||||
int x1,y1,x2,y2;
|
||||
unsigned char *t;
|
||||
|
||||
obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE;
|
||||
|
||||
if (vo_osd_teletex_text==NULL) {
|
||||
obj->flags&=~OSDFLAG_VISIBLE;
|
||||
return;
|
||||
}
|
||||
p=vo_osd_teletex_text;
|
||||
lines=0;
|
||||
endline=0;
|
||||
do { // calculate teletext size
|
||||
memset(line,0,sizeof(line));
|
||||
if(pe=strchr(p,'\n')) {
|
||||
if(pe-p>sizeof(line))
|
||||
strncpy(line,p,sizeof(line));
|
||||
else
|
||||
strncpy(line,p,pe-p);
|
||||
}
|
||||
else
|
||||
strncpy(line,p,sizeof(line));
|
||||
|
||||
t=line;
|
||||
w1=0;
|
||||
while (*t) {
|
||||
c = utf8_get_char(&t);
|
||||
if (!c) c++; // avoid UCS 0
|
||||
render_one_glyph(vo_font, c);
|
||||
w1+=vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
h+=vo_font->height;
|
||||
if(w1>w) w=w1;
|
||||
if(pe) pe++;
|
||||
p=pe;
|
||||
lines++;
|
||||
if(h+vo_font->height*2>dys && endline==0) endline=lines;
|
||||
} while (pe!=NULL);
|
||||
h=h+vo_font->height;
|
||||
w=w-vo_font->charspace;
|
||||
if (w>dxs){
|
||||
// calculate bbox size
|
||||
x1=0;
|
||||
x2=dxs;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1=(dxs-w)/2;
|
||||
x2=x1+w+1;
|
||||
}
|
||||
if (h>dys){
|
||||
y1=0;
|
||||
y2=dys;
|
||||
}
|
||||
else {
|
||||
y1=0;
|
||||
y2=y1+h+1;
|
||||
}
|
||||
obj->bbox.x1 = obj->x = x1;
|
||||
obj->bbox.y1 = obj->y = y1;
|
||||
obj->bbox.x2 = x2;
|
||||
obj->bbox.y2 = y2;
|
||||
obj->flags |= OSDFLAG_BBOX;
|
||||
alloc_buf(obj);
|
||||
p=vo_osd_teletex_text;
|
||||
h=y1;
|
||||
if (vo_osd_teletext_flip)
|
||||
endline=lines-endline; // bottom page
|
||||
else
|
||||
endline=0; // top page
|
||||
lines=0;
|
||||
do { // show teletext page
|
||||
memset(line,0,sizeof(line));
|
||||
if(pe=strchr(p,'\n')) {
|
||||
if(pe-p>sizeof(line))
|
||||
strncpy(line,p,sizeof(line));
|
||||
else
|
||||
strncpy(line,p,pe-p);}
|
||||
else
|
||||
strncpy(line,p,sizeof(line));
|
||||
|
||||
t=line;
|
||||
|
||||
w1=x1;
|
||||
if(lines==0 || endline==0 || lines>endline) {
|
||||
while (*t) {
|
||||
c = utf8_get_char(&t);
|
||||
if (!c) c++; // avoid UCS 0
|
||||
render_one_glyph(vo_font, c);
|
||||
if(w1+vo_font->width[c]>=x2) break;
|
||||
if ((font=vo_font->font[c])>=0)
|
||||
draw_alpha_buf(obj,w1,h,
|
||||
vo_font->width[c],
|
||||
vo_font->pic_a[font]->h,
|
||||
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);
|
||||
w1+=vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
h+=vo_font->height;
|
||||
}
|
||||
if(pe) pe++;
|
||||
p=pe;
|
||||
if(h+vo_font->height*2>dys) pe=NULL;
|
||||
lines++;
|
||||
} while (pe!=NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
int vo_osd_progbar_type=-1;
|
||||
int vo_osd_progbar_value=100; // 0..256
|
||||
|
||||
@ -859,6 +978,11 @@ int vo_update_osd(int dxs,int dys){
|
||||
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;
|
||||
@ -926,6 +1050,9 @@ void vo_init_osd(void){
|
||||
#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
|
||||
@ -963,6 +1090,9 @@ void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h,
|
||||
break;
|
||||
#ifdef USE_DVDNAV
|
||||
case OSDTYPE_DVDNAV:
|
||||
#endif
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
case OSDTYPE_TELETEXT:
|
||||
#endif
|
||||
case OSDTYPE_OSD:
|
||||
case OSDTYPE_SUBTITLE:
|
||||
|
10
libvo/sub.h
10
libvo/sub.h
@ -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 @@ typedef struct mp_osd_bbox_s {
|
||||
#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,11 @@ extern subtitle* vo_sub;
|
||||
|
||||
extern unsigned char* vo_osd_text;
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
extern unsigned char* vo_osd_teletex_text;
|
||||
extern int vo_osd_teletext_flip;
|
||||
#endif
|
||||
|
||||
extern int vo_osd_progbar_type;
|
||||
extern int vo_osd_progbar_value; // 0..255
|
||||
|
||||
|
31
mpcommon.c
31
mpcommon.c
@ -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,31 @@ void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset)
|
||||
}
|
||||
current_module=NULL;
|
||||
}
|
||||
|
||||
void update_teletext(sh_video_t *sh_video, demuxer_t *demuxer, int reset)
|
||||
{
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
int half_page;
|
||||
tvi_handle_t *tvh = demuxer->priv;
|
||||
if (demuxer->type != DEMUXER_TYPE_TV) return;
|
||||
if(!tvh) return;
|
||||
if(vo_spudec) {
|
||||
tv_teletext_img_t* img=tv_get_teletext_imgpage(tvh);
|
||||
if(img!=NULL) {
|
||||
spudec_heartbeat_teletext(vo_spudec, img);
|
||||
if(img->canvas)
|
||||
free(img->canvas);
|
||||
free(img);
|
||||
vo_osd_changed(OSDTYPE_SPU);
|
||||
vo_osd_teletex_text=NULL;
|
||||
vo_osd_changed(OSDTYPE_TELETEXT);
|
||||
return;
|
||||
}
|
||||
vo_osd_changed(OSDTYPE_SPU);
|
||||
}
|
||||
vo_osd_teletex_text=tv_get_teletext_txtpage(tvh);
|
||||
tv_teletext_control(tvh,TVI_CONTROL_VBI_GET_HALF_PAGE,&half_page);
|
||||
vo_osd_teletext_flip=half_page;
|
||||
vo_osd_changed(OSDTYPE_TELETEXT);
|
||||
#endif
|
||||
}
|
||||
|
13
mplayer.c
13
mplayer.c
@ -1040,6 +1040,10 @@ void init_vo_spudec(void) {
|
||||
spudec_set_font_factor(vo_spudec,font_factor);
|
||||
}
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
if (vo_spudec==NULL && mpctx->demuxer->type==DEMUXER_TYPE_TV)
|
||||
vo_spudec=spudec_new_scaled(NULL, mpctx->sh_video->disp_w, mpctx->sh_video->disp_h);
|
||||
#endif
|
||||
if (vo_spudec!=NULL)
|
||||
inited_flags|=INITED_SPUDEC;
|
||||
}
|
||||
@ -1622,6 +1626,7 @@ static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video)
|
||||
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 +2041,7 @@ static double update_video(int *blit_frame)
|
||||
++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 +2255,7 @@ static int seek(MPContext *mpctx, double amount, int style)
|
||||
// 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) {
|
||||
@ -3123,7 +3130,11 @@ demux_info_print(mpctx->demuxer);
|
||||
|
||||
//================== Read SUBTITLES (DVD & TEXT) ==========================
|
||||
if(vo_spudec==NULL && mpctx->sh_video &&
|
||||
(mpctx->stream->type==STREAMTYPE_DVD || mpctx->stream->type == STREAMTYPE_DVDNAV || mpctx->d_sub->id >= 0)){
|
||||
(mpctx->stream->type==STREAMTYPE_DVD || mpctx->stream->type == STREAMTYPE_DVDNAV ||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
mpctx->demuxer->type==DEMUXER_TYPE_TV ||
|
||||
#endif
|
||||
mpctx->d_sub->id >= 0)){
|
||||
init_vo_spudec();
|
||||
}
|
||||
|
||||
|
115
spudec.c
115
spudec.c
@ -29,6 +29,9 @@
|
||||
#include "avutil.h"
|
||||
#endif
|
||||
#include "libswscale/swscale.h"
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
#include "stream/tv.h"
|
||||
#endif
|
||||
|
||||
/* Valid values for spu_aamode:
|
||||
0: none (fastest, most ugly)
|
||||
@ -1185,3 +1188,115 @@ void spudec_set_hw_spu(void *this, vo_functions_t *hw_spu)
|
||||
spu->hw_spu = hw_spu;
|
||||
hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
|
||||
}
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
#define VBI_R(rgba) (((rgba) >> 0) & 0xFF)
|
||||
#define VBI_G(rgba) (((rgba) >> 8) & 0xFF)
|
||||
#define VBI_B(rgba) (((rgba) >> 16) & 0xFF)
|
||||
#define VBI_A(rgba) (((rgba) >> 24) & 0xFF)
|
||||
|
||||
|
||||
static unsigned char rgbtoy(int r, int g, int b) {
|
||||
int ret=(257*r+504*g+98*b+16000)/1000;
|
||||
return ret & 0xff;
|
||||
}
|
||||
|
||||
/// correction u and v planes half size
|
||||
#define SPU_DOUBLE_SIZE 1
|
||||
|
||||
void alloc_images(spudec_handle_t* spu, int cmode) {
|
||||
|
||||
if (spu->image_size < spu->stride * spu->height) {
|
||||
if (spu->image != NULL) {
|
||||
free(spu->image);
|
||||
spu->image_size = 0;
|
||||
}
|
||||
spu->image = malloc(2 * spu->stride * spu->height);
|
||||
if (spu->image) {
|
||||
spu->image_size = spu->stride * spu->height;
|
||||
spu->aimage = spu->image + spu->image_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Render from VBI_PIXFMT_RGBA32_LE to spu
|
||||
**/
|
||||
void spudec_heartbeat_teletext(void *this, void *imgptr)
|
||||
{
|
||||
int px,py;
|
||||
int grey,alpha,cy,cu,cv,alphauv;
|
||||
uint32_t *canvas;
|
||||
uint32_t *pin;
|
||||
spudec_handle_t *spu = (spudec_handle_t*)this;
|
||||
tv_teletext_img_t *img = (tv_teletext_img_t*)imgptr;
|
||||
unsigned char *iptr;
|
||||
unsigned char *aptr;
|
||||
int h1 = 10;
|
||||
int hs = 0;
|
||||
|
||||
if(!spu || !img)
|
||||
return;
|
||||
if(img->canvas==NULL) {
|
||||
spudec_reset(spu);
|
||||
if (spu->image)
|
||||
free(spu->image);
|
||||
spu->image=NULL;
|
||||
spu->image_size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(img->half) h1=5; // top half page
|
||||
if(img->half==2) hs=5; // bottom half page
|
||||
|
||||
spu->start_pts=0;
|
||||
spu->end_pts=0;
|
||||
spu->now_pts=1;
|
||||
spu->orig_frame_width = img->columns*12; // 1 char width 12 pixel
|
||||
spu->orig_frame_height = img->rows*h1; // 1 char height 10 pixel
|
||||
spu->scaled_frame_width = 0;
|
||||
spu->scaled_frame_height = 0;
|
||||
spu->start_col = 0;
|
||||
spu->end_col = img->columns*12;
|
||||
spu->start_row = 0;
|
||||
spu->end_row = img->rows*h1;
|
||||
spu->height = img->rows*h1;
|
||||
spu->width = img->columns*12;
|
||||
spu->height = (spu->height+3)&(~3); // round to 4
|
||||
spu->stride = (spu->width+7)&(~7); // round to 8
|
||||
|
||||
alloc_images(spu,img->tformat); // alloc images buffer
|
||||
if (spu->image == NULL) {
|
||||
spudec_reset(spu);
|
||||
return;
|
||||
}
|
||||
canvas=img->canvas; // RGBA32_LE image
|
||||
pin=canvas+(hs*img->columns*12*img->rows);
|
||||
memset(spu->image,0,spu->image_size*2);
|
||||
|
||||
for(py=0;py<img->rows*h1;py++) {
|
||||
iptr=spu->image+(py-hs)*spu->stride; // image ptr
|
||||
aptr=spu->aimage+(py-hs)*spu->stride; // alpha ptr
|
||||
for(px=0;px<img->columns*12;px++) {
|
||||
grey=rgbtoy(VBI_R(*pin),VBI_G(*pin),VBI_B(*pin)); // RGB to Y
|
||||
if(grey<=0x10) grey=0;
|
||||
alpha=VBI_A(*pin);
|
||||
switch (img->tformat) {
|
||||
case 0x01: // BW
|
||||
case 0x02: // Gray
|
||||
case 0x03: // Color (not supported)
|
||||
alpha=0x100-alpha;
|
||||
if (grey + alpha > 255) grey = 256 - alpha;
|
||||
break;
|
||||
}
|
||||
*iptr=grey; // store Y plane
|
||||
*aptr=alpha; // store alpha
|
||||
iptr++;
|
||||
aptr++;
|
||||
pin++;
|
||||
}
|
||||
}
|
||||
spu->start_pts=0;
|
||||
spu->end_pts=UINT_MAX;
|
||||
}
|
||||
#endif
|
||||
|
3
spudec.h
3
spudec.h
@ -20,5 +20,8 @@ int spudec_changed(void *this);
|
||||
void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox);
|
||||
void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
|
||||
void spudec_set_forced_subs_only(void * const this, const unsigned int flag);
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
void spudec_heartbeat_teletext(void *this, void *imgptr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -51,6 +51,7 @@ SRCS_COMMON-$(TV) += stream_tv.c tv.c frequencies.c tvi_dummy.c
|
||||
SRCS_COMMON-$(TV_BSDBT848) += tvi_bsdbt848.c
|
||||
SRCS_COMMON-$(TV_V4L1) += tvi_v4l.c audio_in.c
|
||||
SRCS_COMMON-$(TV_V4L2) += tvi_v4l2.c audio_in.c
|
||||
SRCS_COMMON-$(TV_TELETEXT) += tvi_vbi.c
|
||||
SRCS_COMMON-$(VCD) += stream_vcd.c
|
||||
SRCS_COMMON-$(VSTREAM) += stream_vstream.c
|
||||
|
||||
|
75
stream/tv.c
75
stream/tv.c
@ -34,6 +34,10 @@
|
||||
|
||||
#include "frequencies.h"
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
#include "tvi_vbi.h"
|
||||
#endif
|
||||
|
||||
/* some default values */
|
||||
int tv_param_audiorate = 44100;
|
||||
int tv_param_noaudio = 0;
|
||||
@ -518,6 +522,9 @@ static demuxer_t* demux_open_tv(demuxer_t *demuxer)
|
||||
tv_uninit(tvh);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
if(tvh->priv_vbi) teletext_control(tvh->priv_vbi,TVI_CONTROL_VBI_START,1); //arg must be not null
|
||||
#endif
|
||||
funcs = tvh->functions;
|
||||
demuxer->priv=tvh;
|
||||
|
||||
@ -657,6 +664,12 @@ no_audio:
|
||||
static void demux_close_tv(demuxer_t *demuxer)
|
||||
{
|
||||
tvi_handle_t *tvh=(tvi_handle_t*)(demuxer->priv);
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
if(tvh->priv_vbi) {
|
||||
teletext_uninit(tvh->priv_vbi);
|
||||
tvh->priv_vbi=NULL;
|
||||
}
|
||||
#endif
|
||||
if (!tvh) return;
|
||||
tvh->functions->uninit(tvh->priv);
|
||||
demuxer->priv=NULL;
|
||||
@ -688,6 +701,10 @@ tvi_handle_t *tv_begin(void)
|
||||
tvi_driver_list[i]->name,
|
||||
tvi_driver_list[i]->author,
|
||||
tvi_driver_list[i]->comment?tvi_driver_list[i]->comment:"");
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
h->priv_vbi=teletext_init();
|
||||
#endif
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
||||
@ -773,6 +790,9 @@ int tv_set_freq(tvi_handle_t *tvh, unsigned long freq)
|
||||
mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_CurrentFrequency,
|
||||
freq, (float)freq/16);
|
||||
}
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
if (tvh->priv_vbi) teletext_control(tvh->priv_vbi,TVI_CONTROL_VBI_RESET,1); //arg must be not null
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -932,6 +952,9 @@ int tv_step_norm(tvi_handle_t *tvh)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
if (tvh->priv_vbi) teletext_control(tvh->priv_vbi,TVI_CONTROL_VBI_RESET,1); //arg must be not null
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -949,9 +972,61 @@ int tv_set_norm(tvi_handle_t *tvh, char* norm)
|
||||
mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm);
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
if (tvh->priv_vbi) teletext_control(tvh->priv_vbi,TVI_CONTROL_VBI_RESET,1); //arg must be not null
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
int tv_teletext_control(tvi_handle_t* tvh, int control, void* arg)
|
||||
{
|
||||
if (!tvh || !tvh->priv_vbi)
|
||||
return TVI_CONTROL_FALSE;
|
||||
|
||||
return teletext_control(tvh->priv_vbi,control,arg);
|
||||
}
|
||||
|
||||
int tv_teletext_add_dec(tvi_handle_t *tvh, char *dec)
|
||||
{
|
||||
if(!dec) return 0;
|
||||
if (teletext_control(tvh->priv_vbi, TVI_CONTROL_VBI_ADD_DEC, &dec)!= TVI_CONTROL_TRUE)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tv_teletext_go_link(tvi_handle_t *tvh, int linkno)
|
||||
{
|
||||
if (teletext_control(tvh->priv_vbi, TVI_CONTROL_VBI_GO_LINK, &linkno)!= TVI_CONTROL_TRUE)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* tv_get_teletext_vbipage(tvi_handle_t *tvh)
|
||||
{
|
||||
void* page = NULL;
|
||||
if (teletext_control(tvh->priv_vbi, TVI_CONTROL_VBI_GET_VBIPAGE, &page)!= TVI_CONTROL_TRUE)
|
||||
return NULL;
|
||||
return page;
|
||||
}
|
||||
|
||||
char* tv_get_teletext_txtpage(tvi_handle_t *tvh)
|
||||
{
|
||||
char* page = NULL;
|
||||
if (teletext_control(tvh->priv_vbi, TVI_CONTROL_VBI_GET_TXTPAGE, &page)!= TVI_CONTROL_TRUE)
|
||||
return NULL;
|
||||
return page;
|
||||
}
|
||||
|
||||
tv_teletext_img_t* tv_get_teletext_imgpage(tvi_handle_t *tvh)
|
||||
{
|
||||
tv_teletext_img_t* tv_teletext_img = NULL;
|
||||
if (teletext_control(tvh->priv_vbi, TVI_CONTROL_VBI_GET_IMGPAGE, &tv_teletext_img)!= TVI_CONTROL_TRUE)
|
||||
return NULL;
|
||||
return tv_teletext_img;
|
||||
}
|
||||
#endif
|
||||
|
||||
demuxer_desc_t demuxer_desc_tv = {
|
||||
"Tv card demuxer",
|
||||
"tv",
|
||||
|
59
stream/tv.h
59
stream/tv.h
@ -43,6 +43,11 @@ extern int tv_param_alsa;
|
||||
#endif
|
||||
extern char* tv_param_adevice;
|
||||
#endif
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
extern char* tv_param_tdevice; ///< teletext vbi device
|
||||
extern char* tv_param_tformat; ///< format: text,bw,gray,color
|
||||
extern int tv_param_tpage; ///< page number
|
||||
#endif
|
||||
extern int tv_param_brightness;
|
||||
extern int tv_param_contrast;
|
||||
extern int tv_param_hue;
|
||||
@ -72,6 +77,9 @@ typedef struct tvi_functions_s
|
||||
typedef struct tvi_handle_s {
|
||||
tvi_functions_t *functions;
|
||||
void *priv;
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
void *priv_vbi;
|
||||
#endif
|
||||
int seq;
|
||||
|
||||
/* specific */
|
||||
@ -90,6 +98,18 @@ typedef struct tv_channels_s {
|
||||
struct tv_channels_s *prev;
|
||||
} tv_channels_t;
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
typedef struct tv_teletext_img_s {
|
||||
void* canvas;
|
||||
int tformat;
|
||||
int columns;
|
||||
int rows;
|
||||
int height;
|
||||
int width;
|
||||
int half;
|
||||
} tv_teletext_img_t;
|
||||
#endif
|
||||
|
||||
extern tv_channels_t *tv_channel_list;
|
||||
extern tv_channels_t *tv_channel_current, *tv_channel_last;
|
||||
extern char *tv_channel_last_real;
|
||||
@ -153,6 +173,31 @@ extern char *tv_channel_last_real;
|
||||
#define TVI_CONTROL_SPC_SET_INPUT 0x402 /* set input channel (tv,s-video,composite..) */
|
||||
#define TVI_CONTROL_SPC_GET_NORMID 0x403 /* get normid from norm name */
|
||||
|
||||
/* TELETEXT controls */
|
||||
#define TVI_CONTROL_VBI_SET_MODE 0x501 ///< on/off grab teletext
|
||||
#define TVI_CONTROL_VBI_GET_MODE 0x502 ///< get current mode teletext
|
||||
#define TVI_CONTROL_VBI_STEP_MODE 0x503 ///< step teletext mode
|
||||
|
||||
#define TVI_CONTROL_VBI_SET_PAGE 0x504 ///< set grab teletext page number
|
||||
#define TVI_CONTROL_VBI_STEP_PAGE 0x505 ///< step grab teletext page number
|
||||
#define TVI_CONTROL_VBI_GET_PAGE 0x506 ///< get grabbed teletext page
|
||||
|
||||
#define TVI_CONTROL_VBI_SET_FORMAT 0x507 ///< set teletext format
|
||||
#define TVI_CONTROL_VBI_STEP_FORMAT 0x508 ///< step teletext format
|
||||
#define TVI_CONTROL_VBI_GET_FORMAT 0x509 ///< get eletext format
|
||||
|
||||
#define TVI_CONTROL_VBI_GET_HALF_PAGE 0x50a ///< get current half page
|
||||
#define TVI_CONTROL_VBI_STEP_HALF_PAGE 0x50b ///< switch half page
|
||||
#define TVI_CONTROL_VBI_SET_HALF_PAGE 0x50c ///< switch half page
|
||||
|
||||
#define TVI_CONTROL_VBI_ADD_DEC 0x50d ///< add page number with dec
|
||||
#define TVI_CONTROL_VBI_GO_LINK 0x50e ///< go link (1..6)
|
||||
#define TVI_CONTROL_VBI_GET_TXTPAGE 0x50f ///< get grabbed text teletext page
|
||||
#define TVI_CONTROL_VBI_GET_IMGPAGE 0x510 ///< get grabbed image teletext page
|
||||
#define TVI_CONTROL_VBI_GET_VBIPAGE 0x511 ///< get vbi_image for grabbed teletext page
|
||||
#define TVI_CONTROL_VBI_RESET 0x512 ///< vbi reset
|
||||
#define TVI_CONTROL_VBI_START 0x513 ///< vbi start
|
||||
|
||||
extern tvi_handle_t *tv_begin(void);
|
||||
extern int tv_init(tvi_handle_t *tvh);
|
||||
extern int tv_uninit(tvi_handle_t *tvh);
|
||||
@ -183,6 +228,20 @@ int tv_step_freq(tvi_handle_t *tvh, float step_interval);
|
||||
|
||||
int tv_set_norm(tvi_handle_t *tvh, char* norm);
|
||||
|
||||
#ifdef HAVE_TV_TELETEXT
|
||||
int tv_teletext_control(tvi_handle_t* tvh, int control,void* arg);
|
||||
/// add dec to pageno
|
||||
int tv_teletext_add_dec(tvi_handle_t *tvh, char *dec);
|
||||
/// go link
|
||||
int tv_teletext_go_link(tvi_handle_t *tvh, int linkno);
|
||||
/// get current vbi_page
|
||||
void* tv_get_teletext_vbipage(tvi_handle_t *tvh);
|
||||
/// get current page text
|
||||
char* tv_get_teletext_txtpage(tvi_handle_t *tvh);
|
||||
/// get current page image (RGB32_LB format)
|
||||
tv_teletext_img_t* tv_get_teletext_imgpage(tvi_handle_t *tvh);
|
||||
#endif
|
||||
|
||||
#define TV_NORM_PAL 1
|
||||
#define TV_NORM_NTSC 2
|
||||
#define TV_NORM_SECAM 3
|
||||
|
1197
stream/tvi_vbi.c
Normal file
1197
stream/tvi_vbi.c
Normal file
File diff suppressed because it is too large
Load Diff
75
stream/tvi_vbi.h
Normal file
75
stream/tvi_vbi.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef __TVI_VBI_H_
|
||||
#define __TVI_VBI_H_
|
||||
|
||||
#include "libzvbi.h"
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
#include "tv.h"
|
||||
|
||||
#define VBI_MAX_SUBPAGES 64 ///< max sub pages number
|
||||
#define VBI_TXT_PAGE_SIZE 42*25*2 ///< max text page size
|
||||
#define VBI_MAX_LINE_SIZE 42 ///< max line size in text page
|
||||
|
||||
#define VBI_TFORMAT_TEXT 0 ///< text mode
|
||||
#define VBI_TFORMAT_BW 1 ///< back&white mode
|
||||
#define VBI_TFORMAT_GRAY 2 ///< grayscale mode
|
||||
#define VBI_TFORMAT_COLOR 3 ///< color mode (require color_spu patch!)
|
||||
|
||||
#define VBI_NO_TELETEXT "No teletext"
|
||||
|
||||
#define VBI_TRANSPARENT_COLOR 40 ///< transparent color id
|
||||
#define VBI_TIME_LINEPOS 13 ///< time line pos in page header
|
||||
|
||||
typedef struct {
|
||||
int on; ///< teletext on/off
|
||||
|
||||
char* device; ///< capture device
|
||||
unsigned int services; ///< services
|
||||
vbi_capture* capture; ///< vbi_capture
|
||||
int capture_fd; ///< capture fd (now not used)
|
||||
vbi_decoder* decoder; ///< vbi_decoder
|
||||
char* errstr; ///< error string
|
||||
pthread_t grabber_thread; ///< grab thread
|
||||
pthread_mutex_t buffer_mutex;
|
||||
pthread_mutex_t update_mutex;
|
||||
int eof; ///< end grab
|
||||
int tpage; ///< tpage
|
||||
int pgno; ///< seek page number
|
||||
int subno; ///< seek subpage
|
||||
int curr_pgno; ///< current page number
|
||||
int curr_subno; ///< current subpage
|
||||
uint32_t pagenumdec; ///< set page num with dec
|
||||
|
||||
vbi_page** cache;
|
||||
vbi_page *page; ///< vbi_page
|
||||
int valid_page; ///< valid page flag
|
||||
char* txtpage; ///< decoded vbi_page to text
|
||||
vbi_char theader[VBI_MAX_LINE_SIZE]; ///< vbi header
|
||||
char header[VBI_MAX_LINE_SIZE]; ///< text header
|
||||
|
||||
int tformat; ///< 0:text, 1:bw, 2:gray, 3:color
|
||||
vbi_pixfmt fmt; ///< image format (only VBI_PIXFMT_RGBA32_LE supported)
|
||||
void* canvas; ///< stored image data
|
||||
int csize; ///< stored image size
|
||||
int canvas_size; ///< image buffer size
|
||||
int reveal; ///< reveal (now not used)
|
||||
int flash_on; ///< flash_on (now not used)
|
||||
int alpha; ///< opacity mode
|
||||
int foreground; ///< foreground black in bw mode
|
||||
int half; ///< 0:half mode off, 1:top half page, 2:bottom half page
|
||||
int redraw; ///< is redraw last image
|
||||
int columns; ///< page size: coloumns
|
||||
int rows; ///< page size: rows
|
||||
int spudec_proc; ///< render image request
|
||||
|
||||
char* network_name; ///< network name
|
||||
char* network_id; ///< network id
|
||||
} priv_vbi_t;
|
||||
|
||||
/// teletext subsystem initialization
|
||||
priv_vbi_t* teletext_init(void);
|
||||
/// teletext subsystem uninitialization
|
||||
void teletext_uninit(priv_vbi_t* priv_vbi);
|
||||
/// ioctl for
|
||||
int teletext_control(priv_vbi_t* priv_vbi, int cmd, void *args);
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user