Advertisement
Guest User

mplayer_vidix_ivtv_vid.c.diff

a guest
Jul 7th, 2011
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.92 KB | None | 0 0
  1. Index: vidix/ivtv_vid.c
  2. ===================================================================
  3. --- vidix/ivtv_vid.c    (Revision 29462)
  4. +++ vidix/ivtv_vid.c    (Arbeitskopie)
  5. @@ -21,7 +21,9 @@
  6.   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  7.   */
  8.  
  9. +#include <ctype.h>
  10.  #include <errno.h>
  11. +#include <glob.h>
  12.  #include <stdio.h>
  13.  #include <stdlib.h>
  14.  #include <string.h>
  15. @@ -30,6 +32,7 @@
  16.  #include <inttypes.h>
  17.  #include <fcntl.h>
  18.  #include <sys/ioctl.h>
  19. +#include <sys/stat.h>
  20.  #include <linux/types.h>
  21.  #include <linux/version.h>
  22.  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
  23. @@ -223,16 +226,30 @@
  24.  
  25.  int ivtv_probe(int verbose, int force)
  26.  {
  27. -   unsigned char fb_number = 0;
  28. -   char *device_name = NULL;
  29.     char *alpha = NULL;
  30. +   char *ivtv_video_device_name = NULL;
  31. +   char *ivtv_framebuffer_device_name = NULL;
  32.     struct fb_var_screeninfo vinfo;
  33. -   char fb_dev_name[] = "/dev/fb0\0";
  34.     pciinfo_t lst[MAX_PCI_DEVICES];
  35.     int err = 0;
  36.     unsigned int i, num_pci = 0;
  37. -   unsigned char yuv_device_number = 48, yuv_device = 48 + fb_number;
  38. -   char yuv_device_name[] = "/dev/videoXXX\0";
  39. +   struct stat fileStat;
  40. +   char   sysfsVideoClass[] = "/sys/class/video4linux\0";
  41. +   char   sysfsGraphicsClass[] = "/sys/class/graphics\0";
  42. +   char   *yuv_searchPattern[] = { "/sys/class/video4linux/video*\0", "/dev/video*\0"};
  43. +   char   *fb_searchPattern[] = { "/sys/class/graphics/fb*\0", "/dev/fb*\0"};
  44. +   int    yuv_patNr = 0;
  45. +   int    fb_patNr = 0;
  46. +   glob_t searchResult;
  47. +   char   deviceName[] = "/dev/videoXXXXX\0";
  48. +   int    devLen = 0;
  49. +   struct v4l2_capability vcap;
  50. +   struct v4l2_fmtdesc vfdesc;
  51. +   int    found_yuv_format = 0;
  52. +   char   *tmpStr = NULL;
  53. +   int    yuvDevNumber = -1;
  54. +   struct v4l2_framebuffer fbuf;
  55. +   struct fb_fix_screeninfo fbsi;
  56.  
  57.     if(verbose)
  58.         printf(IVTV_MSG"probe\n");
  59. @@ -272,59 +289,165 @@
  60.  
  61.  card_found:
  62.  
  63. -   device_name = getenv("FRAMEBUFFER");
  64. -   if(NULL == device_name) {
  65. -       device_name = fb_dev_name;
  66. -   }
  67. +   if((NULL != (ivtv_video_device_name = getenv("VIDIXIVTVVIDEODEV"))) && (NULL != (ivtv_framebuffer_device_name = getenv("VIDIXIVTVFRAMEBUFFERDEV")))) {
  68. +       yuvdev = open(ivtv_video_device_name, O_RDWR);
  69. +       if(-1 != yuvdev) {
  70. +           fbdev = open(ivtv_framebuffer_device_name, O_RDWR);
  71. +           if(-1 == fbdev) {
  72. +               close(yuvdev);
  73. +               yuvdev = -1;
  74. +           } else
  75. +               goto yuv_found;
  76. +       }
  77. +   }
  78. +  
  79. +   /* test if sysfs is present, otherwise fallback to /dev */
  80. +   if(access(sysfsVideoClass, F_OK) < 0)
  81. +       yuv_patNr = 1;
  82. +   if(access(sysfsGraphicsClass, F_OK) < 0)
  83. +       fb_patNr = 1;
  84. +
  85. +   /* search for the installed video devices */
  86. +   if(glob(yuv_searchPattern[yuv_patNr], GLOB_MARK, 0, &searchResult) == 0) {
  87. +       for(i = 0; (yuvDevNumber < 0) && (i < searchResult.gl_pathc); i++) {
  88. +           if(stat(searchResult.gl_pathv[i], &fileStat) == 0) {
  89. +               devLen = 0;
  90. +               if((yuv_patNr == 0) && S_ISDIR(fileStat.st_mode)) {
  91. +                   /* get the related device-node */
  92. +                   snprintf(deviceName, sizeof(deviceName), "/dev/%s", searchResult.gl_pathv[i] + strlen(sysfsVideoClass) + 1);
  93. +                   devLen = strlen(deviceName);
  94. +                   if(deviceName[devLen - 1] == '/') {
  95. +                       devLen--;
  96. +                       deviceName[devLen]= 0;
  97. +                   }
  98. +               } else if((yuv_patNr == 1) && !S_ISDIR(fileStat.st_mode)) {
  99. +                   snprintf(deviceName, sizeof(deviceName), "%s", searchResult.gl_pathv[i]);
  100. +                   devLen = strlen(deviceName);
  101. +               }
  102. +              
  103. +               if(devLen > 0) {
  104. +                   yuvdev = open(deviceName, O_RDONLY);
  105. +                   if(-1 == yuvdev) {
  106. +                       printf(IVTV_MSG"Error occured during opening %s\n", deviceName);
  107. +                   } else {
  108. +                       if(ioctl(yuvdev, VIDIOC_QUERYCAP, &vcap) < 0) {
  109. +                           printf(IVTV_MSG"unable to query capabilites of %s\n", deviceName);
  110. +                       } else if(strncmp(vcap.driver, "ivtv", 4) == 0) {
  111. +                           if(vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT) {
  112. +                               /* it is a device handled by ivtv and it has an output */
  113. +                               vfdesc.index = 0;
  114. +                               vfdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  115. +                               found_yuv_format = 0;
  116. +                               while(ioctl(yuvdev, VIDIOC_ENUM_FMT, &vfdesc) == 0) {
  117. +                                   if(vfdesc.pixelformat == V4L2_PIX_FMT_HM12) {
  118. +                                       found_yuv_format= 1;
  119. +                                       break;
  120. +                                   }
  121. +                                   vfdesc.index++;
  122. +                               }
  123. +                               if(found_yuv_format) {
  124. +                                   /* it supports the needed pixel format */
  125.  
  126. -   fb_number = atoi(device_name+strlen("/dev/fb"));
  127. +                                   /* hack is here
  128. +                                   there is a problem at the v4l2-api
  129. +                                   a PVR350 has multiple devices
  130. +                                   /dev/video0
  131. +                                   /dev/video16
  132. +                                   /dev/video32
  133. +                                   /dev/video48
  134. +                                   VIDIOC_QUERYCAP returns the same for every device
  135. +                                   so the code has to know that the YUV-decoder is
  136. +                                   at /dev/video48 or higher
  137.  
  138. -   fbdev = open(device_name, O_RDWR);
  139. -   if(-1 != fbdev) {
  140. -       if(ioctl(fbdev, FBIOGET_VSCREENINFO, &vinfo) < 0) {
  141. -           printf(IVTV_MSG"Unable to read screen info\n");
  142. -           close(fbdev);
  143. -           return ENXIO;
  144. -       } else {
  145. -           fb_width = vinfo.xres;
  146. -           fb_height = vinfo.yres;
  147. -           if(2 == ivtv_verbose) {
  148. -               printf(IVTV_MSG"framebuffer width : %3.0f\n",fb_width);
  149. -               printf(IVTV_MSG"framebuffer height: %3.0f\n",fb_height);
  150. +                                   maybe this is solved in the future...
  151. +                                   */
  152. +                                   tmpStr = deviceName + devLen;
  153. +                                   while((tmpStr >= deviceName) && isdigit((tmpStr-1)[0]))
  154. +                                       tmpStr--;
  155. +                                   if(tmpStr > deviceName) {
  156. +                                       yuvDevNumber = atoi(tmpStr);
  157. +                                       if(yuvDevNumber < 48)
  158. +                                           yuvDevNumber = -1;
  159. +                                   }
  160. +                               }
  161. +                           }
  162. +                       }
  163. +                       close(yuvdev);
  164. +                       yuvdev = -1;
  165. +                   }
  166. +               }
  167. +           }
  168. +       }
  169. +   }
  170. +   globfree(&searchResult);
  171. +   if(yuvDevNumber < 0) {
  172. +       printf(IVTV_MSG"no ivtv-driven yuv-decoder found\n");
  173. +       printf(IVTV_MSG"try to set VIDIXIVTVVIDEODEV and VIDIXIVTVFRAMEBUFFERDEV  to the right devicenames (e.g. /dev/video48 and /dev/fb1)\n");
  174. +       return ENXIO;
  175. +   }
  176. +
  177. +   snprintf(deviceName, sizeof(deviceName), "/dev/video%d", yuvDevNumber);
  178. +   yuvdev = open(deviceName, O_RDWR);
  179. +   if(-1 == yuvdev) {
  180. +       printf(IVTV_MSG"Error opening yuv-decoder %s\n", deviceName);
  181. +   } else {
  182. +       if(verbose)
  183. +           printf(IVTV_MSG"Found yuv-decoder %s\n", deviceName);
  184. +       if(ioctl(yuvdev, VIDIOC_G_FBUF, &fbuf) == 0) {
  185. +           /* searching for the related framebuffer-device */
  186. +           if(glob(fb_searchPattern[fb_patNr], GLOB_MARK, 0, &searchResult) == 0) {
  187. +               for(i = 0; i < searchResult.gl_pathc; i++) {
  188. +                   if(stat(searchResult.gl_pathv[ i], &fileStat) == 0) {
  189. +                       devLen = 0;
  190. +                       if((fb_patNr == 0) && S_ISDIR(fileStat.st_mode)) {
  191. +                           snprintf(deviceName, sizeof(deviceName), "/dev/%s", searchResult.gl_pathv[i] + strlen(sysfsGraphicsClass) + 1);
  192. +                           devLen = strlen( deviceName);
  193. +                           if(deviceName[devLen - 1] == '/') {
  194. +                               devLen--;
  195. +                               deviceName[devLen] = 0;
  196. +                           }
  197. +                       } else if((fb_patNr == 1) && !S_ISDIR(fileStat.st_mode)) {
  198. +                           snprintf(deviceName, sizeof(deviceName), "%s", searchResult.gl_pathv[i]);
  199. +                           devLen = strlen(deviceName);
  200. +                       }
  201. +                      
  202. +                       if(devLen > 0) {
  203. +                           fbdev = open(deviceName, O_RDWR);
  204. +                           if(-1 == fbdev) {
  205. +                               printf(IVTV_MSG"Error occured during opening %s\n", deviceName);
  206. +                           } else {
  207. +                               if(0 == ioctl(fbdev, FBIOGET_FSCREENINFO, &fbsi)) {
  208. +                                   if(fbsi.smem_start == (unsigned long) fbuf.base)
  209. +                                       break; /* found it */
  210. +                               }
  211. +                               close(fbdev);
  212. +                               fbdev = -1;
  213. +                           }
  214. +                       }
  215. +                   }
  216. +               }
  217. +               globfree(&searchResult);
  218.             }
  219.         }
  220. -       if(NULL != (alpha = getenv("VIDIXIVTVALPHA"))) {
  221. -           if(0 == strcmp(alpha, "disable")) {
  222. -               alpha_disable = 1;
  223. -           }
  224. -       }
  225. -   } else {
  226. -       printf(IVTV_MSG"Failed to open /dev/fb%u\n", fb_number);
  227. -       return ENXIO;
  228. +       if(-1 == fbdev) {
  229. +           printf(IVTV_MSG"no related framebuffer found\n");
  230. +           printf(IVTV_MSG"try to set VIDIXIVTVVIDEODEV and VIDIXIVTVFRAMEBUFFERDEV  to the right devicenames (e.g. /dev/video48 and /dev/fb1)\n");
  231. +       } else
  232. +           goto yuv_found;
  233.     }
  234. -
  235. -   /* Try to find YUV device */
  236. -   do {
  237. -       sprintf(yuv_device_name, "/dev/video%u", yuv_device);
  238. -       yuvdev = open(yuv_device_name, O_RDWR);
  239. -       if(-1 != yuvdev) {
  240. -           if(ivtv_verbose)
  241. -               printf(IVTV_MSG"YUV device found /dev/video%u\n", yuv_device);
  242. -           goto yuv_found;
  243. -       } else {
  244. -           if(ivtv_verbose)
  245. -               printf(IVTV_MSG"YUV device not found: /dev/video%u\n", yuv_device);
  246. -       }
  247. -   } while(yuv_device-- > yuv_device_number);
  248. -   return ENXIO;
  249. -
  250. +   close(yuvdev);
  251. +   yuvdev = -1;
  252. +   return ENXIO;
  253. +
  254.  yuv_found:
  255.     if(0 == alpha_disable) {
  256.  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
  257.         if(ioctl(fbdev, IVTVFB_IOCTL_GET_STATE, &fb_state_old) < 0) {
  258.             printf(IVTV_MSG"Unable to read fb state\n");
  259.             close(yuvdev);
  260. +           yuvdev = -1;
  261.             close(fbdev);
  262. +           fbdev = -1;
  263.             return ENXIO;
  264.         } else {
  265.             if(ivtv_verbose) {
  266. @@ -340,7 +463,9 @@
  267.         if(ioctl(yuvdev, VIDIOC_G_FMT , &format_old) < 0) {
  268.             printf(IVTV_MSG"Unable to read fb state\n");
  269.             close(yuvdev);
  270. +           yuvdev = -1;
  271.             close(fbdev);
  272. +           fbdev = -1;
  273.             return ENXIO;
  274.         } else {
  275.             if(ivtv_verbose) {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement