changeset 8627:14ab71b47a58

user friendly channel tuning + 10L fix in tvi_v4l (by Stephane Jourdois)
author henry
date Sat, 28 Dec 2002 22:57:39 +0000
parents 8494f3ffc04b
children eecc9bb4e758
files DOCS/mplayer.1 cfg-common.h input/input.c input/input.h libmpdemux/tv.c libmpdemux/tv.h libmpdemux/tvi_v4l.c mplayer.c
diffstat 8 files changed, 223 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/mplayer.1	Sat Dec 28 21:58:21 2002 +0000
+++ b/DOCS/mplayer.1	Sat Dec 28 22:57:39 2002 +0000
@@ -666,6 +666,7 @@
 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 @@
 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
--- a/cfg-common.h	Sat Dec 28 21:58:21 2002 +0000
+++ b/cfg-common.h	Sat Dec 28 22:57:39 2002 +0000
@@ -254,6 +254,7 @@
 	{"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},
--- a/input/input.c	Sat Dec 28 21:58:21 2002 +0000
+++ b/input/input.c	Sat Dec 28 22:57:39 2002 +0000
@@ -79,6 +79,7 @@
   { 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}} } },
--- a/input/input.h	Sat Dec 28 21:58:21 2002 +0000
+++ b/input/input.h	Sat Dec 28 22:57:39 2002 +0000
@@ -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
--- a/libmpdemux/tv.c	Sat Dec 28 21:58:21 2002 +0000
+++ b/libmpdemux/tv.c	Sat Dec 28 22:57:39 2002 +0000
@@ -52,6 +52,7 @@
 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 @@
 	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 @@
 	    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 @@
 	    }
 	}
     }
+    }
     
     /* grep frequency in chanlist */
     {
@@ -526,7 +594,7 @@
     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 @@
     {
 	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 @@
     {
 	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 @@
     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 @@
 		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)
--- a/libmpdemux/tv.h	Sat Dec 28 21:58:21 2002 +0000
+++ b/libmpdemux/tv.h	Sat Dec 28 22:57:39 2002 +0000
@@ -20,6 +20,7 @@
 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 @@
     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 @@
 #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);
--- a/libmpdemux/tvi_v4l.c	Sat Dec 28 21:58:21 2002 +0000
+++ b/libmpdemux/tvi_v4l.c	Sat Dec 28 22:57:39 2002 +0000
@@ -1225,7 +1225,6 @@
     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 @@
 		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) {
--- a/mplayer.c	Sat Dec 28 21:58:21 2002 +0000
+++ b/mplayer.c	Sat Dec 28 22:57:39 2002 +0000
@@ -613,6 +613,7 @@
 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 @@
     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 @@
           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--;