📄 v4l2_ctrl.cpp
字号:
if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG)
mpeg_ctrls.push_back(ctrl);
else
user_ctrls.push_back(ctrl);
}
for (unsigned i = 0; i < user_ctrls.size(); i++) {
struct v4l2_control ctrl;
ctrl.id = user_ctrls[i].id;
ctrl.value = user_ctrls[i].value;
if (ioctl(fd, VIDIOC_S_CTRL, &ctrl)) {
fprintf(stderr, "%s: %s\n",
ctrl_id2str[ctrl.id].c_str(),
strerror(errno));
}
}
if (mpeg_ctrls.size()) {
ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ctrls.count = mpeg_ctrls.size();
ctrls.controls = &mpeg_ctrls[0];
if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
if (ctrls.error_idx >= ctrls.count) {
fprintf(stderr, "Error setting MPEG controls: %s\n",
strerror(errno));
}
else {
fprintf(stderr, "%s: %s\n",
ctrl_id2str[mpeg_ctrls[ctrls.error_idx].id].c_str(),
strerror(errno));
}
}
}
}
/* informational opts */
if (options[OptGetDriverInfo]) {
if (doioctl(fd, VIDIOC_QUERYCAP, &vcap, "VIDIOC_QUERYCAP") == 0) {
printf("Driver info:\n");
printf("\tDriver name : %s\n", vcap.driver);
printf("\tCard type : %s\n", vcap.card);
printf("\tBus info : %s\n", vcap.bus_info);
printf("\tDriver version: %d\n", vcap.version);
printf("\tCapabilities : 0x%08X\n", vcap.capabilities);
printf("%s", cap2s(vcap.capabilities).c_str());
}
}
if (options[OptGetVideoFormat]) {
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (doioctl(fd, VIDIOC_G_FMT, &vfmt, "VIDIOC_G_FMT") == 0)
if (printfmt(vfmt) != 0)
fprintf(stderr, "error printing result\n");
}
if (options[OptListInputs]) {
vin.index = 0;
printf("ioctl: VIDIOC_ENUMINPUT\n");
while (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0) {
if (vin.index)
printf("\n");
printf("\tInput : %d\n", vin.index);
printf("\tName : %s\n", vin.name);
printf("\tType : 0x%08X\n", vin.type);
printf("\tAudioset: 0x%08X\n", vin.audioset);
printf("\tTuner : 0x%08X\n", vin.tuner);
printf("\tStandard: 0x%016llX ( ", (unsigned long long)vin.std);
if (vin.std & 0x000FFF)
printf("PAL "); // hack
if (vin.std & 0x00F000)
printf("NTSC "); // hack
if (vin.std & 0x7F0000)
printf("SECAM "); // hack
printf(")\n");
printf("\tStatus : %d\n", vin.status);
vin.index++;
}
}
if (options[OptSetInput]) {
if (doioctl(fd, VIDIOC_S_INPUT, &input, "VIDIOC_S_INPUT") == 0) {
printf("Video input set to %d", input);
vin.index = input;
if (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0)
printf(" (%s)", vin.name);
printf("\n");
}
}
if (options[OptGetInput]) {
if (doioctl(fd, VIDIOC_G_INPUT, &input, "VIDIOC_G_INPUT") == 0) {
printf("Video input : %d", input);
vin.index = input;
if (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0)
printf(" (%s)", vin.name);
printf("\n");
}
}
if (options[OptListOutputs]) {
vout.index = 0;
printf("ioctl: VIDIOC_ENUMOUTPUT\n");
while (ioctl(fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) {
if (vout.index)
printf("\n");
printf("\tOutput : %d\n", vout.index);
printf("\tName : %s\n", vout.name);
printf("\tType : 0x%08X\n", vout.type);
printf("\tAudioset: 0x%08X\n", vout.audioset);
printf("\tStandard: 0x%016llX ( ", (unsigned long long)vout.std);
if (vout.std & 0x000FFF)
printf("PAL "); // hack
if (vout.std & 0x00F000)
printf("NTSC "); // hack
if (vout.std & 0x7F0000)
printf("SECAM "); // hack
printf(")\n");
vout.index++;
}
}
if (options[OptSetOutput]) {
if (doioctl(fd, VIDIOC_S_OUTPUT, &output, "VIDIOC_S_OUTPUT") == 0)
printf("Output set to %d\n", output);
}
if (options[OptGetOutput]) {
if (doioctl(fd, VIDIOC_G_OUTPUT, &output, "VIDIOC_G_OUTPUT") == 0) {
printf("Video output: %d", output);
vout.index = output;
if (ioctl(fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) {
printf(" (%s)", vout.name);
}
printf("\n");
}
}
if (options[OptListAudioInputs]) {
struct v4l2_audio vaudio; /* list audio inputs */
vaudio.index = 0;
printf("ioctl: VIDIOC_ENUMAUDIO\n");
while (ioctl(fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0) {
if (vaudio.index)
printf("\n");
printf("\tInput : %d\n", vaudio.index);
printf("\tName : %s\n", vaudio.name);
vaudio.index++;
}
}
if (options[OptSetAudioInput]) {
if (doioctl(fd, VIDIOC_S_AUDIO, &vaudio, "VIDIOC_S_AUDIO") == 0)
printf("Audio input set to %d\n", vaudio.index);
}
if (options[OptGetAudioInput]) {
if (doioctl(fd, VIDIOC_G_AUDIO, &vaudio, "VIDIOC_G_AUDIO") == 0)
printf("Audio input : %d (%s)\n", vaudio.index, vaudio.name);
}
if (options[OptSetAudioOutput]) {
if (doioctl(fd, VIDIOC_S_AUDOUT, &vaudout, "VIDIOC_S_AUDOUT") == 0)
printf("Audio output set to %d\n", vaudout.index);
}
if (options[OptGetAudioOutput]) {
if (doioctl(fd, VIDIOC_G_AUDOUT, &vaudout, "VIDIOC_G_AUDOUT") == 0)
printf("Audio output: %d (%s)\n", vaudout.index, vaudout.name);
}
if (options[OptGetFreq]) {
double fac = 16;
if (doioctl(fd, VIDIOC_G_TUNER, &tuner, "VIDIOC_G_TUNER") == 0) {
fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16;
}
vf.tuner = 0;
if (doioctl(fd, VIDIOC_G_FREQUENCY, &vf, "VIDIOC_G_FREQUENCY") == 0)
printf("Frequency: %d (%f MHz)\n", vf.frequency,
vf.frequency / fac);
}
if (option_list_stds) {
printf("ioctl: VIDIOC_ENUMSTD\n");
vs.index = 0;
while (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) {
if (vs.index)
printf("\n");
printf("\tindex : %d\n", vs.index);
printf("\tID : 0x%016llX\n", (unsigned long long)vs.id);
printf("\tName : %s\n", vs.name);
printf("\tFrame period: %d/%d\n",
vs.frameperiod.numerator,
vs.frameperiod.denominator);
printf("\tFrame lines : %d\n", vs.framelines);
vs.index++;
}
}
if (options[OptGetStandard]) {
if (doioctl(fd, VIDIOC_G_STD, &std, "VIDIOC_G_STD") == 0)
printf("Video standard = 0x%08llx\n", (unsigned long long)std);
}
if (options[OptListCtrlsMenus]) {
list_controls(fd, 1);
}
if (options[OptGetCtrl] && !get_ctrls.empty()) {
struct v4l2_ext_controls ctrls = { 0 };
mpeg_ctrls.clear();
user_ctrls.clear();
for (ctrl_get_list::iterator iter = get_ctrls.begin();
iter != get_ctrls.end(); ++iter) {
struct v4l2_ext_control ctrl = { 0 };
ctrl.id = ctrl_str2id[*iter];
if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG)
mpeg_ctrls.push_back(ctrl);
else
user_ctrls.push_back(ctrl);
}
for (unsigned i = 0; i < user_ctrls.size(); i++) {
struct v4l2_control ctrl;
ctrl.id = user_ctrls[i].id;
doioctl(fd, VIDIOC_G_CTRL, &ctrl, "VIDIOC_G_CTRL");
printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
}
if (mpeg_ctrls.size()) {
ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ctrls.count = mpeg_ctrls.size();
ctrls.controls = &mpeg_ctrls[0];
doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS");
for (unsigned i = 0; i < mpeg_ctrls.size(); i++) {
struct v4l2_ext_control ctrl = mpeg_ctrls[i];
printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value);
}
}
}
if (options[OptGetTuner]) {
struct v4l2_tuner vt;
memset(&vt, 0, sizeof(struct v4l2_tuner));
if (doioctl(fd, VIDIOC_G_TUNER, &vt, "VIDIOC_G_TUNER") == 0) {
printf("Tuner:\n");
printf("\tCapabilities : %s\n", tcap2s(vt.capability).c_str());
if (vt.capability & V4L2_TUNER_CAP_LOW)
printf("\tFrequency range : %.1f MHz - %.1f MHz\n",
vt.rangelow / 16000.0, vt.rangehigh / 16000.0);
else
printf("\tFrequency range : %.1f MHz - %.1f MHz\n",
vt.rangelow / 16.0, vt.rangehigh / 16.0);
printf("\tSignal strength : %d%%\n", (int)(vt.signal / 655.35));
printf("\tCurrent audio mode : %s\n", audmode2s(vt.audmode));
printf("\tAvailable subchannels: %s\n",
rxsubchans2s(vt.rxsubchans).c_str());
}
}
if (options[OptSetTuner]) {
struct v4l2_tuner vt;
memset(&vt, 0, sizeof(struct v4l2_tuner));
if (ioctl(fd, VIDIOC_G_TUNER, &vt) < 0) {
fprintf(stderr, "ioctl: VIDIOC_G_TUNER failed\n");
exit(1);
}
vt.audmode = mode;
doioctl(fd, VIDIOC_S_TUNER, &vt, "VIDIOC_S_TUNER");
}
if (option_version) {
//printf("ivtvctl version " IVTV_VERSION "\n");
}
if (options[OptListCtrls]) {
list_controls(fd, 0);
}
if (option_log_status) {
static char buf[40960];
int len;
if (doioctl(fd, VIDIOC_LOG_STATUS, NULL, "VIDIOC_LOG_STATUS") == 0) {
printf("\nStatus Log:\n\n");
len = klogctl(3, buf, sizeof(buf) - 1);
if (len >= 0) {
char *p = buf;
char *q;
buf[len] = 0;
while ((q = strstr(p, "START STATUS CARD #"))) {
p = q + 1;
}
if (p) {
while (p > buf && *p != '<') p--;
q = p;
while ((q = strstr(q, "<6>"))) {
memcpy(q, " ", 3);
}
printf("%s", p);
}
}
}
}
if (option_streamon) {
int dummy = 0;
doioctl(fd, VIDIOC_STREAMON, &dummy, "VIDIOC_STREAMON");
}
close(fd);
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -