📄 tvi_v4l.c
字号:
{ mp_msg(MSGT_TV, MSGL_DBG2, "\ndebug: control(priv=%p, cmd=%d, arg=%p)\n", priv, cmd, arg); switch(cmd) { /* ========== GENERIC controls =========== */ case TVI_CONTROL_IS_VIDEO: { if (priv->capability.type & VID_TYPE_CAPTURE) return(TVI_CONTROL_TRUE); return(TVI_CONTROL_FALSE); } case TVI_CONTROL_IS_AUDIO: if (priv->tv_param->force_audio) return(TVI_CONTROL_TRUE); if (priv->channels[priv->act_channel].flags & VIDEO_VC_AUDIO) { return(TVI_CONTROL_TRUE); } return(TVI_CONTROL_FALSE); case TVI_CONTROL_IS_TUNER: {// if (priv->capability.type & VID_TYPE_TUNER) if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER) return(TVI_CONTROL_TRUE); return(TVI_CONTROL_FALSE); } /* ========== VIDEO controls =========== */ case TVI_CONTROL_VID_GET_FORMAT: { int output_fmt = -1; output_fmt = priv->format; if ( priv->tv_param->mjpeg ) { mp_msg(MSGT_TV, MSGL_INFO, " MJP: setting sh_video->format to mjpg\n"); output_fmt = 0x47504a4d; output_fmt = 0x67706a6d; *(int *)arg = output_fmt; mp_msg(MSGT_TV, MSGL_V, "Output format: %s\n", "mjpg"); } else { *(int *)arg = output_fmt; mp_msg(MSGT_TV, MSGL_V, "Output format: %s\n", vo_format_name(output_fmt)); } return(TVI_CONTROL_TRUE); } case TVI_CONTROL_VID_SET_FORMAT: priv->format = *(int *)arg; // !HACK! v4l uses BGR format instead of RGB // and we have to correct this. Fortunately, // tv.c reads later the format back so we // can persuade it to use what we want. if (IMGFMT_IS_RGB(priv->format)) { priv->format &= ~IMGFMT_RGB_MASK; priv->format |= IMGFMT_BGR; } return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_PLANES: *(int *)arg = 1; /* FIXME, also not needed at this time */ return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_BITS: *(int *)arg = palette2depth(format2palette(priv->format)); return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_WIDTH: *(int *)arg = priv->width; return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_CHK_WIDTH: { int req_width = *(int *)arg; mp_msg(MSGT_TV, MSGL_V, "Requested width: %d\n", req_width); if ((req_width >= priv->capability.minwidth) && (req_width <= priv->capability.maxwidth)) return(TVI_CONTROL_TRUE); return(TVI_CONTROL_FALSE); } case TVI_CONTROL_VID_SET_WIDTH: priv->width = *(int *)arg; return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_HEIGHT: *(int *)arg = priv->height; return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_CHK_HEIGHT: { int req_height = *(int *)arg; mp_msg(MSGT_TV, MSGL_V, "Requested height: %d\n", req_height); if ((req_height >= priv->capability.minheight) && (req_height <= priv->capability.maxheight)) return(TVI_CONTROL_TRUE); return(TVI_CONTROL_FALSE); } case TVI_CONTROL_VID_SET_HEIGHT: priv->height = *(int *)arg; return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_GET_PICTURE: if (ioctl(priv->video_fd, VIDIOCGPICT, &priv->picture) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_SET_PICTURE: if (ioctl(priv->video_fd, VIDIOCSPICT, &priv->picture) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl set picture failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } return(TVI_CONTROL_TRUE); case TVI_CONTROL_VID_SET_BRIGHTNESS: priv->picture.brightness = (327*(*(int *)arg+100)) + 68; return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); case TVI_CONTROL_VID_SET_HUE: priv->picture.hue = (327*(*(int *)arg+100)) + 68; return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); case TVI_CONTROL_VID_SET_SATURATION: priv->picture.colour = (327*(*(int *)arg+100)) + 68; return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); case TVI_CONTROL_VID_SET_CONTRAST: priv->picture.contrast = (327*(*(int *)arg+100)) + 68; return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); case TVI_CONTROL_VID_GET_BRIGHTNESS: if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0; *(int*)arg = ((int)priv->picture.brightness-68)/327-100; return 1; case TVI_CONTROL_VID_GET_HUE: if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0; *(int*)arg = ((int)priv->picture.hue-68)/327-100; return 1; case TVI_CONTROL_VID_GET_SATURATION: if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0; *(int*)arg = ((int)priv->picture.colour-68)/327-100; return 1; case TVI_CONTROL_VID_GET_CONTRAST: if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0; *(int*)arg = ((int)priv->picture.contrast-68)/327-100; return 1; case TVI_CONTROL_VID_GET_FPS: *(float *)arg=priv->fps; return(TVI_CONTROL_TRUE); /* ========== TUNER controls =========== */ case TVI_CONTROL_TUN_GET_FREQ: { unsigned long freq; if (ioctl(priv->video_fd, VIDIOCGFREQ, &freq) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl get freq failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } /* tuner uses khz not mhz ! */// if (priv->tuner.flags & VIDEO_TUNER_LOW)// freq /= 1000; *(unsigned long *)arg = freq; return(TVI_CONTROL_TRUE); } case TVI_CONTROL_TUN_SET_FREQ: { /* argument is in MHz ! */ unsigned long freq = *(unsigned long *)arg; if (priv->capability.audios) { priv->audio[priv->audio_id].flags |= VIDEO_AUDIO_MUTE; ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]); } mp_msg(MSGT_TV, MSGL_V, "requested frequency: %.3f\n", (float)freq/16); /* tuner uses khz not mhz ! */// if (priv->tuner.flags & VIDEO_TUNER_LOW)// freq *= 1000;// mp_msg(MSGT_TV, MSGL_V, " requesting from driver: freq=%.3f\n", (float)freq/16); if (ioctl(priv->video_fd, VIDIOCSFREQ, &freq) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl set freq failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } usleep(100000); // wait to suppress noise during switching if (priv->capability.audios) { priv->audio[priv->audio_id].flags &= ~VIDEO_AUDIO_MUTE; ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]); } return(TVI_CONTROL_TRUE); } case TVI_CONTROL_TUN_GET_TUNER: { if (ioctl(priv->video_fd, VIDIOCGTUNER, &priv->tuner) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl get tuner failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } mp_msg(MSGT_TV, MSGL_V, "Tuner (%s) range: %lu -> %lu\n", priv->tuner.name, priv->tuner.rangelow, priv->tuner.rangehigh); return(TVI_CONTROL_TRUE); } case TVI_CONTROL_TUN_SET_TUNER: { if (ioctl(priv->video_fd, VIDIOCSTUNER, &priv->tuner) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl set tuner failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } return(TVI_CONTROL_TRUE); } case TVI_CONTROL_TUN_SET_NORM: { int req_mode = *(int *)arg; if ((req_mode != TV_NORM_PAL) && (req_mode != TV_NORM_NTSC) && (req_mode != TV_NORM_SECAM) && (req_mode != TV_NORM_PALNC) && (req_mode != TV_NORM_PALM) && (req_mode != TV_NORM_PALN) && (req_mode != TV_NORM_NTSCJP)) { mp_msg(MSGT_TV, MSGL_ERR, "Unknown norm!\n"); return(TVI_CONTROL_FALSE); } if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER) { int prev_mode; control(priv, TVI_CONTROL_TUN_GET_TUNER, 0); if (((req_mode == TV_NORM_PAL || req_mode == TV_NORM_PALNC || req_mode == TV_NORM_PALN) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) || ((req_mode == TV_NORM_NTSC || req_mode == TV_NORM_NTSCJP || req_mode == TV_NORM_PALM) && !(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); } prev_mode = priv->tuner.mode; switch(req_mode) { case TV_NORM_PAL: case TV_NORM_PALNC: case TV_NORM_PALN: priv->tuner.mode = VIDEO_MODE_PAL; break; case TV_NORM_NTSC: case TV_NORM_NTSCJP: case TV_NORM_PALM: 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) { // norm setting failed, but maybe it's only because it's fixed if (priv->tuner.mode != prev_mode) return(TVI_CONTROL_FALSE); // no it really failed } } switch(req_mode) { case TV_NORM_PAL: priv->channels[priv->act_channel].norm = VIDEO_MODE_PAL; break; case TV_NORM_NTSC: priv->channels[priv->act_channel].norm = VIDEO_MODE_NTSC; break; case TV_NORM_SECAM: priv->channels[priv->act_channel].norm = VIDEO_MODE_SECAM; break; case TV_NORM_PALNC: priv->channels[priv->act_channel].norm = 3; break; case TV_NORM_PALM: priv->channels[priv->act_channel].norm = 4; break; case TV_NORM_PALN: priv->channels[priv->act_channel].norm = 5; break; case TV_NORM_NTSCJP: priv->channels[priv->act_channel].norm = 6; break; } 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); } if (ioctl(priv->video_fd, VIDIOCGCAP, &priv->capability) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl get capabilites failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } if(req_mode == TV_NORM_PAL || req_mode == TV_NORM_SECAM || req_mode == TV_NORM_PALN || req_mode == TV_NORM_PALNC) { priv->fps = PAL_FPS; } if(req_mode == TV_NORM_NTSC || req_mode == TV_NORM_NTSCJP || req_mode == TV_NORM_PALM) { priv->fps = NTSC_FPS; } if(priv->height > priv->capability.maxheight) { priv->height = priv->capability.maxheight; } if(priv->width > priv->capability.maxwidth) { priv->width = priv->capability.maxwidth; } return(TVI_CONTROL_TRUE); } case TVI_CONTROL_TUN_GET_NORM: { *(int *)arg = priv->tuner.mode; return(TVI_CONTROL_TRUE); } case TVI_CONTROL_TUN_GET_SIGNAL: { if (ioctl(priv->video_fd, VIDIOCGTUNER, &priv->tuner) == -1) { mp_msg(MSGT_TV, MSGL_ERR, "ioctl get tuner failed: %s\n", strerror(errno)); return(TVI_CONTROL_FALSE); } *(int*)arg=100*(priv->tuner.signal>>8)/255; return(TVI_CONTROL_TRUE); } /* ========== AUDIO controls =========== */ case TVI_CONTROL_AUD_GET_FORMAT: { *(int *)arg = AF_FORMAT_S16_LE; return(TVI_CONTROL_TRUE); } case TVI_CONTROL_AUD_GET_CHANNELS: { *(int *)arg = priv->audio_in.channels; return(TVI_CONTROL_TRUE); } case TVI_CONTROL_AUD_GET_SAMPLERATE: { *(int *)arg = priv->audio_in.samplerate; return(TVI_CONTROL_TRUE); } case TVI_CONTROL_AUD_GET_SAMPLESIZE: { *(int *)arg = priv->audio_in.bytes_per_sample; return(TVI_CONTROL_TRUE); } case TVI_CONTROL_AUD_SET_SAMPLERATE: { if (audio_in_set_samplerate(&priv->audio_in, *(int *)arg) < 0) return TVI_CONTROL_FALSE; setup_audio_buffer_sizes(priv); return(TVI_CONTROL_TRUE); } /* ========== SPECIFIC controls =========== */ case TVI_CONTROL_SPC_GET_INPUT: { int req_chan = *(int *)arg; int i; for (i = 0; i < priv->capability.channels; i++) { if (priv->channels[i].channel == req_chan) break; } priv->act_channel = i; if (ioctl(priv->video_fd, VIDIOCGCHAN, &priv->channels[i]) == -1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -