changeset 7163:a193df8b275b

v4l audio fixes by Jindrich Makovicka <makovick@KMLinux.fjfi.cvut.cz>
author alex
date Fri, 30 Aug 2002 11:37:42 +0000
parents c672c79cb396
children 6175f7d18f8c
files DOCS/mplayer.1 cfg-common.h libmpdemux/tv.c libmpdemux/tv.h libmpdemux/tvi_v4l.c
diffstat 5 files changed, 104 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/mplayer.1	Fri Aug 30 11:28:43 2002 +0000
+++ b/DOCS/mplayer.1	Fri Aug 30 11:37:42 2002 +0000
@@ -312,13 +312,37 @@
                       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.
 
 .I NOTE:
 Mplayer doesn't accept colons so type dots instead in the device ID,
--- a/cfg-common.h	Fri Aug 30 11:28:43 2002 +0000
+++ b/cfg-common.h	Fri Aug 30 11:37:42 2002 +0000
@@ -206,7 +206,12 @@
 	{"outfmt", &tv_param_outfmt, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	{"fps", &tv_param_fps, CONF_TYPE_FLOAT, 0, 0, 100.0, 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
--- a/libmpdemux/tv.c	Fri Aug 30 11:28:43 2002 +0000
+++ b/libmpdemux/tv.c	Fri Aug 30 11:37:42 2002 +0000
@@ -52,8 +52,13 @@
 char *tv_param_outfmt = "yv12";
 float tv_param_fps = -1.0;
 #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
--- a/libmpdemux/tv.h	Fri Aug 30 11:28:43 2002 +0000
+++ b/libmpdemux/tv.h	Fri Aug 30 11:37:42 2002 +0000
@@ -24,8 +24,13 @@
 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;
 #ifdef HAVE_ALSA9
 extern int tv_param_alsa;
 #endif
--- a/libmpdemux/tvi_v4l.c	Fri Aug 30 11:28:43 2002 +0000
+++ b/libmpdemux/tvi_v4l.c	Fri Aug 30 11:37:42 2002 +0000
@@ -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]);