[MPlayer-dev-eng] TV watching, 2nd patch...

Stephane Jourdois mplayer-dev-eng at rubis.org
Sun Dec 22 19:12:58 CET 2002


With Istvan Sebestyen, I corrected 2 problems in the patch :
- if the channel wasn't initialized using either channel= or tv://,
  mplayer segfaulted. That's corrected, now if you don't specify
  channel= or tv://, it picks up the first channel.
- I used quoting in channel names to enable spaces, but that seems
  to be to complicated. Now use _ in place of spaces, they are
  replaced at init.

(please see Istvan's screenshot using the patch at :
http://www.underworld.hu/~stevee/mplayertv.png ).


Attached is the new patch, please give it a test.

Thanks Istvan for your appreciated help in testing and debugging
my patch.

-- 
 ///  Stephane Jourdois        	/"\  ASCII RIBBON CAMPAIGN \\\
(((    Ingénieur développement 	\ /    AGAINST HTML MAIL    )))
 \\\   6, av. George V	         X                         ///
  \\\  75008  Paris             / \    +33 6 8643 3085    ///
-------------- next part --------------
Index: cfg-common.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-common.h,v
retrieving revision 1.69
diff -u -r1.69 cfg-common.h
--- cfg-common.h	5 Dec 2002 00:03:26 -0000	1.69
+++ cfg-common.h	22 Dec 2002 17:11:14 -0000
@@ -246,6 +246,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},
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.628
diff -u -r1.628 mplayer.c
--- mplayer.c	19 Dec 2002 10:09:27 -0000	1.628
+++ mplayer.c	22 Dec 2002 17:11:20 -0000
@@ -562,6 +562,7 @@
 int osd_show_sub_pos = 0;
 int osd_show_sub_visibility = 0;
 int osd_show_vobsub_changed = 0;
+int osd_show_tv_channel = 30;
 
 int rtc_fd=-1;
 
@@ -2282,15 +2283,44 @@
     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 = 30;
+	    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 = 30;
+	    vo_osd_changed(OSDTYPE_SUBTITLE);
+	  }
+#endif
+	}
       }
     } break;
     case MP_CMD_TV_SET_CHANNEL :  {
       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 = 30;
+		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 = 30;
+		vo_osd_changed(OSDTYPE_SUBTITLE);
+	}
+#endif
     } break;
     case MP_CMD_TV_STEP_NORM :  {
       if (tv_param_on == 1)
@@ -2733,6 +2763,12 @@
       if (osd_show_dvd_nav_delay) {
           sprintf(osd_text_tmp, "DVDNAV: %s", dvd_nav_text);
           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) {
Index: DOCS/mplayer.1
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/mplayer.1,v
retrieving revision 1.283
diff -u -r1.283 mplayer.1
--- DOCS/mplayer.1	21 Dec 2002 22:16:49 -0000	1.283
+++ DOCS/mplayer.1	22 Dec 2002 17:11:25 -0000
@@ -631,6 +631,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)
@@ -646,6 +647,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
Index: input/input.c
===================================================================
RCS file: /cvsroot/mplayer/main/input/input.c,v
retrieving revision 1.63
diff -u -r1.63 input.c
--- input/input.c	19 Dec 2002 10:09:42 -0000	1.63
+++ input/input.c	22 Dec 2002 17:11:29 -0000
@@ -75,6 +75,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}} } },
Index: input/input.h
===================================================================
RCS file: /cvsroot/mplayer/main/input/input.h,v
retrieving revision 1.27
diff -u -r1.27 input.h
--- input/input.h	19 Dec 2002 10:09:42 -0000	1.27
+++ input/input.h	22 Dec 2002 17:11:29 -0000
@@ -20,6 +20,7 @@
 #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_TV_LAST_CHANNEL 38
 #define MP_CMD_VO_FULLSCREEN 20
 #define MP_CMD_SUB_POS 21
 #define MP_CMD_DVDNAV 22
Index: libmpdemux/tv.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tv.c,v
retrieving revision 1.44
diff -u -r1.44 tv.c
--- libmpdemux/tv.c	19 Dec 2002 10:09:43 -0000	1.44
+++ libmpdemux/tv.c	22 Dec 2002 17:11:31 -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,38 +234,105 @@
 	goto done;
     }
 
-    /* we need to set frequency */
-    if (tv_param_freq)
-    {
-	unsigned long freq = atof(tv_param_freq)*16;
+    /* 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;
+	}
 
-        /* set freq in MHz */
-	funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &freq);
+	tv_channel_current->prev->next = NULL;
+	free(tv_channel_current);
+    } else 
+	    tv_channel_last_real = malloc(sizeof(char)*5);
 
-	funcs->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &freq);
-	mp_msg(MSGT_TV, MSGL_V, "Selected frequency: %lu (%.3f)\n",
-	    freq, (float)freq/16);
-    }
-
-    if (tv_param_channel)
-    {
-	struct CHANLIST cl;
+    if (tv_channel_list) {
+	int i;
+	int channel;
+	if (tv_param_channel)
+		channel = atoi(tv_param_channel);
+	else
+		channel = 1;
 
-	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);
-	    if (!strcasecmp(cl.name, tv_param_channel))
+	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)
 	    {
-		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;
+		unsigned long freq = atof(tv_param_freq)*16;
+
+		/* set freq in MHz */
+		funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &freq);
+
+		funcs->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &freq);
+		mp_msg(MSGT_TV, MSGL_V, "Selected frequency: %lu (%.3f)\n",
+		    freq, (float)freq/16);
+	    }
+
+	    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);
+			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);
+			tv_set_freq(tvh, (unsigned long)(((float)cl.freq/1000)*16));
+			break;
+			}
+		    }
 	    }
-	}
     }
     
     /* grep frequency in chanlist */
@@ -520,13 +588,14 @@
 	tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &freq);
 
 	tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &freq);
+
 	mp_msg(MSGT_TV, MSGL_V, "Current frequency: %lu (%.3f)\n",
 	    freq, (float)freq/16);
     }
     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 +603,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 +615,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 +625,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 +668,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)
Index: libmpdemux/tv.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tv.h,v
retrieving revision 1.20
diff -u -r1.20 tv.h
--- libmpdemux/tv.h	19 Dec 2002 10:09:43 -0000	1.20
+++ libmpdemux/tv.h	22 Dec 2002 17:11:32 -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);


More information about the MPlayer-dev-eng mailing list