分类:AndroidSamsung S5PV210 480人阅读 评论(13) 收藏 举报

最近在调试S5PV210上的camera驱动,因为对Android的samsung camera hal 不太了解,自己写了个测试程序方便调试

因为camera驱动都是遵守V4L2标准,所以测试程序是通用的,在MX51平台也能工作。

[html] view plain copy
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<assert.h>
  5. #include<getopt.h>
  6. #include<fcntl.h>
  7. #include<unistd.h>
  8. #include<errno.h>
  9. #include<sys/stat.h>
  10. #include<sys/types.h>
  11. #include<sys/time.h>
  12. #include<sys/mman.h>
  13. #include<sys/ioctl.h>
  14. #include<asm/types.h>
  15. #include<linux/videodev2.h>
  16. #include<linux/fb.h>
  17. #defineCLEAR(x)memset(&(x),0,sizeof(x))
  18. intPAL_WIDTH=720;
  19. intPAL_HEIGHT=576;
  20. enum{
  21. RGB565,
  22. RGB888,
  23. RGB32,
  24. };
  25. structbuffer{
  26. void*start;
  27. size_tlength;
  28. };
  29. staticchar*dev_name=NULL;
  30. staticintfd=-1;
  31. staticunsignedintn_buffers=0;
  32. staticintg_width;
  33. staticintg_height;
  34. staticunsignedg_pixelformat;
  35. staticstructfb_var_screeninfovinfo;
  36. staticstructfb_fix_screeninfofinfo;
  37. structbuffer*buffers=NULL;
  38. staticintfile_index=1;
  39. staticintg_count=9;
  40. staticvoiderrno_exit(constchar*s)
  41. {
  42. fprintf(stderr,"%serror%d,%s\n",s,errno,strerror(errno));
  43. exit(EXIT_FAILURE);
  44. }
  45. staticintxioctl(intfd,intrequest,void*arg)
  46. {
  47. intr;
  48. dor=ioctl(fd,request,arg);
  49. while(-1==r&&EINTR==errno);
  50. returnr;
  51. }
  52. staticvoidwrite_yuv(constvoid*p,intindex)
  53. {
  54. intwrite_fd=0;
  55. intret;
  56. intlength;
  57. chartmp[20];
  58. sprintf(tmp,"/data/file/yuvfile%d",index);
  59. write_fd=open(tmp,O_RDWR|O_CREAT);
  60. if(write_fd==-1){
  61. printf("%s:openyuvfilefailed,errno(%d)\n",__func__,errno);
  62. }
  63. length=g_width*g_height*2;
  64. ret=write(write_fd,p,length);
  65. if(ret!=length){
  66. printf("%s:writeyuvfilefailed,ret(%d),errno(%d)\n",__func__,ret,errno);
  67. }
  68. }
  69. staticvoidprocess_image(constvoid*p)
  70. {
  71. if(file_index<g_count){
  72. write_yuv(p,file_index);
  73. file_index=file_index+1;
  74. }
  75. }
  76. staticintread_frame(void)
  77. {
  78. intret=0;
  79. structtimevaltimer;
  80. structv4l2_bufferbuf;
  81. CLEAR(buf);
  82. buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  83. buf.memory=V4L2_MEMORY_MMAP;
  84. if(-1==xioctl(fd,VIDIOC_DQBUF,&buf)){
  85. switch(errno){
  86. caseEAGAIN:
  87. printf("VIDIOC_DQBUFreturnEAGAIN\n");
  88. return0;
  89. default:
  90. printf("VIDIOC_DQBUFfailed,errno(%d):\n",errno,strerror(errno));
  91. ret=-errno;
  92. returnret;
  93. }
  94. }
  95. assert(buf.index<n_buffers);
  96. printf("%s:buf.bytesused(%d),buf.index(%d)\n",
  97. __func__,buf.index);
  98. process_image(buffers[buf.index].start);
  99. if(-1==xioctl(fd,VIDIOC_QBUF,&buf)){
  100. printf("VIDIOC_BUFfailed,errno(%d)\n",errno);
  101. ret=-errno;
  102. }
  103. gettimeofday(&timer,NULL);
  104. printf("(%d)thcapture,tv_sec(%d),tv_usec\n",
  105. file_index,timer.tv_sec,timer.tv_usec);
  106. returnret;
  107. }
  108. staticvoidrun(void)
  109. {
  110. intret;
  111. printf("%s:enter\n",__func__);
  112. while(1){
  113. fd_setfds;
  114. structtimevaltv;
  115. FD_ZERO(&fds);
  116. FD_SET(fd,&fds);
  117. if(file_index==g_count){
  118. break;
  119. }
  120. tv.tv_sec=5;
  121. tv.tv_usec=0;
  122. ret=select(fd+1,&fds,NULL,NULL,&tv);
  123. if(-1==ret){
  124. if(EINTR==errno){
  125. printf("errno==EINTR\n");
  126. continue;
  127. }
  128. errno_exit("select");
  129. }
  130. if(0==ret){
  131. printf("selecttimeout\n");
  132. exit(EXIT_FAILURE);
  133. }
  134. if(read_frame())
  135. continue;
  136. sleep(1);
  137. }
  138. printf("%s:endrun\n",__func__);
  139. }
  140. staticvoidstop_capturing(void)
  141. {
  142. enumv4l2_buf_typetype;
  143. printf("%s:enter\n",__func__);
  144. type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  145. if(-1==xioctl(fd,VIDIOC_STREAMOFF,&type))
  146. errno_exit("VIDIOC_STREAMOFF");
  147. }
  148. staticvoidstart_capturing(void)
  149. {
  150. unsignedinti;
  151. enumv4l2_buf_typetype;
  152. printf("%s:enter\n",__func__);
  153. for(i=0;i<n_buffers;++i){
  154. structv4l2_bufferbuf;
  155. CLEAR(buf);
  156. buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  157. buf.memory=V4L2_MEMORY_MMAP;
  158. buf.index=i;
  159. if(-1==xioctl(fd,VIDIOC_QBUF,&buf))
  160. errno_exit("VIDIOC_QBUF");
  161. }
  162. type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  163. if(-1==xioctl(fd,VIDIOC_STREAMON,&type))
  164. errno_exit("VIDIOC_STREAMON");
  165. }
  166. staticvoiduninit_device(void)
  167. {
  168. unsignedinti;
  169. for(i=0;i<n_buffers;++i)
  170. if(-1==munmap(buffers[i].start,buffers[i].length))
  171. errno_exit("munmap");
  172. free(buffers);
  173. }
  174. staticvoidinit_mmap(void)
  175. {
  176. structv4l2_requestbuffersreq;
  177. CLEAR(req);
  178. req.count=4;
  179. req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  180. req.memory=V4L2_MEMORY_MMAP;
  181. if(-1==xioctl(fd,VIDIOC_REQBUFS,&req)){
  182. if(EINVAL==errno){
  183. fprintf(stderr,"%sdoesnotsupportmemorymapping\n",dev_name);
  184. exit(EXIT_FAILURE);
  185. }else{
  186. errno_exit("VIDIOC_REQBUFS");
  187. }
  188. }
  189. if(req.count<2){//if(req.count<2)
  190. fprintf(stderr,"Insufficientbuffermemoryon%s\n",dev_name);
  191. exit(EXIT_FAILURE);
  192. }
  193. buffers=calloc(req.count,sizeof(*buffers));
  194. if(!buffers){
  195. fprintf(stderr,"Outofmemory\n");
  196. exit(EXIT_FAILURE);
  197. }
  198. printf("requestbuffercount(%d)\n",req.count);
  199. for(n_buffers=0;n_buffers<req.count;++n_buffers){
  200. structv4l2_bufferbuf;
  201. CLEAR(buf);
  202. buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  203. buf.memory=V4L2_MEMORY_MMAP;
  204. buf.index=n_buffers;
  205. if(-1==xioctl(fd,VIDIOC_QUERYBUF,&buf))
  206. errno_exit("VIDIOC_QUERYBUF");
  207. buffers[n_buffers].length=buf.length;
  208. buffers[n_buffers].start=mmap(NULL,buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,buf.m.offset);
  209. printf("buf.start(%p),buf.length(%d)\n",buffers[n_buffers].start,buf.length);
  210. if(MAP_FAILED==buffers[n_buffers].start)
  211. errno_exit("mmap");
  212. }
  213. }
  214. staticvoidinit_device(void)
  215. {
  216. structv4l2_capabilitycap;
  217. structv4l2_cropcapcropcap;
  218. structv4l2_cropcrop;
  219. structv4l2_formatfmt;
  220. if(-1==xioctl(fd,VIDIOC_QUERYCAP,&cap)){
  221. printf("%s:VIDIOC_QUERYCAP\n",__func__,errno);
  222. exit(EXIT_FAILURE);
  223. }
  224. printf("supportoverlaycap.capabilities(0x%x)\n",cap.capabilities);
  225. if(!(cap.capabilities&V4L2_CAP_VIDEO_CAPTURE)){
  226. fprintf(stderr,"%sisnovideocapturedevice\n",dev_name);
  227. exit(EXIT_FAILURE);
  228. }
  229. if(!(cap.capabilities&V4L2_CAP_STREAMING)){
  230. fprintf(stderr,"%sdoesnotsupportstreamingi/o\n",dev_name);
  231. exit(EXIT_FAILURE);
  232. }
  233. CLEAR(cropcap);
  234. cropcap.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  235. if(0==xioctl(fd,VIDIOC_CROPCAP,&cropcap)){
  236. crop.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  237. crop.c=cropcap.defrect;
  238. if(-1==xioctl(fd,VIDIOC_S_CROP,&crop)){
  239. printf("VIDIOC_S_CROPfailed(%d),%s\n",errno,strerror(errno));
  240. }
  241. }
  242. CLEAR(fmt);
  243. fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  244. fmt.fmt.pix.width=PAL_WIDTH;
  245. fmt.fmt.pix.height=PAL_HEIGHT;
  246. fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
  247. fmt.fmt.pix.field=V4L2_FIELD_NONE;
  248. if(-1==xioctl(fd,VIDIOC_S_FMT,&fmt)){
  249. errno_exit("VIDIOC_S_FMT");
  250. }
  251. printf("width(%d),height(%d),pixelformat(0x%x),field(%d)\n",
  252. fmt.fmt.pix.width,fmt.fmt.pix.height,fmt.fmt.pix.pixelformat,
  253. fmt.fmt.pix.field);
  254. g_width=fmt.fmt.pix.width;
  255. g_height=fmt.fmt.pix.height;
  256. init_mmap();
  257. }
  258. staticvoidclose_device(void)
  259. {
  260. close(fd);
  261. }
  262. staticvoidopen_device(void)
  263. {
  264. structstatst;
  265. fd=open(dev_name,O_RDWR|O_NONBLOCK,0);
  266. if(-1==fd){
  267. fprintf(stderr,"Cannotopen'%s':%d,%s\n",
  268. dev_name,errno,strerror(errno));
  269. exit(EXIT_FAILURE);
  270. }
  271. }
  272. staticvoidusage(FILE*fp,intargc,char**argv)
  273. {
  274. fprintf(fp,
  275. "Usage:%s[options]\n\n"
  276. "Options:\n"
  277. "-d|--devicenameVideodevicename[/dev/video]\n"
  278. "-h|--helpPrintthismessage\n"
  279. "-t|--howlongwilldisplayinseconds\n"
  280. "",
  281. argv[0]);
  282. }
  283. staticconstcharshort_options[]="d:w:h:f:p:c:";
  284. staticconststructoptionlong_options[]={
  285. {"device",required_argument,NULL,'d'},
  286. {"help",no_argument,NULL,'h'},
  287. {"time",no_argument,NULL,'t'},
  288. {0,0,0,0}
  289. };
  290. intselect_input(intinput)
  291. {
  292. intret;
  293. ret=xioctl(fd,VIDIOC_S_INPUT,&input);
  294. if(ret){
  295. printf("xioctlVIDIOC_S_INPUTfailederrno(%d)\n",errno);
  296. }
  297. returnret;
  298. }
  299. intmain(intargc,char**argv)
  300. {
  301. dev_name="/dev/video0";
  302. for(;;){
  303. intindex;
  304. intc;
  305. inttmp;
  306. c=getopt_long(argc,argv,short_options,long_options,&index);
  307. if(-1==c)
  308. break;
  309. switch(c){
  310. case0:
  311. break;
  312. case'd':
  313. dev_name=optarg;
  314. break;
  315. case'c':
  316. g_count=strtol(optarg,NULL,10);
  317. break;
  318. case'p':
  319. tmp=strtol(optarg,NULL,10);
  320. if(tmp==0){
  321. g_pixelformat=V4L2_PIX_FMT_UYVY;
  322. }
  323. elseif(tmp==1){
  324. g_pixelformat=V4L2_PIX_FMT_YUYV;
  325. }
  326. break;
  327. case'w':
  328. PAL_WIDTH=strtol(optarg,NULL,10);
  329. printf("PAL_WIDTH(%d)\n",PAL_WIDTH);
  330. break;
  331. case'h':
  332. PAL_HEIGHT=strtol(optarg,NULL,10);
  333. printf("PAL_HEIGHT(%d)\n",PAL_HEIGHT);
  334. break;
  335. default:
  336. usage(stderr,argc,argv);
  337. exit(EXIT_FAILURE);
  338. }
  339. }
  340. open_device();
  341. select_input(0);
  342. init_device();
  343. start_capturing();
  344. run();
  345. stop_capturing();
  346. uninit_device();
  347. close_device();
  348. return0;
  349. }

更多相关文章

  1. 【Android(安卓)Api 翻译2】Android(安卓)Testing(1) 浅尝Androi
  2. Android(安卓)Monkey测试脚本
  3. Android(安卓)ViewPager多页面滑动切换以及单页卡内添加事件
  4. Android(安卓)调试桥(adb)是多种用途的工具
  5. Android下进行单元测试
  6. android内核与驱动
  7. Android(安卓)Studio 里搭建自动化测试框架Robotium
  8. 谷歌Android被Linux内核除名(转)
  9. android内核字符驱动设备实战之----------内置C语言测试程序篇

随机推荐

  1. 头条Android 屏幕适配
  2. Android(安卓)Studio 使用平台特性的jar
  3. Android - AndroidManifest.xml 相关
  4. 教你用电脑从 Google Play 下载 Android
  5. Android用户界面
  6. Android适配全攻略
  7. Android 移植到 C#
  8. webview
  9. Android高仿网易新闻客户端之侧滑菜单
  10. Android MuPDF 部署