Hi,
Really, I previously overlooked tv_set_color_options in tv.c. Here is
the patch which does the eq setting via this function. I only moved the
option handling code from tvi_v4l.c to tv.c because I need the eq
setting in mencoder too, eg. for grabbing tv series with the same
settings. I also fixed the calculations in tv_set_color_options.
The rest of patch is unchanged.
--
Jindrich Makovicka
diff -urN --exclude-from dontdiff vanilla/main/DOCS/mplayer.1 main/DOCS/mplayer.1
--- vanilla/main/DOCS/mplayer.1 Wed Aug 28 18:06:59 2002
+++ main/DOCS/mplayer.1 Wed Aug 28 21:57:43 2002
@@ -312,13 +312,41 @@
us-cable, etc
audiorate=<value> set audio capture bitrate
alsa capture from ALSA
- mono force mono audio
+ amode=<0..3> choose an audio mode:
+ 0 .. mono
+ 1 .. stereo
+ 2 .. language 1
+ 3 .. language 2
+ forcechan=<1,2> By default, the count of
+ recorded audio channels is
+ determined automatically
+ by querying the audio mode
+ from the tv card. This option
+ allows to force stereo/mono
+ recording regardless of the
+ amode option and the values
+ returned by v4l. This can
+ be used for troubleshooting
+ when the tv card is unable
+ to report the current audio
+ mode.
adevice=<value> set an audio device
/dev/... for OSS,
hardware ID for ALSA
audioid=<value> choose an audio output
of the capture card, if it
has more of them
+ volume=<value> These options set
+ bass=<value> parameters of the mixer
+ treble=<value> on the video capture card.
+ balance=<value> They will have no effect,
+ if your card doesn't have
+ one. All values are from
+ 0 to 65535.
+ brightness=<val> set tv brightness
+ hue=<value> set tv hue
+ saturation=<val> set tv saturation
+ contrast=<value> set tv contrast
.I NOTE:
Mplayer doesn't accept colons so type dots instead in the device ID,
diff -urN --exclude-from dontdiff vanilla/main/cfg-common.h main/cfg-common.h
--- vanilla/main/cfg-common.h Wed Aug 28 20:42:18 2002
+++ main/cfg-common.h Wed Aug 28 22:03:33 2002
@@ -197,8 +197,17 @@
{"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},
+ {"brightness", &tv_param_brightness, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+ {"hue", &tv_param_hue, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+ {"saturation", &tv_param_saturation, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+ {"contrast", &tv_param_contrast, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
#ifdef HAVE_TV_V4L
- {"mono", &tv_param_mono, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+ {"amode", &tv_param_amode, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL},
+ {"volume", &tv_param_volume, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
+ {"bass", &tv_param_bass, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
+ {"treble", &tv_param_treble, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
+ {"balance", &tv_param_balance, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
+ {"forcechan", &tv_param_forcechan, CONF_TYPE_INT, CONF_RANGE, 1, 2, NULL},
#ifdef HAVE_ALSA9
{"alsa", &tv_param_alsa, CONF_TYPE_FLAG, 0, 0, 1, NULL},
#endif
diff -urN --exclude-from dontdiff vanilla/main/libmpdemux/tv.c main/libmpdemux/tv.c
--- vanilla/main/libmpdemux/tv.c Thu Aug 22 18:02:39 2002
+++ main/libmpdemux/tv.c Wed Aug 28 22:09:30 2002
@@ -51,9 +51,18 @@
int tv_param_input = 0; /* used in v4l and bttv */
char *tv_param_outfmt = "yv12";
float tv_param_fps = -1.0;
+int tv_param_brightness = -1;
+int tv_param_hue = -1;
+int tv_param_saturation = -1;
+int tv_param_contrast = -1;
#ifdef HAVE_TV_V4L
-int tv_param_mono = 0;
+int tv_param_amode = -1;
int tv_param_audio_id = 0;
+int tv_param_volume = 60000;
+int tv_param_bass = -1;
+int tv_param_treble = -1;
+int tv_param_balance = -1;
+int tv_param_forcechan = -1;
#ifdef HAVE_ALSA9
int tv_param_alsa = 0;
#endif
@@ -180,6 +189,15 @@
}
}
+ if (tv_param_brightness >= 0)
+ tv_set_color_options(tvh, TV_COLOR_BRIGHTNESS, tv_param_brightness);
+ if (tv_param_hue >= 0)
+ tv_set_color_options(tvh, TV_COLOR_HUE, tv_param_hue);
+ if (tv_param_saturation >= 0)
+ tv_set_color_options(tvh, TV_COLOR_SATURATION, tv_param_saturation);
+ if (tv_param_contrast >= 0)
+ tv_set_color_options(tvh, TV_COLOR_CONTRAST, tv_param_contrast);
+
if (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) != TVI_CONTROL_TRUE)
{
mp_msg(MSGT_TV, MSGL_WARN, "Selected input hasn't got a tuner!\n");
@@ -421,7 +439,6 @@
return(tvh->functions->uninit(tvh->priv));
}
-/* utilities for mplayer (not mencoder!!) */
int tv_set_color_options(tvi_handle_t *tvh, int opt, int value)
{
tvi_functions_t *funcs = tvh->functions;
@@ -429,71 +446,19 @@
switch(opt)
{
case TV_COLOR_BRIGHTNESS:
- if (value == 50)
- value = 32768;
- if (value > 50)
- {
- value *= 100;
- value += 32768;
- }
- if (value < 50)
- {
- int i;
- value *= 100;
- i = value;
- value = 32768 - i;
- }
+ value = 32768+(value-50)*400;
funcs->control(tvh->priv, TVI_CONTROL_VID_SET_BRIGHTNESS, &value);
break;
case TV_COLOR_HUE:
- if (value == 50)
- value = 32768;
- if (value > 50)
- {
- value *= 100;
- value += 32768;
- }
- if (value < 50)
- {
- int i;
- value *= 100;
- i = value;
- value = 32768 - i;
- }
+ value = 32768+(value-50)*400;
funcs->control(tvh->priv, TVI_CONTROL_VID_SET_HUE, &value);
break;
case TV_COLOR_SATURATION:
- if (value == 50)
- value = 32512;
- if (value > 50)
- {
- value *= 100;
- value += 32512;
- }
- if (value < 50)
- {
- int i;
- value *= 100;
- i = value;
- value = 32512 - i;
- }
+ value = 32512+(value-50)*400;
funcs->control(tvh->priv, TVI_CONTROL_VID_SET_SATURATION, &value);
break;
case TV_COLOR_CONTRAST:
- if (value == 50)
- value = 27648;
- if (value > 50)
- {
- value *= 100;
- value += 27648;
- }
- if (value < 50)
- {
- int i;
- value *= 100;
- i = value;
- value = 27648 - i;
- }
+ value = 27648+(value-50)*400;
funcs->control(tvh->priv, TVI_CONTROL_VID_SET_CONTRAST, &value);
break;
default:
@@ -503,6 +468,7 @@
return(1);
}
+/* utilities for mplayer (not mencoder!!) */
int tv_set_freq(tvi_handle_t *tvh, unsigned long freq)
{
if (tvh->functions->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) == TVI_CONTROL_TRUE)
diff -urN --exclude-from dontdiff vanilla/main/libmpdemux/tv.h main/libmpdemux/tv.h
--- vanilla/main/libmpdemux/tv.h Thu Aug 22 18:02:39 2002
+++ main/libmpdemux/tv.h Wed Aug 28 21:43:12 2002
@@ -24,8 +24,17 @@
extern int tv_param_immediate;
extern int tv_param_audiorate;
#ifdef HAVE_TV_V4L
-extern int tv_param_mono;
+extern int tv_param_amode;
extern int tv_param_audio_id;
+extern int tv_param_volume;
+extern int tv_param_bass;
+extern int tv_param_treble;
+extern int tv_param_balance;
+extern int tv_param_forcechan;
+extern int tv_param_brightness;
+extern int tv_param_hue;
+extern int tv_param_saturation;
+extern int tv_param_contrast;
#ifdef HAVE_ALSA9
extern int tv_param_alsa;
#endif
diff -urN --exclude-from dontdiff vanilla/main/libmpdemux/tvi_v4l.c main/libmpdemux/tvi_v4l.c
--- vanilla/main/libmpdemux/tvi_v4l.c Fri Aug 23 18:38:41 2002
+++ main/libmpdemux/tvi_v4l.c Wed Aug 28 21:39:57 2002
@@ -144,8 +144,20 @@
};
#define PALETTE(x) ((x < sizeof(device_pal)/sizeof(char*)) ? device_pal[x] : "UNKNOWN")
-static const char *audio_mode2name[] = {
- "unknown", "mono", "stereo", "language1", "language2", NULL
+static const char *audio_mode2name(int mode)
+{
+ switch (mode) {
+ case VIDEO_SOUND_MONO:
+ return "mono";
+ case VIDEO_SOUND_STEREO:
+ return "stereo";
+ case VIDEO_SOUND_LANG1:
+ return "language1";
+ case VIDEO_SOUND_LANG2:
+ return "language2";
+ default:
+ return "unknown";
+ }
};
static void *audio_grabber(void *data);
@@ -262,6 +274,7 @@
static void init_v4l_audio(priv_t *priv)
{
int i;
+ int reqmode;
if (!priv->capability.audios) return;
@@ -289,15 +302,26 @@
/* mute all channels */
priv->audio[i].volume = 0;
priv->audio[i].flags |= VIDEO_AUDIO_MUTE;
- if (tv_param_mono) {
- priv->audio[i].mode = VIDEO_SOUND_MONO;
- ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[i]);
- } else {
- /* try to set stereo */
- priv->audio[i].mode = VIDEO_SOUND_STEREO;
- ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[i]);
+ if (tv_param_amode >= 0) {
+ switch (tv_param_amode) {
+ case 0:
+ reqmode = VIDEO_SOUND_MONO;
+ break;
+ case 1:
+ reqmode = VIDEO_SOUND_STEREO;
+ break;
+ case 2:
+ reqmode = VIDEO_SOUND_LANG1;
+ break;
+ case 3:
+ reqmode = VIDEO_SOUND_LANG2;
+ break;
+ }
}
+ priv->audio[i].mode = reqmode;
+ ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[i]);
+ // get the parameters back
if (ioctl(priv->video_fd, VIDIOCGAUDIO, &priv->audio[i]) == -1)
{
mp_msg(MSGT_TV, MSGL_ERR, "ioctl get audio failed: %s\n", strerror(errno));
@@ -316,7 +340,15 @@
break;
}
+ if (tv_param_amode >= 0 && priv->audio[i].mode != reqmode) {
+ mp_msg(MSGT_TV, MSGL_ERR, "Audio mode setup warning!\n");
+ mp_msg(MSGT_TV, MSGL_ERR, "Requested mode was %s, but v4l still reports %s.\n",
+ audio_mode2name(reqmode), audio_mode2name(priv->audio[i].mode));
+ mp_msg(MSGT_TV, MSGL_ERR, "You may need \"forcechan\" option\nto force stereo/mono audio recording.\n");
+ }
+
/* display stuff */
+ mp_msg(MSGT_TV, MSGL_V, "Video capture card reports the audio setup as follows:\n");
mp_msg(MSGT_TV, MSGL_V, " %d: %s: ", priv->audio[i].audio,
priv->audio[i].name);
if (priv->audio[i].flags & VIDEO_AUDIO_MUTABLE) {
@@ -325,8 +357,17 @@
}
mp_msg(MSGT_TV, MSGL_V, "volume=%d bass=%d treble=%d balance=%d mode=%s\n",
priv->audio[i].volume, priv->audio[i].bass, priv->audio[i].treble,
- priv->audio[i].balance, audio_mode2name[priv->audio[i].mode]);
+ priv->audio[i].balance, audio_mode2name(priv->audio[i].mode));
mp_msg(MSGT_TV, MSGL_V, " channels: %d\n", priv->audio_channels[i]);
+
+ if (tv_param_forcechan >= 0)
+ priv->audio_channels[i] = tv_param_forcechan;
+
+ // we'll call VIDIOCSAUDIO again when starting capture
+ // let's set audio mode to requested mode again for the case
+ // when VIDIOCGAUDIO just cannot report the mode correctly
+ if (tv_param_amode >= 0)
+ priv->audio[i].mode = reqmode;
}
}
@@ -697,14 +738,20 @@
priv->first = 1;
/* enable audio */
- if (priv->audio[priv->audio_id].volume <= 0)
- priv->audio[priv->audio_id].volume = 100;
+ if (tv_param_volume >= 0)
+ priv->audio[priv->audio_id].volume = tv_param_volume;
+ if (tv_param_bass >= 0)
+ priv->audio[priv->audio_id].bass = tv_param_bass;
+ if (tv_param_treble >= 0)
+ priv->audio[priv->audio_id].treble = tv_param_treble;
+ if (tv_param_balance >= 0)
+ priv->audio[priv->audio_id].balance = tv_param_balance;
priv->audio[priv->audio_id].flags &= ~VIDEO_AUDIO_MUTE;
- mp_msg(MSGT_TV, MSGL_V, "Starting audio capture\n");
+ mp_msg(MSGT_TV, MSGL_V, "Starting audio capture. Requested setup is:\n");
mp_msg(MSGT_TV, MSGL_V, "id=%d volume=%d bass=%d treble=%d balance=%d mode=%s\n",
priv->audio_id,
priv->audio[priv->audio_id].volume, priv->audio[priv->audio_id].bass, priv->audio[priv->audio_id].treble,
- priv->audio[priv->audio_id].balance, audio_mode2name[priv->audio[priv->audio_id].mode]);
+ priv->audio[priv->audio_id].balance, audio_mode2name(priv->audio[priv->audio_id].mode));
mp_msg(MSGT_TV, MSGL_V, " channels: %d\n", priv->audio_channels[priv->audio_id]);
ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);