📄 pvrusb2-hdw.c
字号:
{ int ret; struct v4l2_ext_controls cs; struct v4l2_ext_control c1; memset(&cs,0,sizeof(cs)); memset(&c1,0,sizeof(c1)); cs.controls = &c1; cs.count = 1; c1.id = cptr->info->v4l_id; ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs, VIDIOC_G_EXT_CTRLS); if (ret) return ret; *vp = c1.value; return 0;}static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v){ int ret; struct v4l2_ext_controls cs; struct v4l2_ext_control c1; memset(&cs,0,sizeof(cs)); memset(&c1,0,sizeof(c1)); cs.controls = &c1; cs.count = 1; c1.id = cptr->info->v4l_id; c1.value = v; ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs, VIDIOC_S_EXT_CTRLS); if (ret) return ret; cptr->hdw->enc_stale = !0; return 0;}static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr){ struct v4l2_queryctrl qctrl; struct pvr2_ctl_info *info; qctrl.id = cptr->info->v4l_id; cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); /* Strip out the const so we can adjust a function pointer. It's OK to do this here because we know this is a dynamically created control, so the underlying storage for the info pointer is (a) private to us, and (b) not in read-only storage. Either we do this or we significantly complicate the underlying control implementation. */ info = (struct pvr2_ctl_info *)(cptr->info); if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { if (info->set_value) { info->set_value = NULL; } } else { if (!(info->set_value)) { info->set_value = ctrl_cx2341x_set; } } return qctrl.flags;}static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp){ *vp = cptr->hdw->flag_streaming_enabled; return 0;}static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp){ int result = pvr2_hdw_is_hsm(cptr->hdw); *vp = PVR2_CVAL_HSM_FULL; if (result < 0) *vp = PVR2_CVAL_HSM_FAIL; if (result) *vp = PVR2_CVAL_HSM_HIGH; return 0;}static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp){ *vp = cptr->hdw->std_mask_avail; return 0;}static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v){ struct pvr2_hdw *hdw = cptr->hdw; v4l2_std_id ns; ns = hdw->std_mask_avail; ns = (ns & ~m) | (v & m); if (ns == hdw->std_mask_avail) return 0; hdw->std_mask_avail = ns; pvr2_hdw_internal_set_std_avail(hdw); pvr2_hdw_internal_find_stdenum(hdw); return 0;}static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val, char *bufPtr,unsigned int bufSize, unsigned int *len){ *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val); return 0;}static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr, const char *bufPtr,unsigned int bufSize, int *mskp,int *valp){ int ret; v4l2_std_id id; ret = pvr2_std_str_to_id(&id,bufPtr,bufSize); if (ret < 0) return ret; if (mskp) *mskp = id; if (valp) *valp = id; return 0;}static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp){ *vp = cptr->hdw->std_mask_cur; return 0;}static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v){ struct pvr2_hdw *hdw = cptr->hdw; v4l2_std_id ns; ns = hdw->std_mask_cur; ns = (ns & ~m) | (v & m); if (ns == hdw->std_mask_cur) return 0; hdw->std_mask_cur = ns; hdw->std_dirty = !0; pvr2_hdw_internal_find_stdenum(hdw); return 0;}static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr){ return cptr->hdw->std_dirty != 0;}static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr){ cptr->hdw->std_dirty = 0;}static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp){ struct pvr2_hdw *hdw = cptr->hdw; pvr2_i2c_core_status_poll(hdw); *vp = hdw->tuner_signal_info.signal; return 0;}static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp){ int val = 0; unsigned int subchan; struct pvr2_hdw *hdw = cptr->hdw; pvr2_i2c_core_status_poll(hdw); subchan = hdw->tuner_signal_info.rxsubchans; if (subchan & V4L2_TUNER_SUB_MONO) { val |= (1 << V4L2_TUNER_MODE_MONO); } if (subchan & V4L2_TUNER_SUB_STEREO) { val |= (1 << V4L2_TUNER_MODE_STEREO); } if (subchan & V4L2_TUNER_SUB_LANG1) { val |= (1 << V4L2_TUNER_MODE_LANG1); } if (subchan & V4L2_TUNER_SUB_LANG2) { val |= (1 << V4L2_TUNER_MODE_LANG2); } *vp = val; return 0;}static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp){ *vp = cptr->hdw->subsys_enabled_mask; return 0;}static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v){ pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v); return 0;}static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp){ *vp = cptr->hdw->subsys_stream_mask; return 0;}static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v){ pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v); return 0;}static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v){ struct pvr2_hdw *hdw = cptr->hdw; if (v < 0) return -EINVAL; if (v > hdw->std_enum_cnt) return -EINVAL; hdw->std_enum_cur = v; if (!v) return 0; v--; if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0; hdw->std_mask_cur = hdw->std_defs[v].id; hdw->std_dirty = !0; return 0;}static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp){ *vp = cptr->hdw->std_enum_cur; return 0;}static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr){ return cptr->hdw->std_dirty != 0;}static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr){ cptr->hdw->std_dirty = 0;}#define DEFINT(vmin,vmax) \ .type = pvr2_ctl_int, \ .def.type_int.min_value = vmin, \ .def.type_int.max_value = vmax#define DEFENUM(tab) \ .type = pvr2_ctl_enum, \ .def.type_enum.count = ARRAY_SIZE(tab), \ .def.type_enum.value_names = tab#define DEFBOOL \ .type = pvr2_ctl_bool#define DEFMASK(msk,tab) \ .type = pvr2_ctl_bitmask, \ .def.type_bitmask.valid_bits = msk, \ .def.type_bitmask.bit_names = tab#define DEFREF(vname) \ .set_value = ctrl_set_##vname, \ .get_value = ctrl_get_##vname, \ .is_dirty = ctrl_isdirty_##vname, \ .clear_dirty = ctrl_cleardirty_##vname#define VCREATE_FUNCS(vname) \static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \{*vp = cptr->hdw->vname##_val; return 0;} \static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \{return cptr->hdw->vname##_dirty != 0;} \static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \{cptr->hdw->vname##_dirty = 0;}VCREATE_FUNCS(brightness)VCREATE_FUNCS(contrast)VCREATE_FUNCS(saturation)VCREATE_FUNCS(hue)VCREATE_FUNCS(volume)VCREATE_FUNCS(balance)VCREATE_FUNCS(bass)VCREATE_FUNCS(treble)VCREATE_FUNCS(mute)VCREATE_FUNCS(audiomode)VCREATE_FUNCS(res_hor)VCREATE_FUNCS(res_ver)VCREATE_FUNCS(srate)/* Table definition of all controls which can be manipulated */static const struct pvr2_ctl_info control_defs[] = { { .v4l_id = V4L2_CID_BRIGHTNESS, .desc = "Brightness", .name = "brightness", .default_value = 128, DEFREF(brightness), DEFINT(0,255), },{ .v4l_id = V4L2_CID_CONTRAST, .desc = "Contrast", .name = "contrast", .default_value = 68, DEFREF(contrast), DEFINT(0,127), },{ .v4l_id = V4L2_CID_SATURATION, .desc = "Saturation", .name = "saturation", .default_value = 64, DEFREF(saturation), DEFINT(0,127), },{ .v4l_id = V4L2_CID_HUE, .desc = "Hue", .name = "hue", .default_value = 0, DEFREF(hue), DEFINT(-128,127), },{ .v4l_id = V4L2_CID_AUDIO_VOLUME, .desc = "Volume", .name = "volume", .default_value = 62000, DEFREF(volume), DEFINT(0,65535), },{ .v4l_id = V4L2_CID_AUDIO_BALANCE, .desc = "Balance", .name = "balance", .default_value = 0, DEFREF(balance), DEFINT(-32768,32767), },{ .v4l_id = V4L2_CID_AUDIO_BASS, .desc = "Bass", .name = "bass", .default_value = 0, DEFREF(bass), DEFINT(-32768,32767), },{ .v4l_id = V4L2_CID_AUDIO_TREBLE, .desc = "Treble", .name = "treble", .default_value = 0, DEFREF(treble), DEFINT(-32768,32767), },{ .v4l_id = V4L2_CID_AUDIO_MUTE, .desc = "Mute", .name = "mute", .default_value = 0, DEFREF(mute), DEFBOOL, },{ .desc = "Video Source", .name = "input", .internal_id = PVR2_CID_INPUT, .default_value = PVR2_CVAL_INPUT_TV, DEFREF(input), DEFENUM(control_values_input), },{ .desc = "Audio Mode", .name = "audio_mode", .internal_id = PVR2_CID_AUDIOMODE, .default_value = V4L2_TUNER_MODE_STEREO, DEFREF(audiomode), DEFENUM(control_values_audiomode), },{ .desc = "Horizontal capture resolution", .name = "resolution_hor", .internal_id = PVR2_CID_HRES, .default_value = 720, DEFREF(res_hor), DEFINT(19,720), },{ .desc = "Vertical capture resolution", .name = "resolution_ver", .internal_id = PVR2_CID_VRES, .default_value = 480, DEFREF(res_ver), DEFINT(17,576), /* Hook in check for video standard and adjust maximum depending on the standard. */ .get_max_value = ctrl_vres_max_get, .get_min_value = ctrl_vres_min_get, },{ .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, .desc = "Audio Sampling Frequency", .name = "srate", DEFREF(srate), DEFENUM(control_values_srate), },{ .desc = "Tuner Frequency (Hz)", .name = "frequency", .internal_id = PVR2_CID_FREQUENCY, .default_value = 0, .set_value = ctrl_freq_set, .get_value = ctrl_freq_get, .is_dirty = ctrl_freq_is_dirty, .clear_dirty = ctrl_freq_clear_dirty, DEFINT(0,0), /* Hook in check for input value (tv/radio) and adjust max/min values accordingly */ .get_max_value = ctrl_freq_max_get, .get_min_value = ctrl_freq_min_get, },{ .desc = "Channel", .name = "channel", .set_value = ctrl_channel_set, .get_value = ctrl_channel_get, DEFINT(0,FREQTABLE_SIZE), },{ .desc = "Channel Program Frequency", .name = "freq_table_value", .set_value = ctrl_channelfreq_set, .get_value = ctrl_channelfreq_get, DEFINT(0,0), /* Hook in check for input value (tv/radio) and adjust max/min values accordingly */ .get_max_value = ctrl_freq_max_get, .get_min_value = ctrl_freq_min_get, },{ .desc = "Channel Program ID", .name = "freq_table_channel", .set_value = ctrl_channelprog_set, .get_value = ctrl_channelprog_get, DEFINT(0,FREQTABLE_SIZE), },{ .desc = "Streaming Enabled", .name = "streaming_enabled", .get_value = ctrl_streamingenabled_get, DEFBOOL, },{ .desc = "USB Speed", .name = "usb_speed", .get_value = ctrl_hsm_get, DEFENUM(control_values_hsm), },{ .desc = "Signal Present", .name = "signal_present", .get_value = ctrl_signal_get, DEFINT(0,65535), },{ .desc = "Audio Modes Present", .name = "audio_modes_present", .get_value = ctrl_audio_modes_present_get, /* For this type we "borrow" the V4L2_TUNER_MODE enum from v4l. Nothing outside of this module cares about this, but I reuse it in order to also reuse the control_values_audiomode string table. */ DEFMASK(((1 << V4L2_TUNER_MODE_MONO)| (1 << V4L2_TUNER_MODE_STEREO)| (1 << V4L2_TUNER_MODE_LANG1)| (1 << V4L2_TUNER_MODE_LANG2)), control_values_audiomode), },{ .desc = "Video Standards Available Mask", .name = "video_standard_mask_available", .internal_id = PVR2_CID_STDAVAIL, .skip_init = !0, .get_value = ctrl_stdavail_get, .set_value = ctrl_stdavail_set, .val_to_sym = ctrl_std_val_to_sym, .sym_to_val = ctrl_std_sym_to_val, .type = pvr2_ctl_bitmask, },{ .desc = "Video Standards In Use Mask", .name = "video_standard_mask_active", .internal_id = PVR2_CID_STDCUR, .skip_init = !0, .get_value = ctrl_stdcur_get, .set_value = ctrl_stdcur_set, .is_dirty = ctrl_stdcur_is_dirty, .clear_dirty = ctrl_stdcur_clear_dirty, .val_to_sym = ctrl_std_val_to_sym, .sym_to_val = ctrl_std_sym_to_val, .type = pvr2_ctl_bitmask, },{ .desc = "Subsystem enabled mask", .name = "debug_subsys_mask", .skip_init = !0, .get_value = ctrl_subsys_get, .set_value = ctrl_subsys_set, DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), },{ .desc = "Subsystem stream mask", .name = "debug_subsys_stream_mask", .skip_init = !0, .get_value = ctrl_subsys_stream_get, .set_value = ctrl_subsys_stream_set, DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -