changeset 7532:26cd91676fb6

complex patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
author alex
date Sat, 28 Sep 2002 18:49:47 +0000
parents 3eb3d3d832d9
children abc3b12165b7
files libmpdemux/tvi_v4l.c
diffstat 1 files changed, 92 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/tvi_v4l.c	Sat Sep 28 18:49:07 2002 +0000
+++ b/libmpdemux/tvi_v4l.c	Sat Sep 28 18:49:47 2002 +0000
@@ -140,9 +140,25 @@
 static const char *device_palette2name[] = {
     "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422",
     "yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p",
-    "yuv420p", "yuv410p", NULL
+    "yuv420p", "yuv410p"
 };
-#define PALETTE(x) ((x < sizeof(device_pal)/sizeof(char*)) ? device_pal[x] : "UNKNOWN")
+#define PALETTE(x) ((x < sizeof(device_palette2name)/sizeof(char*)) ? device_palette2name[x] : "UNKNOWN")
+
+static const char *norm2name(int mode)
+{
+    switch (mode) {
+    case VIDEO_MODE_PAL:
+	return "pal";
+    case VIDEO_MODE_SECAM:
+	return "secam";
+    case VIDEO_MODE_NTSC:
+	return "ntsc";
+    case VIDEO_MODE_AUTO:
+	return "auto";
+    default:
+	return "unknown";
+    }
+};
 
 static const char *audio_mode2name(int mode)
 {
@@ -280,6 +296,7 @@
 
     mp_msg(MSGT_TV, MSGL_V, " Audio devices: %d\n", priv->capability.audios);
 
+    mp_msg(MSGT_TV, MSGL_V, "Video capture card reports the audio setup as follows:\n");
     for (i = 0; i < priv->capability.audios; i++)
     {
 	if (i >= MAX_AUDIO_CHANNELS)
@@ -300,6 +317,7 @@
 	/* mute all channels */
 	priv->audio[i].volume = 0;
 	priv->audio[i].flags |= VIDEO_AUDIO_MUTE;
+	reqmode = -1;
 	if (tv_param_amode >= 0) {
 	    switch (tv_param_amode) {
 	    case 0:
@@ -314,9 +332,12 @@
 	    case 3:
 		reqmode = VIDEO_SOUND_LANG2;
 		break;
+	    default:
+		mp_msg(MSGT_TV, MSGL_ERR, "Unknown audio mode requested.\n");
+		break;
 	    }
+	    if (reqmode >= 0) priv->audio[i].mode = reqmode;
 	}
-	priv->audio[i].mode = reqmode;
 	ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[i]);
 	
 	// get the parameters back
@@ -338,25 +359,24 @@
 	    break;
 	}
 
-	if (tv_param_amode >= 0 && priv->audio[i].mode != reqmode) {
+	if (reqmode >= 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");
+	    mp_msg(MSGT_TV, MSGL_ERR, "You may need \"forcechan\" option to 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) {
 	    mp_msg(MSGT_TV, MSGL_V, "muted=%s ",
 		   (priv->audio[i].flags & VIDEO_AUDIO_MUTE) ? "yes" : "no");
 	}
-	mp_msg(MSGT_TV, MSGL_V, "volume=%d bass=%d treble=%d balance=%d mode=%s\n",
+	mp_msg(MSGT_TV, MSGL_V, "vol=%d bass=%d treble=%d balance=%d mode=%s",
 	       priv->audio[i].volume, priv->audio[i].bass, priv->audio[i].treble,
 	       priv->audio[i].balance, audio_mode2name(priv->audio[i].mode));
-	mp_msg(MSGT_TV, MSGL_V, " channels: %d\n", priv->audio_channels[i]);
+	mp_msg(MSGT_TV, MSGL_V, " chan=%d\n", priv->audio_channels[i]);
 
 	if (tv_param_forcechan >= 0)
 	    priv->audio_channels[i] = tv_param_forcechan;
@@ -364,8 +384,7 @@
 	// 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; 
+	if (reqmode >= 0) priv->audio[i].mode = reqmode;
     }
 }
 
@@ -391,8 +410,6 @@
 	goto err;
     }
     
