Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: vidix/ivtv_vid.c
- ===================================================================
- --- vidix/ivtv_vid.c (Revision 29462)
- +++ vidix/ivtv_vid.c (Arbeitskopie)
- @@ -21,7 +21,9 @@
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- +#include <ctype.h>
- #include <errno.h>
- +#include <glob.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- @@ -30,6 +32,7 @@
- #include <inttypes.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- +#include <sys/stat.h>
- #include <linux/types.h>
- #include <linux/version.h>
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
- @@ -223,16 +226,30 @@
- int ivtv_probe(int verbose, int force)
- {
- - unsigned char fb_number = 0;
- - char *device_name = NULL;
- char *alpha = NULL;
- + char *ivtv_video_device_name = NULL;
- + char *ivtv_framebuffer_device_name = NULL;
- struct fb_var_screeninfo vinfo;
- - char fb_dev_name[] = "/dev/fb0\0";
- pciinfo_t lst[MAX_PCI_DEVICES];
- int err = 0;
- unsigned int i, num_pci = 0;
- - unsigned char yuv_device_number = 48, yuv_device = 48 + fb_number;
- - char yuv_device_name[] = "/dev/videoXXX\0";
- + struct stat fileStat;
- + char sysfsVideoClass[] = "/sys/class/video4linux\0";
- + char sysfsGraphicsClass[] = "/sys/class/graphics\0";
- + char *yuv_searchPattern[] = { "/sys/class/video4linux/video*\0", "/dev/video*\0"};
- + char *fb_searchPattern[] = { "/sys/class/graphics/fb*\0", "/dev/fb*\0"};
- + int yuv_patNr = 0;
- + int fb_patNr = 0;
- + glob_t searchResult;
- + char deviceName[] = "/dev/videoXXXXX\0";
- + int devLen = 0;
- + struct v4l2_capability vcap;
- + struct v4l2_fmtdesc vfdesc;
- + int found_yuv_format = 0;
- + char *tmpStr = NULL;
- + int yuvDevNumber = -1;
- + struct v4l2_framebuffer fbuf;
- + struct fb_fix_screeninfo fbsi;
- if(verbose)
- printf(IVTV_MSG"probe\n");
- @@ -272,59 +289,165 @@
- card_found:
- - device_name = getenv("FRAMEBUFFER");
- - if(NULL == device_name) {
- - device_name = fb_dev_name;
- - }
- + if((NULL != (ivtv_video_device_name = getenv("VIDIXIVTVVIDEODEV"))) && (NULL != (ivtv_framebuffer_device_name = getenv("VIDIXIVTVFRAMEBUFFERDEV")))) {
- + yuvdev = open(ivtv_video_device_name, O_RDWR);
- + if(-1 != yuvdev) {
- + fbdev = open(ivtv_framebuffer_device_name, O_RDWR);
- + if(-1 == fbdev) {
- + close(yuvdev);
- + yuvdev = -1;
- + } else
- + goto yuv_found;
- + }
- + }
- +
- + /* test if sysfs is present, otherwise fallback to /dev */
- + if(access(sysfsVideoClass, F_OK) < 0)
- + yuv_patNr = 1;
- + if(access(sysfsGraphicsClass, F_OK) < 0)
- + fb_patNr = 1;
- +
- + /* search for the installed video devices */
- + if(glob(yuv_searchPattern[yuv_patNr], GLOB_MARK, 0, &searchResult) == 0) {
- + for(i = 0; (yuvDevNumber < 0) && (i < searchResult.gl_pathc); i++) {
- + if(stat(searchResult.gl_pathv[i], &fileStat) == 0) {
- + devLen = 0;
- + if((yuv_patNr == 0) && S_ISDIR(fileStat.st_mode)) {
- + /* get the related device-node */
- + snprintf(deviceName, sizeof(deviceName), "/dev/%s", searchResult.gl_pathv[i] + strlen(sysfsVideoClass) + 1);
- + devLen = strlen(deviceName);
- + if(deviceName[devLen - 1] == '/') {
- + devLen--;
- + deviceName[devLen]= 0;
- + }
- + } else if((yuv_patNr == 1) && !S_ISDIR(fileStat.st_mode)) {
- + snprintf(deviceName, sizeof(deviceName), "%s", searchResult.gl_pathv[i]);
- + devLen = strlen(deviceName);
- + }
- +
- + if(devLen > 0) {
- + yuvdev = open(deviceName, O_RDONLY);
- + if(-1 == yuvdev) {
- + printf(IVTV_MSG"Error occured during opening %s\n", deviceName);
- + } else {
- + if(ioctl(yuvdev, VIDIOC_QUERYCAP, &vcap) < 0) {
- + printf(IVTV_MSG"unable to query capabilites of %s\n", deviceName);
- + } else if(strncmp(vcap.driver, "ivtv", 4) == 0) {
- + if(vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT) {
- + /* it is a device handled by ivtv and it has an output */
- + vfdesc.index = 0;
- + vfdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- + found_yuv_format = 0;
- + while(ioctl(yuvdev, VIDIOC_ENUM_FMT, &vfdesc) == 0) {
- + if(vfdesc.pixelformat == V4L2_PIX_FMT_HM12) {
- + found_yuv_format= 1;
- + break;
- + }
- + vfdesc.index++;
- + }
- + if(found_yuv_format) {
- + /* it supports the needed pixel format */
- - fb_number = atoi(device_name+strlen("/dev/fb"));
- + /* hack is here
- + there is a problem at the v4l2-api
- + a PVR350 has multiple devices
- + /dev/video0
- + /dev/video16
- + /dev/video32
- + /dev/video48
- + VIDIOC_QUERYCAP returns the same for every device
- + so the code has to know that the YUV-decoder is
- + at /dev/video48 or higher
- - fbdev = open(device_name, O_RDWR);
- - if(-1 != fbdev) {
- - if(ioctl(fbdev, FBIOGET_VSCREENINFO, &vinfo) < 0) {
- - printf(IVTV_MSG"Unable to read screen info\n");
- - close(fbdev);
- - return ENXIO;
- - } else {
- - fb_width = vinfo.xres;
- - fb_height = vinfo.yres;
- - if(2 == ivtv_verbose) {
- - printf(IVTV_MSG"framebuffer width : %3.0f\n",fb_width);
- - printf(IVTV_MSG"framebuffer height: %3.0f\n",fb_height);
- + maybe this is solved in the future...
- + */
- + tmpStr = deviceName + devLen;
- + while((tmpStr >= deviceName) && isdigit((tmpStr-1)[0]))
- + tmpStr--;
- + if(tmpStr > deviceName) {
- + yuvDevNumber = atoi(tmpStr);
- + if(yuvDevNumber < 48)
- + yuvDevNumber = -1;
- + }
- + }
- + }
- + }
- + close(yuvdev);
- + yuvdev = -1;
- + }
- + }
- + }
- + }
- + }
- + globfree(&searchResult);
- + if(yuvDevNumber < 0) {
- + printf(IVTV_MSG"no ivtv-driven yuv-decoder found\n");
- + printf(IVTV_MSG"try to set VIDIXIVTVVIDEODEV and VIDIXIVTVFRAMEBUFFERDEV to the right devicenames (e.g. /dev/video48 and /dev/fb1)\n");
- + return ENXIO;
- + }
- +
- + snprintf(deviceName, sizeof(deviceName), "/dev/video%d", yuvDevNumber);
- + yuvdev = open(deviceName, O_RDWR);
- + if(-1 == yuvdev) {
- + printf(IVTV_MSG"Error opening yuv-decoder %s\n", deviceName);
- + } else {
- + if(verbose)
- + printf(IVTV_MSG"Found yuv-decoder %s\n", deviceName);
- + if(ioctl(yuvdev, VIDIOC_G_FBUF, &fbuf) == 0) {
- + /* searching for the related framebuffer-device */
- + if(glob(fb_searchPattern[fb_patNr], GLOB_MARK, 0, &searchResult) == 0) {
- + for(i = 0; i < searchResult.gl_pathc; i++) {
- + if(stat(searchResult.gl_pathv[ i], &fileStat) == 0) {
- + devLen = 0;
- + if((fb_patNr == 0) && S_ISDIR(fileStat.st_mode)) {
- + snprintf(deviceName, sizeof(deviceName), "/dev/%s", searchResult.gl_pathv[i] + strlen(sysfsGraphicsClass) + 1);
- + devLen = strlen( deviceName);
- + if(deviceName[devLen - 1] == '/') {
- + devLen--;
- + deviceName[devLen] = 0;
- + }
- + } else if((fb_patNr == 1) && !S_ISDIR(fileStat.st_mode)) {
- + snprintf(deviceName, sizeof(deviceName), "%s", searchResult.gl_pathv[i]);
- + devLen = strlen(deviceName);
- + }
- +
- + if(devLen > 0) {
- + fbdev = open(deviceName, O_RDWR);
- + if(-1 == fbdev) {
- + printf(IVTV_MSG"Error occured during opening %s\n", deviceName);
- + } else {
- + if(0 == ioctl(fbdev, FBIOGET_FSCREENINFO, &fbsi)) {
- + if(fbsi.smem_start == (unsigned long) fbuf.base)
- + break; /* found it */
- + }
- + close(fbdev);
- + fbdev = -1;
- + }
- + }
- + }
- + }
- + globfree(&searchResult);
- }
- }
- - if(NULL != (alpha = getenv("VIDIXIVTVALPHA"))) {
- - if(0 == strcmp(alpha, "disable")) {
- - alpha_disable = 1;
- - }
- - }
- - } else {
- - printf(IVTV_MSG"Failed to open /dev/fb%u\n", fb_number);
- - return ENXIO;
- + if(-1 == fbdev) {
- + printf(IVTV_MSG"no related framebuffer found\n");
- + printf(IVTV_MSG"try to set VIDIXIVTVVIDEODEV and VIDIXIVTVFRAMEBUFFERDEV to the right devicenames (e.g. /dev/video48 and /dev/fb1)\n");
- + } else
- + goto yuv_found;
- }
- -
- - /* Try to find YUV device */
- - do {
- - sprintf(yuv_device_name, "/dev/video%u", yuv_device);
- - yuvdev = open(yuv_device_name, O_RDWR);
- - if(-1 != yuvdev) {
- - if(ivtv_verbose)
- - printf(IVTV_MSG"YUV device found /dev/video%u\n", yuv_device);
- - goto yuv_found;
- - } else {
- - if(ivtv_verbose)
- - printf(IVTV_MSG"YUV device not found: /dev/video%u\n", yuv_device);
- - }
- - } while(yuv_device-- > yuv_device_number);
- - return ENXIO;
- -
- + close(yuvdev);
- + yuvdev = -1;
- + return ENXIO;
- +
- yuv_found:
- if(0 == alpha_disable) {
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- if(ioctl(fbdev, IVTVFB_IOCTL_GET_STATE, &fb_state_old) < 0) {
- printf(IVTV_MSG"Unable to read fb state\n");
- close(yuvdev);
- + yuvdev = -1;
- close(fbdev);
- + fbdev = -1;
- return ENXIO;
- } else {
- if(ivtv_verbose) {
- @@ -340,7 +463,9 @@
- if(ioctl(yuvdev, VIDIOC_G_FMT , &format_old) < 0) {
- printf(IVTV_MSG"Unable to read fb state\n");
- close(yuvdev);
- + yuvdev = -1;
- close(fbdev);
- + fbdev = -1;
- return ENXIO;
- } else {
- if(ivtv_verbose) {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement