changeset 23422:e7b4c913dc31

New "automute" tv:// option. Will switch off sound and show blue screen instead of video with noise when signal level (in 0-255 scale) is less than specified value.
author voroshil
date Thu, 31 May 2007 17:49:51 +0000
parents e013cf91368f
children 6b18c979dd45
files DOCS/man/en/mplayer.1 cfg-common.h stream/tv.c stream/tv.h stream/tvi_def.h stream/tvi_v4l.c stream/tvi_v4l2.c
diffstat 7 files changed, 80 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1	Thu May 31 17:30:49 2007 +0000
+++ b/DOCS/man/en/mplayer.1	Thu May 31 17:49:51 2007 +0000
@@ -1722,6 +1722,10 @@
 .RSs
 .IPs noaudio
 no sound
+.IPs automute=<0-255> (v4l and v4l2 only)
+If signal strength reported by device is less then this value,
+audio and video will be muted. In most cases automute=100 will be enough.
+Default is 0 (automute disabled).
 .IPs driver=<value>
 See \-tv driver=help for a list of compiled-in TV input drivers.
 available: dummy, v4l, v4l2, bsdbt848
--- a/cfg-common.h	Thu May 31 17:30:49 2007 +0000
+++ b/cfg-common.h	Thu May 31 17:49:51 2007 +0000
@@ -429,6 +429,7 @@
 	{"channel", &tv_param_channel, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	{"chanlist", &tv_param_chanlist, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	{"norm", &tv_param_norm, CONF_TYPE_STRING, 0, 0, 0, NULL},
+	{"automute", &tv_param_automute, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
 #ifdef HAVE_TV_V4L2
 	{"normid", &tv_param_normid, CONF_TYPE_INT, 0, 0, 0, NULL},
 #endif
--- a/stream/tv.c	Thu May 31 17:30:49 2007 +0000
+++ b/stream/tv.c	Thu May 31 17:49:51 2007 +0000
@@ -55,6 +55,7 @@
 float tv_param_fps = -1.0;
 char **tv_param_channels = NULL;
 int tv_param_audio_id = 0;
+int tv_param_automute = 0;
 #if defined(HAVE_TV_V4L)
 int tv_param_amode = -1;
 int tv_param_volume = -1;
--- a/stream/tv.h	Thu May 31 17:30:49 2007 +0000
+++ b/stream/tv.h	Thu May 31 17:49:51 2007 +0000
@@ -12,6 +12,7 @@
 extern char *tv_param_channel;
 extern char *tv_param_chanlist;
 extern char *tv_param_norm;
+extern int tv_param_automute;
 #ifdef HAVE_TV_V4L2
 extern int tv_param_normid;
 #endif
--- a/stream/tvi_def.h	Thu May 31 17:30:49 2007 +0000
+++ b/stream/tvi_def.h	Thu May 31 17:49:51 2007 +0000
@@ -52,3 +52,41 @@
 	free(h);
     }
 }
+
+/**
+ Fills video frame in given buffer with blue color for yv12,i420,uyvy,yuy2.
+ Other formats will be filled with 0xC0 
+*/
+static inline void fill_blank_frame(char* buffer,int len,int fmt){
+    int i;
+
+    switch(fmt){
+    case IMGFMT_YV12:
+        memset(buffer, 0xFF,5*len/6);
+        memset(buffer+5*len/6, 0xFF,len/6);
+        break;
+    case IMGFMT_I420:
+        memset(buffer, 0xFF,4*len/6);
+        memset(buffer+4*len/6, 0xFF,len/6);
+        memset(buffer+5*len/6, 0xFF,len/6);
+        break;
+    case IMGFMT_UYVY:
+        for(i=0;i<len;i+=4){
+            buffer[i]=0xFF;
+            buffer[i+1]=0;
+            buffer[i+2]=0;
+            buffer[i+3]=0;
+	}
+        break;
+    case IMGFMT_YUY2:
+        for(i=0;i<len;i+=4){
+            buffer[i]=0;
+            buffer[i+1]=0xFF;
+            buffer[i+2]=0;
+            buffer[i+3]=0;
+	}
+        break;
+    default:
+        memset(buffer,0xC0,len);
+    }
+}
--- a/stream/tvi_v4l.c	Thu May 31 17:30:49 2007 +0000
+++ b/stream/tvi_v4l.c	Thu May 31 17:49:51 2007 +0000
@@ -1381,6 +1381,21 @@
     return(TVI_CONTROL_UNKNOWN);
 }
 
+static int set_mute(priv_t* priv,int value)
+{
+    if (!priv->capability.audios) {
+        return 0;
+	
+    if(value)
+        priv->audio[priv->audio_id].flags |=VIDEO_AUDIO_MUTE;
+    else
+        priv->audio[priv->audio_id].flags &= ~VIDEO_AUDIO_MUTE;
+    }
+    if(ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id])<0)
+        return 0;
+    return 1;
+}
+
 // copies a video frame
 // for RGB (i.e. BGR in mplayer) flips the image upside down
 // for YV12 swaps the 2nd and 3rd plane
@@ -1389,6 +1404,16 @@
     int i;
     unsigned char *sptr;
 
+    if(tv_param_automute>0){
+        if (ioctl(priv->video_fd, VIDIOCGTUNER, &priv->tuner) >= 0) {
+            if(tv_param_automute<<8>priv->tuner.signal){
+                fill_blank_frame(dest,priv->bytesperline * priv->height,priv->format);
+                set_mute(priv,1);
+                return;
+            }
+        }
+        set_mute(priv,0);
+    }
     // YV12 uses VIDEO_PALETTE_YUV420P, but the planes are swapped
     if (priv->format == IMGFMT_YV12) {
         memcpy(dest, source, priv->width * priv->height);
--- a/stream/tvi_v4l2.c	Thu May 31 17:30:49 2007 +0000
+++ b/stream/tvi_v4l2.c	Thu May 31 17:49:51 2007 +0000
@@ -1321,6 +1321,16 @@
     int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
     int bytesperline = w*d/8;
 
+    if(tv_param_automute>0){
+        if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
+            if(tv_param_automute<<8>priv->tuner.signal){
+	        fill_blank_frame(dest,bytesperline * h,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
+	        set_mute(priv,1);
+	        return;
+	    }
+        }
+        set_mute(priv,0);
+    }
     memcpy(dest, source, bytesperline * h);
 }