-    priv->fps = PAL_FPS; /* pal */
-    
     /* get capabilities (priv->capability is needed!) */
     if (ioctl(priv->video_fd, VIDIOCGCAP, &priv->capability) == -1)
     {
@@ -400,25 +417,6 @@
 	goto err;
     }
 
-    if (ioctl(priv->video_fd, VIDIOCGTUNER, &priv->tuner) == -1)
-    {
-	mp_msg(MSGT_TV, MSGL_ERR, "ioctl get tuner failed: %s\n", strerror(errno));
-	priv->fps = PAL_FPS;
-//	goto err;
-    } else
-    switch (priv->tuner.mode) {
-    case VIDEO_MODE_PAL:
-    case VIDEO_MODE_SECAM:
-	priv->fps = PAL_FPS;
-	break;
-    case VIDEO_MODE_NTSC:
-	priv->fps = NTSC_FPS;
-	break;
-    default:
-	mp_msg(MSGT_TV, MSGL_ERR, "get tuner returned an unknown mode: %d\n", priv->tuner.mode);
-	goto err;
-    }
-
     fcntl(priv->video_fd, F_SETFD, FD_CLOEXEC);
 
     mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.name);
@@ -447,15 +445,16 @@
 	    mp_msg(MSGT_TV, MSGL_ERR, "ioctl get channel failed: %s\n", strerror(errno));
 	    break;
 	}
-	mp_msg(MSGT_TV, MSGL_INFO, "  %d: %s: %s%s%s%s (tuner:%d, norm:%d)\n", i,
+	mp_msg(MSGT_TV, MSGL_INFO, "  %d: %s: %s%s%s%s (tuner:%d, norm:%s)\n", i,
 	    priv->channels[i].name,
 	    (priv->channels[i].flags & VIDEO_VC_TUNER) ? "tuner " : "",
 	    (priv->channels[i].flags & VIDEO_VC_AUDIO) ? "audio " : "",
 	    (priv->channels[i].flags & VIDEO_TYPE_TV) ? "tv " : "",
 	    (priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : "",
 	    priv->channels[i].tuners,
-	    priv->channels[i].norm);
+	    norm2name(priv->channels[i].norm));
     }
+    priv->act_channel = 0;
 
     if (!(priv->capability.type & VID_TYPE_CAPTURE))
     {
@@ -585,12 +584,9 @@
     bufsize = 16*1024*1024;
 #endif
 
-    cnt = bufsize/(priv->width*priv->bytesperline);
+    cnt = bufsize/(priv->height*priv->bytesperline);
     if (cnt < 2) cnt = 2;
     
-    mp_msg(MSGT_TV, MSGL_V, "Allocating a ring buffer for %d frames, %d MB total size.\n",
-	   cnt, cnt*priv->width*priv->bytesperline/(1024*1024));
-
     return cnt;
 }
 
@@ -615,8 +611,8 @@
     }
 
     mp_msg(MSGT_TV, MSGL_V, "Picture values:\n");
-    mp_msg(MSGT_TV, MSGL_V, " Depth: %d, Palette: %d (Format: %s)\n", priv->picture.depth,
-	priv->picture.palette, vo_format_name(priv->format));
+    mp_msg(MSGT_TV, MSGL_V, " Depth: %d, Palette: %s (Format: %s)\n", priv->picture.depth,
+	PALETTE(priv->picture.palette), vo_format_name(priv->format));
     mp_msg(MSGT_TV, MSGL_V, " Brightness: %d, Hue: %d, Colour: %d, Contrast: %d\n",
 	priv->picture.brightness, priv->picture.hue,
 	priv->picture.colour, priv->picture.contrast);
@@ -719,6 +715,10 @@
 	}
     }
 
