[patch] bilangual support for Xvideo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hi,

I noticed yesterday that xawtv does not support switching between
mono/stereo/lang1/lang2 when using the xfree86 Xvideo extension
(the v4l module). Out of impulse I hacked right away...

Attached are two patches, one for xawtv-3.88, and one
for xfree86-4.X (against the newest v4l.c fetched from xfree86 CVS).
I didn't do much testing but it seems to work as I expected.


Johannes
--- xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c.cvs	2003-08-07 00:06:51.000000000 +0200
+++ xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c	2003-08-07 01:13:59.000000000 +0200
@@ -122,6 +122,7 @@ typedef struct _PortPrivRec {
     /* attributes */
     struct video_picture	pict;
     struct video_audio          audio;
+    int				audio_mode;
 
     XF86VideoEncodingPtr        enc;
     int                         *input;
@@ -148,12 +149,13 @@ typedef struct _PortPrivRec {
 
 #define XV_FREQ		"XV_FREQ"
 #define XV_MUTE		"XV_MUTE"
+#define XV_AUDIO_MODE	"XV_AUDIO_MODE"
 #define XV_VOLUME      	"XV_VOLUME"
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
 static Atom xvEncoding, xvBrightness, xvContrast, xvSaturation, xvHue;
-static Atom xvFreq, xvMute, xvVolume;
+static Atom xvFreq, xvMute, xvAudioMode, xvVolume;
 
 static XF86VideoFormatRec
 InputVideoFormats[] = {
@@ -176,6 +178,8 @@ static const XF86AttributeRec VolumeAttr
     {XvSettable | XvGettable, -1000,    1000, XV_VOLUME};
 static const XF86AttributeRec MuteAttr = 
     {XvSettable | XvGettable,     0,       1, XV_MUTE};
+static const XF86AttributeRec AudioModeAttr =
+    {XvSettable | XvGettable,     0,      15, XV_AUDIO_MODE};
 static const XF86AttributeRec FreqAttr = 
     {XvSettable | XvGettable,     0, 16*1000, XV_FREQ};
 
@@ -549,6 +553,7 @@ V4lSetPortAttribute(ScrnInfoPtr pScrn,
 	    pPPriv->cenc = value;
 	    chan.channel = pPPriv->input[value];
 	    chan.norm    = pPPriv->norm[value];
+	    pPPriv->audio_mode = 0;
 	    if (-1 == ioctl(V4L_FD,VIDIOCSCHAN,&chan))
 		perror("ioctl VIDIOCSCHAN");
 	} else {
@@ -566,6 +571,7 @@ V4lSetPortAttribute(ScrnInfoPtr pScrn,
 	if (-1 == ioctl(V4L_FD,VIDIOCSPICT,&pPPriv->pict))
 	    perror("ioctl VIDIOCSPICT");
     } else if (attribute == xvMute ||
+	       attribute == xvAudioMode ||
 	       attribute == xvVolume) {
 	ioctl(V4L_FD,VIDIOCGAUDIO,&pPPriv->audio);
 	if (attribute == xvMute) {
@@ -573,12 +579,24 @@ V4lSetPortAttribute(ScrnInfoPtr pScrn,
 		pPPriv->audio.flags |= VIDEO_AUDIO_MUTE;
 	    else
 		pPPriv->audio.flags &= ~VIDEO_AUDIO_MUTE;
+	} else if (attribute == xvAudioMode) {
+		if (value < 0)
+			value = 0;
+		else if (value > 8)
+			value = 8;
+		pPPriv->audio_mode = value;
 	} else if (attribute == xvVolume) {
 	    if (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME)
 		pPPriv->audio.volume = xv_to_v4l(value);
 	} else {
 	    ret = BadValue;
 	}
+	/* have to set that all the time as read and write have
+	 * slightly different semantics:
+	 *   read  == bitmask with all available modes flagged
+	 *   write == one bit set (for the selected mode, zero is autodetect)
+	 */
+	pPPriv->audio.mode = pPPriv->audio_mode;
 	if (ret != BadValue)
 	    if (-1 == ioctl(V4L_FD,VIDIOCSAUDIO,&pPPriv->audio))
 		perror("ioctl VIDIOCSAUDIO");
@@ -624,10 +642,13 @@ V4lGetPortAttribute(ScrnInfoPtr pScrn, 
 	if (attribute == xvSaturation) *value = v4l_to_xv(pPPriv->pict.colour);
 	if (attribute == xvHue)        *value = v4l_to_xv(pPPriv->pict.hue);
     } else if (attribute == xvMute ||
+	       attribute == xvAudioMode ||
 	       attribute == xvVolume) {
 	ioctl(V4L_FD,VIDIOCGAUDIO,&pPPriv->audio);
 	if (attribute == xvMute) {
 	    *value = (pPPriv->audio.flags & VIDEO_AUDIO_MUTE) ? 1 : 0;
+	} else if (attribute == xvAudioMode) {
+	    *value = pPPriv->audio.mode;
 	} else if (attribute == xvVolume) {
 	    if (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME)
 		*value = v4l_to_xv(pPPriv->audio.volume);
@@ -948,6 +969,8 @@ V4LInit(ScrnInfoPtr pScrn, XF86VideoAdap
 	    if (pPPriv->audio.flags & VIDEO_AUDIO_MUTABLE)
 		v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes,
 			     &MuteAttr);
+	    v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes,
+			 &AudioModeAttr);
 	}
 	if (pPPriv->cap.type & VID_TYPE_TUNER) {
 	    /* tuner attributes */
@@ -1003,6 +1026,7 @@ V4LInit(ScrnInfoPtr pScrn, XF86VideoAdap
 
     xvFreq       = MAKE_ATOM(XV_FREQ);
     xvMute       = MAKE_ATOM(XV_MUTE);
+    xvAudioMode  = MAKE_ATOM(XV_AUDIO_MODE);
     xvVolume     = MAKE_ATOM(XV_VOLUME);
 
     DEBUG(xf86Msg(X_INFO, "v4l: init done, %d device(s) found\n",i));
--- xawtv-3.88/x11/xv.c.orig	2003-08-07 00:16:42.000000000 +0200
+++ xawtv-3.88/x11/xv.c	2003-08-07 01:02:56.000000000 +0200
@@ -41,6 +41,15 @@ static XvAdaptorInfo        *ai;
 static XvEncodingInfo       *ei;
 static XvAttribute          *at;
 
+static struct STRTAB stereo[] = {
+    {  0, "auto"    },
+    {  1, "mono"    },
+    {  2, "stereo"  },
+    {  4, "lang1"   },
+    {  8, "lang2"   },
+    { -1, NULL },
+};
+
 static int
 xv_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y,
 	   struct OVERLAY_CLIP *oc, int count, int aspect)
@@ -82,16 +91,17 @@ static const struct XVATTR {
     int   type;
     char  *atom;
 } xvattr[] = {
-    { ATTR_ID_COLOR,    ATTR_TYPE_INTEGER, "XV_COLOR"       },
-    { ATTR_ID_COLOR,    ATTR_TYPE_INTEGER, "XV_SATURATION"  },
-    { ATTR_ID_HUE,      ATTR_TYPE_INTEGER, "XV_HUE",        },
-    { ATTR_ID_BRIGHT,   ATTR_TYPE_INTEGER, "XV_BRIGHTNESS", },
-    { ATTR_ID_CONTRAST, ATTR_TYPE_INTEGER, "XV_CONTRAST",   },
-    { ATTR_ID_MUTE,     ATTR_TYPE_BOOL,    "XV_MUTE",       },
-    { ATTR_ID_VOLUME,   ATTR_TYPE_INTEGER, "XV_VOLUME",     },
-    { -1,               -1,                "XV_COLORKEY",   },
-    { -1,               -1,                "XV_FREQ",       },
-    { -1,               -1,                "XV_ENCODING",   },
+    { ATTR_ID_COLOR,      ATTR_TYPE_INTEGER, "XV_COLOR"       },
+    { ATTR_ID_COLOR,      ATTR_TYPE_INTEGER, "XV_SATURATION"  },
+    { ATTR_ID_HUE,        ATTR_TYPE_INTEGER, "XV_HUE",        },
+    { ATTR_ID_BRIGHT,     ATTR_TYPE_INTEGER, "XV_BRIGHTNESS", },
+    { ATTR_ID_CONTRAST,   ATTR_TYPE_INTEGER, "XV_CONTRAST",   },
+    { ATTR_ID_MUTE,       ATTR_TYPE_BOOL,    "XV_MUTE",       },
+    { ATTR_ID_AUDIO_MODE, ATTR_TYPE_CHOICE,  "XV_AUDIO_MODE", },
+    { ATTR_ID_VOLUME,     ATTR_TYPE_INTEGER, "XV_VOLUME",     },
+    { -1,                 -1,                "XV_COLORKEY",   },
+    { -1,                 -1,                "XV_FREQ",       },
+    { -1,                 -1,                "XV_ENCODING",   },
     {}
 };
 
@@ -422,8 +432,12 @@ void xv_video_init(unsigned int port, in
 			at[i].min_value,at[i].max_value);
             if (0 == strcmp("XV_ENCODING",at[i].name))
                 handle->xv_encoding = XV_ENCODING;
-            if (0 == strcmp("XV_FREQ",at[i].name))
+	    else if (0 == strcmp("XV_FREQ",at[i].name))
                 handle->xv_freq     = XV_FREQ;
+	    else if (0 == strcmp("XV_AUDIO_MODE",at[i].name)) {
+		xv_add_attr(handle, 0, 0, 0, stereo, at+i);
+                continue;
+	    }
 #if 0
             if (0 == strcmp("XV_COLORKEY",at[i].name))
                 handle->xv_colorkey = XV_COLORKEY;

[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux