summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cfg-common.h5
-rw-r--r--command.c105
-rwxr-xr-xconfigure26
-rw-r--r--help/help_mp-en.h1
-rw-r--r--input/input.c8
-rw-r--r--input/input.h2
-rw-r--r--stream/Makefile1
-rw-r--r--stream/stream_tv.c3
-rw-r--r--stream/tv.c6
-rw-r--r--stream/tv.h92
10 files changed, 249 insertions, 0 deletions
diff --git a/cfg-common.h b/cfg-common.h
index 16f839511c..7b5ff29cb8 100644
--- a/cfg-common.h
+++ b/cfg-common.h
@@ -460,6 +460,11 @@ m_option_t tvopts_conf[]={
#endif
{"adevice", &stream_tv_defaults.adevice, CONF_TYPE_STRING, 0, 0, 0, NULL},
#endif
+#ifdef HAVE_TV_TELETEXT
+ {"tdevice", &stream_tv_defaults.tdevice, CONF_TYPE_STRING, 0, 0, 0, NULL},
+ {"tpage", &stream_tv_defaults.tpage, CONF_TYPE_INT, CONF_RANGE, 100, 899, NULL},
+ {"tformat", &stream_tv_defaults.tformat, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL},
+#endif
{"audioid", &stream_tv_defaults.audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
diff --git a/command.c b/command.c
index 6a6c8762c6..49252c6f96 100644
--- a/command.c
+++ b/command.c
@@ -1510,6 +1510,89 @@ static int mp_property_tv_color(m_option_t * prop, int action, void *arg,
#endif
+#ifdef HAVE_TV_TELETEXT
+static int mp_property_teletext_common(m_option_t * prop, int action, void *arg,
+ MPContext * mpctx)
+{
+ int val,result;
+ int base_ioctl=(int)prop->priv;
+ /*
+ for teletext's GET,SET,STEP ioctls this is not 0
+ SET is GET+1
+ STEP is GET+2
+ */
+ tvi_handle_t *tvh = mpctx->demuxer->priv;
+ if (mpctx->demuxer->type != DEMUXER_TYPE_TV || !tvh)
+ return M_PROPERTY_UNAVAILABLE;
+ if(!base_ioctl)
+ return M_PROPERTY_ERROR;
+
+ switch (action) {
+ case M_PROPERTY_GET:
+ if (!arg)
+ return M_PROPERTY_ERROR;
+ result=tvh->functions->control(tvh->priv, base_ioctl, arg);
+ break;
+ case M_PROPERTY_SET:
+ if (!arg)
+ return M_PROPERTY_ERROR;
+ M_PROPERTY_CLAMP(prop, *(int *) arg);
+ result=tvh->functions->control(tvh->priv, base_ioctl+1, arg);
+ break;
+ case M_PROPERTY_STEP_UP:
+ case M_PROPERTY_STEP_DOWN:
+ result=tvh->functions->control(tvh->priv, base_ioctl, &val);
+ val += (arg ? *(int *) arg : 1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
+ result=tvh->functions->control(tvh->priv, base_ioctl+1, &val);
+ break;
+ default:
+ return M_PROPERTY_NOT_IMPLEMENTED;
+ }
+
+ return (result==TVI_CONTROL_TRUE?M_PROPERTY_OK:M_PROPERTY_ERROR);
+}
+
+static int mp_property_teletext_mode(m_option_t * prop, int action, void *arg,
+ MPContext * mpctx)
+{
+ tvi_handle_t *tvh = mpctx->demuxer->priv;
+ int result;
+ int val;
+
+ //with tvh==NULL will fail too
+ result=mp_property_teletext_common(prop,action,arg,mpctx);
+ if(result!=M_PROPERTY_OK)
+ return result;
+
+ if(tvh->functions->control(tvh->priv, prop->priv, &val)==TVI_CONTROL_TRUE && val)
+ mp_input_set_section("teletext");
+ else
+ mp_input_set_section("tv");
+ return M_PROPERTY_OK;
+}
+
+static int mp_property_teletext_page(m_option_t * prop, int action, void *arg,
+ MPContext * mpctx)
+{
+ tvi_handle_t *tvh = mpctx->demuxer->priv;
+ int result;
+ int val;
+ switch(action){
+ case M_PROPERTY_STEP_UP:
+ case M_PROPERTY_STEP_DOWN:
+ //This should be handled separately
+ val = (arg ? *(int *) arg : 1) * (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
+ result=tvh->functions->control(tvh->priv, TV_VBI_CONTROL_STEP_PAGE, &val);
+ break;
+ default:
+ result=mp_property_teletext_common(prop,action,arg,mpctx);
+ }
+ return result;
+}
+
+
+#endif /* HAVE_TV_TELETEXT */
+
///@}
/// All properties available in MPlayer.
@@ -1643,6 +1726,19 @@ 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, 100, 899, (void*)TV_VBI_CONTROL_GET_PAGE },
+ { "teletext_subpage", mp_property_teletext_common, CONF_TYPE_INT,
+ M_OPT_RANGE, 0, 64, (void*)TV_VBI_CONTROL_GET_SUBPAGE },
+ { "teletext_mode", mp_property_teletext_mode, CONF_TYPE_FLAG,
+ M_OPT_RANGE, 0, 1, (void*)TV_VBI_CONTROL_GET_MODE },
+ { "teletext_format", mp_property_teletext_common, CONF_TYPE_INT,
+ M_OPT_RANGE, 0, 3, (void*)TV_VBI_CONTROL_GET_FORMAT },
+ { "teletext_half_page", mp_property_teletext_common, CONF_TYPE_INT,
+ M_OPT_RANGE, 0, 2, (void*)TV_VBI_CONTROL_GET_HALF_PAGE },
+#endif
+
{ NULL, NULL, NULL, 0, 0, 0, NULL }
};
@@ -2342,6 +2438,15 @@ 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:
+ {
+ tvi_handle_t* tvh=(tvi_handle_t *)(mpctx->demuxer->priv);
+ if (mpctx->file_format == DEMUXER_TYPE_TV)
+ tvh->functions->control(tvh->priv,TV_VBI_CONTROL_ADD_DEC,&(cmd->args[0].v.s));
+ break;
+ }
+#endif /* HAVE_TV_TELETEXT */
#endif /* USE_TV */
case MP_CMD_SUB_LOAD:
diff --git a/configure b/configure
index 917e30c512..5c22f4a613 100755
--- a/configure
+++ b/configure
@@ -247,6 +247,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-teletext 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]
@@ -598,6 +599,7 @@ _tv=yes
_tv_v4l1=auto
_tv_v4l2=auto
_tv_bsdbt848=auto
+_tv_teletext=auto
_pvr=auto
_network=yes
_winsock2=auto
@@ -948,6 +950,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 ;;
@@ -6679,6 +6683,24 @@ fi
echores "$_tv_v4l2"
+echocheck "TV teletext interface"
+if test "$_tv_teletext" = auto ; then
+ if test "$_tv_v4l2" = yes; then
+ _tv_teletext=yes
+ else
+ _tv_teletext=no
+ fi
+fi
+if test "$_tv_teletext" = yes ; then
+ _def_tv_teletext='#define HAVE_TV_TELETEXT 1'
+ _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
_def_radio='#define USE_RADIO 1'
@@ -7415,6 +7437,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
@@ -7938,6 +7961,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
diff --git a/help/help_mp-en.h b/help/help_mp-en.h
index a82c12832c..2aa41ffcd7 100644
--- a/help/help_mp-en.h
+++ b/help/help_mp-en.h
@@ -2083,3 +2083,4 @@ static char help_text[]=
#define MSGTR_TV_NoSuchDriver "No such driver: %s\n"
#define MSGTR_TV_UnknownColorOption "Unknown color option (%d) specified!\n"
#define MSGTR_TV_CurrentFrequency "Current frequency: %lu (%.3f)\n"
+#define MSGTR_TV_NoTeletext "No teletext"
diff --git a/input/input.c b/input/input.c
index 425763a1c2..affe926c9c 100644
--- a/input/input.c
+++ b/input/input.c
@@ -139,6 +139,9 @@ 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}} } },
+#endif
#ifdef HAVE_NEW_GUI
{ MP_CMD_GUI_LOADFILE, "gui_loadfile", 0, { {-1,{0}} } },
@@ -391,6 +394,11 @@ 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" },
+ { { '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" },
diff --git a/input/input.h b/input/input.h
index 6092445060..9970207c4c 100644
--- a/input/input.h
+++ b/input/input.h
@@ -96,6 +96,8 @@
#define MP_CMD_LOOP 94
#define MP_CMD_BALANCE 96
#define MP_CMD_SUB_SCALE 97
+#define MP_CMD_TV_TELETEXT_ADD_DEC 98
+#define MP_CMD_TV_TELETEXT_GO_LINK 99
#define MP_CMD_GUI_EVENTS 5000
#define MP_CMD_GUI_LOADFILE 5001
diff --git a/stream/Makefile b/stream/Makefile
index a5d7edcf37..cb7baa6175 100644
--- a/stream/Makefile
+++ b/stream/Makefile
@@ -49,6 +49,7 @@ SRCS_COMMON-$(STREAM_CACHE) += cache2.c
SRCS_COMMON-$(STREAMING_LIVE555) += stream_livedotcom.c
SRCS_COMMON-$(TV) += stream_tv.c tv.c frequencies.c tvi_dummy.c
SRCS_COMMON-$(TV_BSDBT848) += tvi_bsdbt848.c
+SRCS_COMMON-$(TV_TELETEXT) += tvi_vbi.c
SRCS_COMMON-$(TV_V4L1) += tvi_v4l.c audio_in.c
SRCS_COMMON-$(TV_V4L2) += tvi_v4l2.c audio_in.c
SRCS_COMMON-$(VCD) += stream_vcd.c
diff --git a/stream/stream_tv.c b/stream/stream_tv.c
index 126c35d8f2..8332b07477 100644
--- a/stream/stream_tv.c
+++ b/stream/stream_tv.c
@@ -72,6 +72,9 @@ tv_param_t stream_tv_defaults = {
0, //contrast
0, //hue
0, //saturation
+ NULL, //tdevice
+ 0, //tformat
+ 100 //tpage
};
#define ST_OFF(f) M_ST_OFF(tv_param_t,f)
diff --git a/stream/tv.c b/stream/tv.c
index 884271d53b..12d23895b9 100644
--- a/stream/tv.c
+++ b/stream/tv.c
@@ -516,6 +516,9 @@ static demuxer_t* demux_open_tv(demuxer_t *demuxer)
demuxer->priv=NULL;
if(!(tvh=tv_begin(demuxer->stream->priv))) return NULL;
if (!tvh->functions->init(tvh->priv)) return NULL;
+
+ tvh->functions->control(tvh->priv,TVI_CONTROL_VBI_INIT,&(tvh->tv_param->tdevice));
+
if (!open_tv(tvh)){
tv_uninit(tvh);
return NULL;
@@ -731,6 +734,7 @@ int tv_set_freq(tvi_handle_t *tvh, unsigned long freq)
mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_CurrentFrequency,
freq, (float)freq/16);
}
+ tvh->functions->control(tvh->priv,TV_VBI_CONTROL_RESET,tvh->tv_param);
return(1);
}
@@ -890,6 +894,7 @@ int tv_step_norm(tvi_handle_t *tvh)
return 0;
}
}
+ tvh->functions->control(tvh->priv,TV_VBI_CONTROL_RESET,tvh->tv_param);
return(1);
}
@@ -907,6 +912,7 @@ int tv_set_norm(tvi_handle_t *tvh, char* norm)
mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm);
return 0;
}
+ tvh->functions->control(tvh->priv,TV_VBI_CONTROL_RESET,tvh->tv_param);
return(1);
}
diff --git a/stream/tv.h b/stream/tv.h
index ad40780414..292238b51b 100644
--- a/stream/tv.h
+++ b/stream/tv.h
@@ -47,6 +47,9 @@ typedef struct tv_param_s {
int contrast;
int hue;
int saturation;
+ char *tdevice; ///< teletext device
+ int tformat; ///< teletext display format
+ int tpage; ///< start teletext page
} tv_param_t;
extern tv_param_t stream_tv_defaults;
@@ -157,6 +160,39 @@ 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 */
+//tvi_* ioctl (not tvi_vbi.c !!!)
+#define TVI_CONTROL_VBI_INIT 0x501 ///< vbi init
+
+/*
+ TELETEXT controls (through tv_teletext_control() )
+ NOTE:
+ _SET_ should be _GET_ +1
+ _STEP_ should be _GET_ +2
+*/
+#define TV_VBI_CONTROL_GET_MODE 0x510 ///< get current mode teletext
+#define TV_VBI_CONTROL_SET_MODE 0x511 ///< on/off grab teletext
+
+#define TV_VBI_CONTROL_GET_PAGE 0x513 ///< get grabbed teletext page
+#define TV_VBI_CONTROL_SET_PAGE 0x514 ///< set grab teletext page number
+#define TV_VBI_CONTROL_STEP_PAGE 0x515 ///< step grab teletext page number
+
+#define TV_VBI_CONTROL_GET_SUBPAGE 0x516 ///< get grabbed teletext page
+#define TV_VBI_CONTROL_SET_SUBPAGE 0x517 ///< set grab teletext page number
+
+#define TV_VBI_CONTROL_GET_FORMAT 0x519 ///< get eletext format
+#define TV_VBI_CONTROL_SET_FORMAT 0x51a ///< set teletext format
+
+#define TV_VBI_CONTROL_GET_HALF_PAGE 0x51c ///< get current half page
+#define TV_VBI_CONTROL_SET_HALF_PAGE 0x51d ///< switch half page
+
+#define TV_VBI_CONTROL_ADD_DEC 0x550 ///< add page number with dec
+#define TV_VBI_CONTROL_GO_LINK 0x551 ///< go link (1..6) NYI
+#define TV_VBI_CONTROL_GET_VBIPAGE 0x552 ///< get vbi_image for grabbed teletext page
+#define TV_VBI_CONTROL_RESET 0x553 ///< vbi reset
+#define TV_VBI_CONTROL_START 0x554 ///< vbi start
+#define TV_VBI_CONTROL_STOP 0x555 ///< vbi stop
+#define TV_VBI_CONTROL_DECODE_PAGE 0x556 ///< decode vbi page
+
int tv_set_color_options(tvi_handle_t *tvh, int opt, int val);
int tv_get_color_options(tvi_handle_t *tvh, int opt, int* val);
#define TV_COLOR_BRIGHTNESS 1
@@ -191,4 +227,60 @@ int tv_set_norm(tvi_handle_t *tvh, char* norm);
#define TV_NORM_PALN 6
#define TV_NORM_NTSCJP 7
+#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_MAX_PAGES 0x800 ///< max sub pages number
+#define VBI_MAX_SUBPAGES 64 ///< max sub pages number
+
+#define VBI_ROWS 24 ///< teletext page width in chars
+#define VBI_COLUMNS 40 ///< teletext page height in chars
+#define VBI_TIME_LINEPOS 26 ///< time line pos in page header
+
+typedef
+enum{
+ TT_FORMAT_OPAQUE=0, ///< opaque
+ TT_FORMAT_TRANSPARENT, ///< translarent
+ TT_FORMAT_OPAQUE_INV, ///< opaque with inverted colors
+ TT_FORMAT_TRANSPARENT_INV ///< translarent with inverted colors
+} teletext_format;
+
+typedef
+enum{
+ TT_ZOOM_NORMAL=0,
+ TT_ZOOM_TOP_HALF,
+ TT_ZOOM_BOTTOM_HALF
+} teletext_zoom;
+
+typedef struct tt_char_s{
+ unsigned int unicode; ///< unicode (utf8) character
+ unsigned char fg; ///< foreground color
+ unsigned char bg; ///< background color
+ unsigned char gfx; ///< 0-no gfx, 1-solid gfx, 2-separated gfx
+ unsigned char ctl; ///< control character
+ unsigned char lng; ///< lang: 0-lating,1-national
+ unsigned char raw; ///< raw character (as received from device)
+} tt_char;
+
+typedef struct tt_page_s{
+ int pagenum; ///< page number
+ int subpagenum; ///< subpage number
+ unsigned char lang; ///< language code
+ unsigned char active; ///< page is complete and ready for rendering
+ unsigned char flags; ///< page flags, not used
+ unsigned char raw[VBI_ROWS*VBI_COLUMNS]; ///< page data
+ struct tt_page_s* next_subpage;
+} tt_page;
+
+typedef struct tt_stream_props_s{
+ int sampling_rate;
+ int samples_per_line;
+ int offset;
+ int count[2]; ///< number of lines in first and second fields
+ int interlaced; ///< vbi data are interlaced
+ int bufsize; ///< required buffer size
+} tt_stream_props;
+
#endif /* TV_H */