summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/mplayer.18
-rw-r--r--cfg-common.h1
-rw-r--r--input/input.c1
-rw-r--r--input/input.h4
-rw-r--r--libmpdemux/tv.c159
-rw-r--r--libmpdemux/tv.h17
-rw-r--r--libmpdemux/tvi_v4l.c3
-rw-r--r--mplayer.c44
8 files changed, 223 insertions, 14 deletions
diff --git a/DOCS/mplayer.1 b/DOCS/mplayer.1
index 2c507f6350..530b169046 100644
--- a/DOCS/mplayer.1
+++ b/DOCS/mplayer.1
@@ -666,6 +666,7 @@ Specify other device than the default /dev/\:video0.
Specify other input than the default 0 (Television) (see output for a list)
.IPs freq=<value>
Specify the frequency to set the tuner to (e.g.\& 511.250).
+Not compatible with channels parameter.
.IPs outfmt=<value>
output format of the tuner (yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2,
i420)
@@ -682,6 +683,13 @@ available: PAL, SECAM, NTSC
Set tuner to <value> channel.
.IPs chanlist=<value>
available: europe-east, europe-west, us-bcast, us-cable, etc
+.IPs channels=<channel>-<name>,<channel>-<name>,...
+Set names for channels. Use _ for spaces in names (or play with quoting ;-).
+The channel names will then be written using OSD, and the commands tv_step_channel,
+tv_set_channel and tv_last_channel will then be usable using a remote (see. lirc).
+Not compatible with frequency parameter.
+Warning : The channel number will then be the position in the 'channels' list,
+beginning with 1. Ie. use tv://1, tv://2, tv_set_channel 1, tv_set_channel 2, etc.
.IPs audiorate=<value>
set audio capture bitrate
.IPs forceaudio
diff --git a/cfg-common.h b/cfg-common.h
index ab18850df1..a41e015614 100644
--- a/cfg-common.h
+++ b/cfg-common.h
@@ -254,6 +254,7 @@ struct config tvopts_conf[]={
{"input", &tv_param_input, CONF_TYPE_INT, 0, 0, 20, NULL},
{"outfmt", &tv_param_outfmt, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"fps", &tv_param_fps, CONF_TYPE_FLOAT, 0, 0, 100.0, NULL},
+ {"channels", &tv_param_channels, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
#ifdef HAVE_TV_V4L
{"amode", &tv_param_amode, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL},
{"volume", &tv_param_volume, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
diff --git a/input/input.c b/input/input.c
index b6b245a0f1..c22b23b1ac 100644
--- a/input/input.c
+++ b/input/input.c
@@ -79,6 +79,7 @@ static mp_cmd_t mp_cmds[] = {
{ MP_CMD_TV_STEP_NORM, "tv_step_norm",0, { {-1,{0}} } },
{ MP_CMD_TV_STEP_CHANNEL_LIST, "tv_step_chanlist", 0, { {-1,{0}} } },
{ MP_CMD_TV_SET_CHANNEL, "tv_set_channel", 1, { { MP_CMD_ARG_STRING, {0}}, {-1,{0}} }},
+ { MP_CMD_TV_LAST_CHANNEL, "tv_last_channel", 0, { {-1,{0}} } },
#endif
{ MP_CMD_VO_FULLSCREEN, "vo_fullscreen", 0, { {-1,{0}} } },
{ MP_CMD_SCREENSHOT, "screenshot", 0, { {-1,{0}} } },
diff --git a/input/input.h b/input/input.h
index bddb5935a1..e13493f0a0 100644
--- a/input/input.h
+++ b/input/input.h
@@ -19,7 +19,6 @@
#define MP_CMD_TV_STEP_CHANNEL 17
#define MP_CMD_TV_STEP_NORM 18
#define MP_CMD_TV_STEP_CHANNEL_LIST 19
-#define MP_CMD_TV_SET_CHANNEL 37
#define MP_CMD_VO_FULLSCREEN 20
#define MP_CMD_SUB_POS 21
#define MP_CMD_DVDNAV 22
@@ -37,11 +36,12 @@
#define MP_CMD_GET_TIME_LENGTH 34
#define MP_CMD_GET_PERCENT_POS 35
#define MP_CMD_SUB_STEP 36
-//#define MP_CMD_TV_SET_CHANNEL 37
+#define MP_CMD_TV_SET_CHANNEL 37
#ifdef USE_EDL
#define MP_CMD_EDL_MARK 38
#endif
#define MP_CMD_SUB_ALIGNMENT 39
+#define MP_CMD_TV_LAST_CHANNEL 40
#define MP_CMD_GUI_EVENTS 5000
#define MP_CMD_GUI_LOADFILE 5001
diff --git a/libmpdemux/tv.c b/libmpdemux/tv.c
index 6a90f31ac5..95350c8da5 100644
--- a/libmpdemux/tv.c
+++ b/libmpdemux/tv.c
@@ -52,6 +52,7 @@ int tv_param_height = -1;
int tv_param_input = 0; /* used in v4l and bttv */
char *tv_param_outfmt = "yv12";
float tv_param_fps = -1.0;
+char **tv_param_channels = NULL;
#ifdef HAVE_TV_V4L
int tv_param_amode = -1;
int tv_param_audio_id = 0;
@@ -233,6 +234,72 @@ static int open_tv(tvi_handle_t *tvh)
goto done;
}
+ /* Handle channels names */
+ if (tv_param_channels) {
+ mp_msg(MSGT_TV, MSGL_INFO, "TV Channels names detected.\n");
+ tv_channel_list = malloc(sizeof(tv_channels_t));
+ tv_channel_list->index=1;
+ tv_channel_list->next=NULL;
+ tv_channel_list->prev=NULL;
+ tv_channel_current = tv_channel_list;
+
+ while (*tv_param_channels) {
+ char* tmp = *(tv_param_channels++);
+ int i;
+ struct CHANLIST cl;
+
+ strcpy(tv_channel_current->name, strchr(tmp, '-') + 1);
+ strchr(tmp, '-')[0] = '\0';
+ strncpy(tv_channel_current->number, tmp, 4);
+
+ while (strchr(tv_channel_current->name, '_'))
+ strchr(tv_channel_current->name, '_')[0] = ' ';
+
+ tv_channel_current->freq = 0;
+ for (i = 0; i < chanlists[tvh->chanlist].count; i++) {
+ cl = tvh->chanlist_s[i];
+ if (!strcasecmp(cl.name, tv_channel_current->number)) {
+ tv_channel_current->freq=cl.freq;
+ break;
+ }
+ }
+ if (tv_channel_current->freq == 0)
+ mp_msg(MSGT_TV, MSGL_ERR, "Couldn't find frequency for channel %s (%s)\n",
+ tv_channel_current->number, tv_channel_current->name);
+
+ /*mp_msg(MSGT_TV, MSGL_INFO, "-- Detected channel %s - %s (%5.3f)\n",
+ tv_channel_current->number, tv_channel_current->name,
+ (float)tv_channel_current->freq/1000);*/
+
+ tv_channel_current->next = malloc(sizeof(tv_channels_t));
+ tv_channel_current->next->index = tv_channel_current->index + 1;
+ tv_channel_current->next->prev = tv_channel_current;
+ tv_channel_current->next->next = NULL;
+ tv_channel_current = tv_channel_current->next;
+ }
+
+ tv_channel_current->prev->next = NULL;
+ free(tv_channel_current);
+ } else
+ tv_channel_last_real = malloc(sizeof(char)*5);
+
+ if (tv_channel_list) {
+ int i;
+ int channel;
+ if (tv_param_channel)
+ channel = atoi(tv_param_channel);
+ else
+ channel = 1;
+
+ tv_channel_current = tv_channel_list;
+ for (i = 1; i < channel; i++)
+ if (tv_channel_current->next)
+ tv_channel_current = tv_channel_current->next;
+ mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s - %s (freq: %.3f)\n", tv_channel_current->number,
+ tv_channel_current->name, (float)tv_channel_current->freq/1000);
+ tv_set_freq(tvh, (unsigned long)(((float)tv_channel_current->freq/1000)*16));
+ tv_channel_last = tv_channel_current;
+ } else {
/* we need to set frequency */
if (tv_param_freq)
{
@@ -246,18 +313,18 @@ static int open_tv(tvi_handle_t *tvh)
freq, (float)freq/16);
}
- if (tv_param_channel)
- {
+ if (tv_param_channel) {
struct CHANLIST cl;
mp_msg(MSGT_TV, MSGL_V, "Requested channel: %s\n", tv_param_channel);
for (i = 0; i < chanlists[tvh->chanlist].count; i++)
{
cl = tvh->chanlist_s[i];
-// printf("count%d: name: %s, freq: %d\n",
-// i, cl.name, cl.freq);
+ // printf("count%d: name: %s, freq: %d\n",
+ // i, cl.name, cl.freq);
if (!strcasecmp(cl.name, tv_param_channel))
{
+ strcpy(tv_channel_last_real, cl.name);
tvh->channel = i;
mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s (freq: %.3f)\n",
cl.name, (float)cl.freq/1000);
@@ -266,6 +333,7 @@ static int open_tv(tvi_handle_t *tvh)
}
}
}
+ }
/* grep frequency in chanlist */
{
@@ -526,7 +594,7 @@ int tv_set_freq(tvi_handle_t *tvh, unsigned long freq)
return(1);
}
-int tv_step_channel(tvi_handle_t *tvh, int direction)
+int tv_step_channel_real(tvi_handle_t *tvh, int direction)
{
struct CHANLIST cl;
@@ -534,6 +602,7 @@ int tv_step_channel(tvi_handle_t *tvh, int direction)
{
if (tvh->channel-1 >= 0)
{
+ strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
cl = tvh->chanlist_s[--tvh->channel];
mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s (freq: %.3f)\n",
cl.name, (float)cl.freq/1000);
@@ -545,6 +614,7 @@ int tv_step_channel(tvi_handle_t *tvh, int direction)
{
if (tvh->channel+1 < chanlists[tvh->chanlist].count)
{
+ strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
cl = tvh->chanlist_s[++tvh->channel];
mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s (freq: %.3f)\n",
cl.name, (float)cl.freq/1000);
@@ -554,11 +624,35 @@ int tv_step_channel(tvi_handle_t *tvh, int direction)
return(1);
}
-int tv_set_channel(tvi_handle_t *tvh, char *channel)
-{
+int tv_step_channel(tvi_handle_t *tvh, int direction) {
+ if (tv_channel_list) {
+ if (direction == TV_CHANNEL_HIGHER) {
+ if (tv_channel_current->next) {
+ tv_channel_last = tv_channel_current;
+ tv_channel_current = tv_channel_current->next;
+ tv_set_freq(tvh, (unsigned long)(((float)tv_channel_current->freq/1000)*16));
+ mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s - %s (freq: %.3f)\n",
+ tv_channel_current->number, tv_channel_current->name, (float)tv_channel_current->freq/1000);
+ }
+ }
+ if (direction == TV_CHANNEL_LOWER) {
+ if (tv_channel_current->prev) {
+ tv_channel_last = tv_channel_current;
+ tv_channel_current = tv_channel_current->prev;
+ tv_set_freq(tvh, (unsigned long)(((float)tv_channel_current->freq/1000)*16));
+ mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s - %s (freq: %.3f)\n",
+ tv_channel_current->number, tv_channel_current->name, (float)tv_channel_current->freq/1000);
+ }
+ }
+ } else tv_step_channel_real(tvh, direction);
+ return(1);
+}
+
+int tv_set_channel_real(tvi_handle_t *tvh, char *channel) {
int i;
struct CHANLIST cl;
+ strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
for (i = 0; i < chanlists[tvh->chanlist].count; i++)
{
cl = tvh->chanlist_s[i];
@@ -573,6 +667,57 @@ int tv_set_channel(tvi_handle_t *tvh, char *channel)
break;
}
}
+ return(1);
+}
+
+int tv_set_channel(tvi_handle_t *tvh, char *channel) {
+ int i, channel_int;
+
+ if (tv_channel_list) {
+ tv_channel_last = tv_channel_current;
+ channel_int = atoi(channel);
+ tv_channel_current = tv_channel_list;
+ for (i = 1; i < channel_int; i++)
+ if (tv_channel_current->next)
+ tv_channel_current = tv_channel_current->next;
+ mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s - %s (freq: %.3f)\n", tv_channel_current->number,
+ tv_channel_current->name, (float)tv_channel_current->freq/1000);
+ tv_set_freq(tvh, (unsigned long)(((float)tv_channel_current->freq/1000)*16));
+ } else tv_set_channel_real(tvh, channel);
+ return(1);
+}
+
+int tv_last_channel(tvi_handle_t *tvh) {
+
+ if (tv_channel_list) {
+ tv_channels_t *tmp;
+
+ tmp = tv_channel_last;
+ tv_channel_last = tv_channel_current;
+ tv_channel_current = tmp;
+
+ mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s - %s (freq: %.3f)\n", tv_channel_current->number,
+ tv_channel_current->name, (float)tv_channel_current->freq/1000);
+ tv_set_freq(tvh, (unsigned long)(((float)tv_channel_current->freq/1000)*16));
+ } else {
+ int i;
+ struct CHANLIST cl;
+
+ for (i = 0; i < chanlists[tvh->chanlist].count; i++)
+ {
+ cl = tvh->chanlist_s[i];
+ if (!strcasecmp(cl.name, tv_channel_last_real))
+ {
+ strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
+ tvh->channel = i;
+ mp_msg(MSGT_TV, MSGL_INFO, "Selected channel: %s (freq: %.3f)\n",
+ cl.name, (float)cl.freq/1000);
+ tv_set_freq(tvh, (unsigned long)(((float)cl.freq/1000)*16));
+ break;
+ }
+ }
+ }
+ return(1);
}
int tv_step_norm(tvi_handle_t *tvh)
diff --git a/libmpdemux/tv.h b/libmpdemux/tv.h
index 4f2cb9e41c..abd5055021 100644
--- a/libmpdemux/tv.h
+++ b/libmpdemux/tv.h
@@ -20,6 +20,7 @@ extern int tv_param_height;
extern int tv_param_input;
extern char *tv_param_outfmt;
extern float tv_param_fps;
+extern char **tv_param_channels;
extern int tv_param_noaudio;
extern int tv_param_immediate;
extern int tv_param_audiorate;
@@ -75,6 +76,18 @@ typedef struct tvi_handle_s {
int channel;
} tvi_handle_t;
+typedef struct tv_channels_s {
+ int index;
+ char number[5];
+ char name[20];
+ int freq;
+ struct tv_channels_s *next;
+ struct tv_channels_s *prev;
+} tv_channels_t;
+
+tv_channels_t *tv_channel_list;
+tv_channels_t *tv_channel_current, *tv_channel_last;
+char *tv_channel_last_real;
#define TVI_CONTROL_FALSE 0
#define TVI_CONTROL_TRUE 1
@@ -144,10 +157,14 @@ int tv_set_color_options(tvi_handle_t *tvh, int opt, int val);
#define TV_COLOR_SATURATION 3
#define TV_COLOR_CONTRAST 4
+int tv_step_channel_real(tvi_handle_t *tvh, int direction);
int tv_step_channel(tvi_handle_t *tvh, int direction);
#define TV_CHANNEL_LOWER 1
#define TV_CHANNEL_HIGHER 2
+int tv_last_channel(tvi_handle_t *tvh);
+
+int tv_set_channel_real(tvi_handle_t *tvh, char *channel);
int tv_set_channel(tvi_handle_t *tvh, char *channel);
int tv_step_norm(tvi_handle_t *tvh);
diff --git a/libmpdemux/tvi_v4l.c b/libmpdemux/tvi_v4l.c
index b967e1a63f..771d36346d 100644
--- a/libmpdemux/tvi_v4l.c
+++ b/libmpdemux/tvi_v4l.c
@@ -1225,7 +1225,6 @@ static void *video_grabber(void *data)
struct timeval curtime;
long long skew, prev_skew, xskew, interval, prev_interval;
int frame, nextframe;
- int fsize = priv->bytesperline * priv->height;
int i;
int first = 1;
int framecount;
@@ -1284,7 +1283,7 @@ static void *video_grabber(void *data)
if (!priv->immediate_mode) {
interval = (long long)1e6*curtime.tv_sec + curtime.tv_usec - priv->starttime;
} else {
- interval = (double)framecount/priv->fps;
+ interval = (long long)1e6*framecount/priv->fps;
}
if (!priv->immediate_mode) {
diff --git a/mplayer.c b/mplayer.c
index 9a6f47e9ce..6d2fd2084c 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -613,6 +613,7 @@ int osd_show_sub_visibility = 0;
int osd_show_sub_alignment = 0;
int osd_show_vobsub_changed = 0;
int osd_show_percentage = 0;
+int osd_show_tv_channel = 25;
int rtc_fd=-1;
@@ -2467,15 +2468,46 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
case MP_CMD_TV_STEP_CHANNEL : {
if (tv_param_on == 1) {
int v = cmd->args[0].v.i;
- if(v > 0)
+ if(v > 0){
tv_step_channel((tvi_handle_t*)(demuxer->priv), TV_CHANNEL_HIGHER);
- else
+#ifdef USE_OSD
+ if (tv_channel_list) {
+ osd_show_tv_channel = sh_video->fps;
+ vo_osd_changed(OSDTYPE_SUBTITLE);
+ }
+#endif
+ } else {
tv_step_channel((tvi_handle_t*)(demuxer->priv), TV_CHANNEL_LOWER);
+#ifdef USE_OSD
+ if (tv_channel_list) {
+ osd_show_tv_channel = sh_video->fps;
+ vo_osd_changed(OSDTYPE_SUBTITLE);
+ }
+#endif
+ }
}
} break;
case MP_CMD_TV_SET_CHANNEL : {
- if (tv_param_on == 1)
+ if (tv_param_on == 1) {
tv_set_channel((tvi_handle_t*)(demuxer->priv), cmd->args[0].v.s);
+#ifdef USE_OSD
+ if (tv_channel_list) {
+ osd_show_tv_channel = sh_video->fps;
+ vo_osd_changed(OSDTYPE_SUBTITLE);
+ }
+#endif
+ }
+ } break;
+ case MP_CMD_TV_LAST_CHANNEL : {
+ if (tv_param_on == 1) {
+ tv_last_channel((tvi_handle_t*)(demuxer->priv));
+#ifdef USE_OSD
+ if (tv_channel_list) {
+ osd_show_tv_channel = sh_video->fps;
+ vo_osd_changed(OSDTYPE_SUBTITLE);
+ }
+#endif
+ }
} break;
case MP_CMD_TV_STEP_NORM : {
if (tv_param_on == 1)
@@ -2952,6 +2984,12 @@ if(rel_seek_secs || abs_seek_pos){
osd_show_dvd_nav_delay--;
} else
#endif
+#ifdef USE_TV
+ if (osd_show_tv_channel && tv_channel_list) {
+ sprintf(osd_text_tmp, "Channel: %s", tv_channel_current->name);
+ osd_show_tv_channel--;
+ } else
+#endif
if (osd_show_sub_visibility) {
sprintf(osd_text_tmp, "Subtitles: %sabled", sub_visibility?"en":"dis");
osd_show_sub_visibility--;