[MPlayer-dev-eng] [PATCH] blue back tv feature (automute with no signal)
Vladimir Voroshilov
voroshil at gmail.com
Thu May 24 17:29:30 CEST 2007
2007/5/23, Vladimir Voroshilov <voroshil at gmail.com>:
> Hi, All.
>
> Attached patch implements nice feature, already existed in many
> software and standalone tvs: auto muting video and audio when no (or
> too poor quality)
> signal presents. Currently implemented only for v4l and v4l2.
> The idea was offered by Karthik Kumar.
>
> Disadvantages:
> 1. ioctl call overhead (ioctl for getting signal strength is called
> from copy_frame, i.e.at least every 1/25 sec for PAL). Is this bad or
> not ?
> 2. pink screen instead on blue one.
Fixed for most common pixel formats.
> 3. no apropriate osd message
>
> (3) i need a hint how to show "no signal" osd msg all time until
> signal will appear.
Can anybody advise me how to show osd message from inside tvi_*.c
(i.e. from stream module)
> Opinions? Suggestions about (1),(3) ?
>
Updated patch is attached. This is more or less final version. I want
to aply this version in a week if nobody has objections.
--
Regards,
Vladimir Voroshilov mailto:voroshil at gmail.com
JID: voroshil at jabber.ru
ICQ: 95587719
-------------- next part --------------
Index: stream/tvi_v4l2.c
===================================================================
--- stream/tvi_v4l2.c (revision 23382)
+++ stream/tvi_v4l2.c (working copy)
@@ -94,6 +94,8 @@
volatile int video_buffer_size_current;
unsigned char **video_ringbuffer;
long long *video_timebuffer;
+ unsigned char* blank_frame;
+ int blank_frame_size;
volatile int video_head;
volatile int video_tail;
volatile int video_cnt;
@@ -924,6 +926,11 @@
free(priv->audio_skew_delta_buffer);
}
+ if(priv->blank_frame){
+ free(priv->blank_frame);
+ priv->blank_frame=NULL;
+ priv->blank_frame_size=0;
+ }
/* show some nice statistics ;-) */
mp_msg(MSGT_TV, MSGL_INFO,
"%s: %d frames successfully processed, %d frames dropped.\n",
@@ -1321,6 +1328,23 @@
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){
+ if(priv->blank_frame_size!=bytesperline * h){
+ if(priv->blank_frame)
+ free(priv->blank_frame);
+ priv->blank_frame=(unsigned char*)malloc(bytesperline * h);
+ priv->blank_frame_size=bytesperline * h;
+ fill_blank_frame(priv->blank_frame,bytesperline * h,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
+ }
+ memcpy(dest,priv->blank_frame,bytesperline * h);
+ set_mute(priv,1);
+ return;
+ }
+ }
+ set_mute(priv,0);
+ }
memcpy(dest, source, bytesperline * h);
}
Index: stream/tv.c
===================================================================
--- stream/tv.c (revision 23382)
+++ stream/tv.c (working copy)
@@ -56,6 +56,7 @@
float tv_param_fps = -1.0;
char **tv_param_channels = NULL;
int tv_param_audio_id = 0;
+unsigned int tv_param_automute = 0;
#if defined(HAVE_TV_V4L)
int tv_param_amode = -1;
int tv_param_volume = -1;
Index: stream/tv.h
===================================================================
--- stream/tv.h (revision 23382)
+++ stream/tv.h (working copy)
@@ -13,6 +13,7 @@
extern char *tv_param_channel;
extern char *tv_param_chanlist;
extern char *tv_param_norm;
+extern unsigned int tv_param_automute;
#ifdef HAVE_TV_V4L2
extern int tv_param_normid;
#endif
Index: stream/tvi_def.h
===================================================================
--- stream/tvi_def.h (revision 23382)
+++ stream/tvi_def.h (working copy)
@@ -52,3 +52,34 @@
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;
+
+ memset(buffer,0,len);
+ //following code will set only nonzero bytes of video frame
+ switch(fmt){
+ case IMGFMT_YV12:
+ memset(buffer+5*len/6, 0xFF,len/6);
+ break;
+ case IMGFMT_I420:
+ memset(buffer+4*len/6, 0xff,len/6);
+ break;
+ case IMGFMT_UYVY:
+ for(i=0;i<len;i+=4)
+ buffer[i]=0xff;
+ break;
+ case IMGFMT_YUY2:
+ for(i=1;i<len;i+=4)
+ buffer[i]=0xff;
+ break;
+ default:
+ memset(buffer,0xC0,len);
+ }
+}
Index: stream/tvi_v4l.c
===================================================================
--- stream/tvi_v4l.c (revision 23382)
+++ stream/tvi_v4l.c (working copy)
@@ -106,6 +106,8 @@
int audio_buffer_size;
int aud_skew_cnt;
+ unsigned char* blank_frame;
+ int blank_frame_size;
unsigned char *audio_ringbuffer;
long long *audio_skew_buffer;
volatile int audio_head;
@@ -706,6 +708,11 @@
if (priv->audio_skew_buffer)
free(priv->audio_skew_buffer);
}
+ if(priv->blank_frame){
+ free(priv->blank_frame);
+ priv->blank_frame=NULL;
+ priv->blank_frame_size=0;
+ }
return(1);
}
@@ -1381,6 +1388,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 +1411,23 @@
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){
+ if (priv->blank_frame_size!=priv->bytesperline * priv->height){
+ if(priv->blank_frame)
+ free(priv->blank_frame);
+ priv->blank_frame=(unsigned char*)malloc(priv->bytesperline * priv->height);
+ priv->blank_frame_size=priv->bytesperline * priv->height;
+ fill_blank_frame(priv->blank_frame,priv->bytesperline * priv->height,priv->format);
+ }
+ memcpy(dest,priv->blank_frame,priv->bytesperline * priv->height);
+ 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);
Index: DOCS/man/en/mplayer.1
===================================================================
--- DOCS/man/en/mplayer.1 (revision 23382)
+++ DOCS/man/en/mplayer.1 (working copy)
@@ -1718,6 +1718,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
Index: cfg-common.h
===================================================================
--- cfg-common.h (revision 23382)
+++ cfg-common.h (working copy)
@@ -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
More information about the MPlayer-dev-eng
mailing list