[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