+    mp_msg(MSGT_TV, MSGL_V, "Allocating a ring buffer for %d frames, %d MB total size.\n",
+	   priv->video_buffer_size,
+	   priv->video_buffer_size*priv->height*priv->bytesperline/(1024*1024));
+
     priv->video_ringbuffer = (unsigned char*)malloc(priv->bytesperline * priv->height * priv->video_buffer_size);
     if (!priv->video_ringbuffer) {
 	mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
@@ -734,24 +734,26 @@
     priv->video_cnt = 0;
     priv->first = 1;
 
-    /* enable audio */
-    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. 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));
-    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]);
-	    
+    if (priv->capability.audios) {
+	/* enable audio */
+	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, "Enabling tv audio. Requested setup is:\n");
+	mp_msg(MSGT_TV, MSGL_V, "id=%d vol=%d bass=%d treble=%d balance=%d mode=%s",
+	       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));
+	mp_msg(MSGT_TV, MSGL_V, " chan=%d\n", priv->audio_channels[priv->audio_id]);
+	ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);
+    }
+    
     /* launch capture threads */
     priv->shutdown = 0;
     if (!tv_param_noaudio) {
@@ -951,27 +953,48 @@
 		return(TVI_CONTROL_FALSE);
 	    }
 
-	    if (((req_mode == TV_NORM_PAL) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) ||
-		((req_mode == TV_NORM_NTSC) && !(priv->tuner.flags & VIDEO_TUNER_NTSC)) ||
-		((req_mode == TV_NORM_SECAM) && !(priv->tuner.flags & VIDEO_TUNER_SECAM)))
-	    {
-		mp_msg(MSGT_TV, MSGL_ERR, "Tuner isn't capable to set norm!\n");
-		return(TVI_CONTROL_FALSE);
+	    if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER) {
+		control(priv, TVI_CONTROL_TUN_GET_TUNER, 0);
+		if (((req_mode == TV_NORM_PAL) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) ||
+		    ((req_mode == TV_NORM_NTSC) && !(priv->tuner.flags & VIDEO_TUNER_NTSC)) ||
+		    ((req_mode == TV_NORM_SECAM) && !(priv->tuner.flags & VIDEO_TUNER_SECAM)))
+		{
+		    mp_msg(MSGT_TV, MSGL_ERR, "Tuner isn't capable to set norm!\n");
+		    return(TVI_CONTROL_FALSE);
+		}
+
+		switch(req_mode) {
+		case TV_NORM_PAL:
+		    priv->tuner.mode = VIDEO_MODE_PAL;
+		    break;
+		case TV_NORM_NTSC:
+		    priv->tuner.mode = VIDEO_MODE_NTSC;
+		    break;
+		case TV_NORM_SECAM:
+		    priv->tuner.mode = VIDEO_MODE_SECAM;
+		    break;
+		}
+	    
+		if (control(priv, TVI_CONTROL_TUN_SET_TUNER, &priv->tuner) != TVI_CONTROL_TRUE) {
+		    return(TVI_CONTROL_FALSE);
+		}
+
 	    }
 
 	    switch(req_mode) {
 	    case TV_NORM_PAL:
-		priv->tuner.mode = VIDEO_MODE_PAL;
+		priv->channels[priv->act_channel].norm = VIDEO_MODE_PAL;
 		break;
 	    case TV_NORM_NTSC:
-		priv->tuner.mode = VIDEO_MODE_NTSC;
+		priv->channels[priv->act_channel].norm = VIDEO_MODE_NTSC;
 		break;
 	    case TV_NORM_SECAM:
-		priv->tuner.mode = VIDEO_MODE_SECAM;
+		priv->channels[priv->act_channel].norm = VIDEO_MODE_SECAM;
 		break;
 	    }
-	    
-	    if (control(priv, TVI_CONTROL_TUN_SET_TUNER, &priv->tuner) != TVI_CONTROL_TRUE) {
+	    if (ioctl(priv->video_fd, VIDIOCSCHAN, &priv->channels[priv->act_channel]) == -1)
+	    {
+		mp_msg(MSGT_TV, MSGL_ERR, "ioctl set chan failed: %s\n", strerror(errno));
 		return(TVI_CONTROL_FALSE);
 	    }
 
@@ -1148,7 +1171,7 @@
     int first = 1;
 
     int dropped = 0;
-    double dropped_time;
+    double dropped_time = 0.0;
     double drop_delta = 0.0;
 
     /* start the capture process */