static int ali_vbi_open(struct inode *inode, struct file *file) { //VBI_PRINT("%s()->%s()->%d\n", __FILE__, __FUNCTION__, __LINE__); if(NULL == g_vbi_config_dev) { VBI_PRINT("VBI: g_vbi_config_dev is NULL\n"); return -ENODEV; } else file->private_data = g_vbi_config_dev; vbi_open(g_vbi_config_dev); return 0; }
int V4LRecorder::OpenVBIDevice(void) { int fd = -1; if (vbi_fd >= 0) return vbi_fd; struct VBIData *vbi_cb = NULL; struct vbi *pal_tt = NULL; uint width = 0, start_line = 0, line_count = 0; QByteArray vbidev = vbidevice.toAscii(); if (VBIMode::PAL_TT == vbimode) { pal_tt = vbi_open(vbidev.constData(), NULL, 99, -1); if (pal_tt) { fd = pal_tt->fd; vbi_cb = new VBIData; memset(vbi_cb, 0, sizeof(VBIData)); vbi_cb->nvr = this; vbi_add_handler(pal_tt, (void*) vbi_event, vbi_cb); } } else if (VBIMode::NTSC_CC == vbimode) { fd = open(vbidev.constData(), O_RDONLY/*|O_NONBLOCK*/); } else { LOG(VB_GENERAL, LOG_ERR, LOC + "Invalid CC/Teletext mode"); return -1; } if (fd < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Can't open vbi device: '%1'").arg(vbidevice)); return -1; } if (VBIMode::NTSC_CC == vbimode) { #ifdef USING_V4L2 struct v4l2_format fmt; memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VBI_CAPTURE; if (0 != ioctl(fd, VIDIOC_G_FMT, &fmt)) { #ifdef USING_V4L1 LOG(VB_RECORD, LOG_INFO, "V4L2 VBI setup failed, trying v1 ioctl"); // Try V4L v1 VBI ioctls, iff V4L v2 fails struct vbi_format old_fmt; memset(&old_fmt, 0, sizeof(vbi_format)); if (ioctl(fd, VIDIOCGVBIFMT, &old_fmt) < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to query vbi capabilities (V4L1)"); close(fd); return -1; } fmt.fmt.vbi.sampling_rate = old_fmt.sampling_rate; fmt.fmt.vbi.offset = 0; fmt.fmt.vbi.samples_per_line = old_fmt.samples_per_line; fmt.fmt.vbi.start[0] = old_fmt.start[0]; fmt.fmt.vbi.start[1] = old_fmt.start[1]; fmt.fmt.vbi.count[0] = old_fmt.count[0]; fmt.fmt.vbi.count[1] = old_fmt.count[1]; fmt.fmt.vbi.flags = old_fmt.flags; #else // if !USING_V4L1 LOG(VB_RECORD, LOG_ERR, "V4L2 VBI setup failed"); close(fd); return -1; #endif // !USING_V4L1 } LOG(VB_RECORD, LOG_INFO, LOC + QString("vbi_format rate: %1" "\n\t\t\t offset: %2" "\n\t\t\tsamples_per_line: %3" "\n\t\t\t starts: %4, %5" "\n\t\t\t counts: %6, %7" "\n\t\t\t flags: 0x%8") .arg(fmt.fmt.vbi.sampling_rate) .arg(fmt.fmt.vbi.offset) .arg(fmt.fmt.vbi.samples_per_line) .arg(fmt.fmt.vbi.start[0]) .arg(fmt.fmt.vbi.start[1]) .arg(fmt.fmt.vbi.count[0]) .arg(fmt.fmt.vbi.count[1]) .arg(fmt.fmt.vbi.flags,0,16)); width = fmt.fmt.vbi.samples_per_line; start_line = fmt.fmt.vbi.start[0]; line_count = fmt.fmt.vbi.count[0]; if (line_count != fmt.fmt.vbi.count[1]) { LOG(VB_GENERAL, LOG_ERR, LOC + "VBI must have the same number of " "odd and even fields for our decoder"); close(fd); return -1; } if (start_line > 21 || start_line + line_count < 22) { LOG(VB_GENERAL, LOG_ERR, LOC + "VBI does not include line 21"); // TODO We could try to set the VBI format ourselves.. close(fd); return -1; } #endif // USING_V4L2 } if (VBIMode::PAL_TT == vbimode) { pal_vbi_cb = vbi_cb; pal_vbi_tt = pal_tt; } else if (VBIMode::NTSC_CC == vbimode) { ntsc_vbi_width = width; ntsc_vbi_start_line = start_line; ntsc_vbi_line_count = line_count; vbi608 = new VBI608Extractor(); } vbi_fd = fd; return fd; }