struct pvr2_v4l2_dev { struct video_device devbase; /* MUST be first! */ struct pvr2_v4l2 *v4lp; struct pvr2_context_stream *stream; /* Information about this device: */ enum pvr2_config config; /* Expected stream format */ int v4l_type; /* V4L defined type for this device node */ enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
};
struct pvr2_v4l2_fh { struct v4l2_fh fh; struct pvr2_channel channel; struct pvr2_v4l2_dev *pdi; struct pvr2_ioread *rhp; struct file *file;
wait_queue_head_t wait_data; int fw_mode_flag; /* Map contiguous ordinal value to input id */ unsignedchar *input_map; unsignedint input_cnt;
};
struct pvr2_v4l2 { struct pvr2_channel channel;
/* streams - Note that these must be separately, individually, *allocatedpointers.Thisisbecausethev4lcoreisgoingto
* manage their deletion - separately, individually... */ struct pvr2_v4l2_dev *dev_video; struct pvr2_v4l2_dev *dev_radio;
};
staticint video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor"); staticint radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
module_param_array(radio_nr, int, NULL, 0444);
MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor"); staticint vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
module_param_array(vbi_nr, int, NULL, 0444);
MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
/* Don't bother with audioset, since this driver currently alwaysswitchestheaudiowheneverthevideois
switched. */
/* Handling std is a tougher problem. It doesn't make senseincaseswhereadevicemightbemulti-standard. Wecouldjustcopyoutthecurrentvalueforthe standard,butitcanchangeovertime.Fornowjust
leave it zero. */
*vi = tmp; return0;
}
if (inp >= fh->input_cnt) return -EINVAL;
ret = pvr2_ctrl_set_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
fh->input_map[inp]);
pvr2_hdw_commit_ctl(hdw); return ret;
}
staticint pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
{ /* pkt: FIXME: We are returning one "fake" input here whichcouldverywellbecalled"whatever_we_like". Thisisforappsthatwanttoseeanaudioinput justtofeelcomfortable,aswellastotestif itcandostereoorsth.Thereisactuallynoguarantee thattheactualaudioinputcannotchangebehindtheapp's back,butmostapplicationsshouldnotmindthateither.
Hopefully,mplayerpeoplewillworkwithusonthis(this wholemessistosupportmplayerpvr://), or Hans will come upwithamorestandardwaytosay"wehaveinputsbutwe don'twantyoutochangethemindependentofvideo"which willsortthismess.
*/
ret = pvr2_hdw_get_tuner_status(hdw, &vt); if (ret != 0) return ret;
ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
ret = pvr2_ctrl_get_value(ctrlp, &cur_input); if (ret != 0) return ret; if (vf->type == V4L2_TUNER_RADIO) { if (cur_input != PVR2_CVAL_INPUT_RADIO)
pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO);
} else { if (cur_input == PVR2_CVAL_INPUT_RADIO)
pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV);
}
fv = vf->frequency; if (vt.capability & V4L2_TUNER_CAP_LOW)
fv = (fv * 125) / 2; else
fv = fv * 62500;
ret = pvr2_ctrl_set_value(
pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
pvr2_hdw_commit_ctl(hdw); return ret;
}
staticint pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
{ struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; int val = 0; int cur_input; struct v4l2_tuner vt; int ret;
ret = pvr2_hdw_get_tuner_status(hdw, &vt); if (ret != 0) return ret;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY),
&val); if (ret != 0) return ret;
pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
&cur_input); if (cur_input == PVR2_CVAL_INPUT_RADIO)
vf->type = V4L2_TUNER_RADIO; else
vf->type = V4L2_TUNER_ANALOG_TV; if (vt.capability & V4L2_TUNER_CAP_LOW)
val = (val * 2) / 125; else
val /= 62500;
vf->frequency = val; return0;
}
staticint pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
{ /* Only one format is supported: MPEG. */ if (fd->index) return -EINVAL;
if (!fh->pdi->stream) { /* No stream defined for this node. This means thatwe'renotcurrentlyallowedtostreamfrom
this node. */ return -EPERM;
}
ret = pvr2_hdw_set_stream_type(hdw, pdi->config); if (ret < 0) return ret; return pvr2_hdw_set_streaming(hdw, !0);
}
if (!fh->pdi->stream) { /* No stream defined for this node. This means thatwe'renotcurrentlyallowedtostreamfrom
this node. */ return -EPERM;
} return pvr2_hdw_set_streaming(hdw, 0);
}
ret = 0; for (idx = 0; idx < ctls->count; idx++) {
ctrl = ctls->controls + idx;
cptr = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id); if (cptr) { if (ctls->which == V4L2_CTRL_WHICH_DEF_VAL)
pvr2_ctrl_get_def(cptr, &val); else
ret = pvr2_ctrl_get_value(cptr, &val);
} else
ret = -EINVAL;
if (ret) {
ctls->error_idx = idx; return ret;
} /* Ensure that if read as a 64 bit value, the user
will still get a hopefully sane value */
ctrl->value64 = 0;
ctrl->value = val;
} return0;
}
/* For the moment just validate that the requested control
actually exists. */ for (idx = 0; idx < ctls->count; idx++) {
ctrl = ctls->controls + idx;
pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id); if (!pctl) {
ctls->error_idx = idx; return -EINVAL;
}
} return0;
}
staticint pvr2_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f)
{ struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; struct v4l2_cropcap cap = { .type = type }; int ret;
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL;
ret = pvr2_hdw_get_cropcap(hdw, &cap); if (!ret)
*f = cap.pixelaspect; return ret;
}
staticint pvr2_g_selection(struct file *file, void *priv, struct v4l2_selection *sel)
{ struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; struct v4l2_cropcap cap; int val = 0; int ret;
if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL;
cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
switch (sel->target) { case V4L2_SEL_TGT_CROP:
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val); if (ret != 0) return -EINVAL;
sel->r.left = val;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val); if (ret != 0) return -EINVAL;
sel->r.top = val;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val); if (ret != 0) return -EINVAL;
sel->r.width = val;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val); if (ret != 0) return -EINVAL;
sel->r.height = val; break; case V4L2_SEL_TGT_CROP_DEFAULT:
ret = pvr2_hdw_get_cropcap(hdw, &cap);
sel->r = cap.defrect; break; case V4L2_SEL_TGT_CROP_BOUNDS:
ret = pvr2_hdw_get_cropcap(hdw, &cap);
sel->r = cap.bounds; break; default: return -EINVAL;
} return ret;
}
staticint pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
{ int ret; struct pvr2_stream *sp; struct pvr2_hdw *hdw; if (fh->rhp) return0;
if (!fh->pdi->stream) { /* No stream defined for this node. This means that we're
not currently allowed to stream from this node. */ return -EPERM;
}
/* First read() attempt. Try to claim the stream and start
it... */ if ((ret = pvr2_channel_claim_stream(&fh->channel,
fh->pdi->stream)) != 0) { /* Someone else must already have it */ return ret;
}
fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream); if (!fh->rhp) {
pvr2_channel_claim_stream(&fh->channel,NULL); return -ENOMEM;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.9Bemerkung:
(vorverarbeitet am 2026-10-02)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.