main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <sys/mman.h>
  6. #include <poll.h>
  7. #include <sys/ioctl.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <linux/videodev2.h>
  11. #include <pthread.h>
  12. #include "include/ark_api.h"
  13. #define DISP_WIDTH 1024
  14. #define DISP_HEIGHE 600
  15. #define DISP_SOURCE_WIDTH 720
  16. #define DISP_SOURCE_HEIGHE 240
  17. #define BUF_NUM 4
  18. #define DISPLAY 1
  19. #define GETDATA 2
  20. struct vin_display_outpara{
  21. unsigned int layer;
  22. unsigned int pos_data;
  23. unsigned int source_size;
  24. unsigned int layer_size;
  25. unsigned int format;
  26. struct ark_disp_addr disp_addr;
  27. struct ark_disp_scaler scaler;
  28. };
  29. struct VideoDevice {
  30. int Vfd;
  31. int VpixelFormat;
  32. int VideoBufCurIndex;
  33. int VideoBufCnt;
  34. int VideoBufMaxLen;
  35. unsigned char *Cam_vbuf[BUF_NUM]; //video data virtual address
  36. unsigned char* Video_Data; //video data physical address
  37. };
  38. enum work_mode {
  39. WORK_MODE_DISPLAY,
  40. WORK_MODE_GETDATA,
  41. WORK_MODE_END,
  42. };
  43. struct VideoDevice *g_ark_Vdev;
  44. struct vin_display_outpara* g_ark_para;
  45. static pthread_t v4l2_work_id;
  46. int t_cmd;
  47. /* This function first makes the query judgmentThe space is then allocated and queued */
  48. static int V4l2InitDevice(struct VideoDevice *Vdec)
  49. {
  50. struct v4l2_fmtdesc tFmtDesc;
  51. struct v4l2_requestbuffers tV4l2buf;
  52. struct v4l2_format tV4l2Fmt;
  53. struct v4l2_buffer tV4l2Buf;
  54. struct v4l2_capability tV4l2Cap;
  55. int Fd,Ret,Error,i;
  56. Fd = open("/dev/video0",O_RDWR);
  57. if( Fd < 0 )
  58. {
  59. printf("open error.\n");
  60. return -1;
  61. }
  62. Vdec->Vfd = Fd;
  63. memset(&tV4l2Cap, 0, sizeof(struct v4l2_capability));
  64. Error = ioctl(Fd, VIDIOC_QUERYCAP, &tV4l2Cap);
  65. if (Error) {
  66. printf("unable to query device.\n");
  67. return -1;
  68. }
  69. if (!(tV4l2Cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
  70. {
  71. printf("device is not a video capture device.\n");
  72. return -1;
  73. }
  74. tFmtDesc.index = 0;
  75. tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  76. ioctl(Fd,VIDIOC_ENUM_FMT,&tFmtDesc);
  77. Vdec->VpixelFormat = tFmtDesc.pixelformat;
  78. memset(&tV4l2Fmt, 0, sizeof(struct v4l2_format));
  79. tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  80. tV4l2Fmt.fmt.pix.pixelformat = Vdec->VpixelFormat;
  81. tV4l2Fmt.fmt.pix.width = 720;
  82. tV4l2Fmt.fmt.pix.height = 240;
  83. tV4l2Fmt.fmt.pix.field = V4L2_FIELD_ANY;
  84. Ret = ioctl(Fd, VIDIOC_S_FMT, &tV4l2Fmt);
  85. if (Ret)
  86. printf("Unable to set format\n");
  87. tV4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  88. tV4l2buf.memory = 1;
  89. tV4l2buf.count = BUF_NUM;
  90. ioctl(Fd,VIDIOC_REQBUFS,&tV4l2buf);
  91. Vdec->VideoBufCnt = tV4l2buf.count;
  92. for(i =0; i<Vdec->VideoBufCnt; i++)
  93. {
  94. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  95. tV4l2Buf.index = i;
  96. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  97. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  98. ioctl(Fd,VIDIOC_QUERYBUF,&tV4l2Buf);
  99. Vdec->VideoBufMaxLen = tV4l2Buf.length;
  100. //printf("Vdec->VideoBufMaxLen = %d \n",Vdec->VideoBufMaxLen);
  101. /* 0 is start anywhere */
  102. Vdec->Cam_vbuf[i] = mmap(0,tV4l2Buf.length, PROT_READ, MAP_SHARED,Fd,tV4l2Buf.m.offset);
  103. if (Vdec->Cam_vbuf[i] == MAP_FAILED)
  104. {
  105. printf("Unable to map buffer\n");
  106. }
  107. }
  108. for(i =0; i<Vdec->VideoBufCnt; i++)
  109. {
  110. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  111. tV4l2Buf.index = i;
  112. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  113. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  114. Error = ioctl(Fd, VIDIOC_QBUF, &tV4l2Buf);
  115. if (Error)
  116. {
  117. printf("Unable to queue buffer.\n");
  118. }
  119. }
  120. return 0;
  121. }
  122. static int V4l2ExitDevice(struct VideoDevice *Vdec)
  123. {
  124. int i;
  125. for (i = 0; i < Vdec->VideoBufCnt; i++)
  126. {
  127. if (Vdec->Cam_vbuf[i])
  128. {
  129. munmap(Vdec->Cam_vbuf[i], Vdec->VideoBufMaxLen);
  130. Vdec->Cam_vbuf[i] = NULL;
  131. }
  132. }
  133. close(Vdec->Vfd);
  134. return 0;
  135. }
  136. static int V4l2GetDataForStreaming(struct VideoDevice *Vdec)
  137. {
  138. struct pollfd Fds[1];
  139. int Ret;
  140. struct v4l2_buffer tV4l2Buf;
  141. /*wait data*/
  142. Fds[0].fd = Vdec->Vfd;
  143. Fds[0].events = POLLIN;
  144. Ret = poll(Fds, 1, -1);
  145. if (Ret <= 0)
  146. {
  147. printf("poll error!\n");
  148. return -1;
  149. }
  150. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  151. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  152. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  153. Ret = ioctl(Vdec->Vfd, VIDIOC_DQBUF, &tV4l2Buf);
  154. if (Ret < 0)
  155. {
  156. printf("Unable to dequeue buffer.\n");
  157. return -1;
  158. }
  159. Vdec->VideoBufCurIndex = tV4l2Buf.index;
  160. Vdec->VideoBufMaxLen = tV4l2Buf.length;
  161. //printf("app get buf index : %d\n",tV4l2Buf.index);
  162. /*get physics data*/
  163. Vdec->Video_Data = tV4l2Buf.m.offset;
  164. return 0;
  165. }
  166. static int V4l2PutDataForStreaming(struct VideoDevice *Vdec)
  167. {
  168. struct v4l2_buffer tV4l2Buf;
  169. int Error;
  170. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  171. tV4l2Buf.index = Vdec->VideoBufCurIndex;
  172. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  173. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  174. /*Put the extracted buf in the queue*/
  175. Error = ioctl(Vdec->Vfd, VIDIOC_QBUF, &tV4l2Buf);
  176. if (Error)
  177. {
  178. printf("Unable to queue buffer.\n");
  179. return -1;
  180. }
  181. return 0;
  182. }
  183. static int V4l2StartDevice(struct VideoDevice *Vdec)
  184. {
  185. int Type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  186. int Error;
  187. Error = ioctl(Vdec->Vfd, VIDIOC_STREAMON, &Type);
  188. if (Error)
  189. {
  190. printf("Unable to start capture.\n");
  191. return -1;
  192. }
  193. return 0;
  194. }
  195. static int V4l2StopDevice(struct VideoDevice *Vdec)
  196. {
  197. int Type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  198. int Error;
  199. Error = ioctl(Vdec->Vfd, VIDIOC_STREAMOFF, &Type);
  200. if (Error)
  201. {
  202. printf("Unable to stop capture.\n");
  203. return -1;
  204. }
  205. return 0;
  206. }
  207. void display_layer_init(struct VideoDevice *Vdec)
  208. {
  209. screen_info screen;
  210. disp_scaler out_para;
  211. int Ret,Format;
  212. Ret = arkapi_display_get_screen_info(&screen);
  213. if(Ret == 0){
  214. g_ark_para->layer_size= (screen.height << 16) | screen.width;
  215. }else{
  216. g_ark_para->layer_size = (DISP_HEIGHE << 16) | DISP_WIDTH;
  217. }
  218. g_ark_para->source_size = (DISP_SOURCE_HEIGHE << 16) | DISP_SOURCE_WIDTH;
  219. g_ark_para->pos_data = 0;
  220. g_ark_para->format = ARK_LCDC_FORMAT_VYUY; //| ARK_LCDC_ORDER_VYUY;
  221. memset(&out_para, 0, sizeof(disp_scaler));
  222. out_para.src_w=DISP_SOURCE_WIDTH;
  223. out_para.src_h=DISP_SOURCE_HEIGHE;
  224. out_para.out_w=screen.width;
  225. out_para.out_h=screen.height;
  226. printf("display_layer_init : out_w = %d out_h = %d \n",screen.width,screen.height);
  227. g_ark_para->scaler = out_para;
  228. display_hide_layer();
  229. ioctl(g_ark_Vdev->Vfd, VIN_SET_WINDOW_POS, g_ark_para);
  230. ioctl(g_ark_Vdev->Vfd, VIN_SET_SOURCE_SIZE, g_ark_para);
  231. ioctl(g_ark_Vdev->Vfd, VIN_SET_LAYER_SIZE, g_ark_para);
  232. ioctl(g_ark_Vdev->Vfd, VIN_SET_WINDOW_FORMAT, g_ark_para);
  233. ioctl(g_ark_Vdev->Vfd, VIN_SET_WINDOW_SCALER, g_ark_para);
  234. }
  235. void display_set_addr(u32 pyrgbaddr, u32 pcbaddr, u32 pcraddr)
  236. {
  237. //printf("app write buf : %p\n",Vbuf->Video_Data);
  238. struct ark_disp_addr addr;
  239. addr.yaddr = pyrgbaddr;
  240. addr.cbaddr = pcbaddr;
  241. addr.craddr = pcraddr;
  242. g_ark_para->disp_addr = addr;
  243. ioctl(g_ark_Vdev->Vfd, VIN_SET_WINDOW_ADDR, g_ark_para);
  244. }
  245. void display_show_layer(void)
  246. {
  247. ioctl(g_ark_Vdev->Vfd, VIN_SHOW_WINDOW, g_ark_para);
  248. }
  249. void display_hide_layer(void)
  250. {
  251. ioctl(g_ark_Vdev->Vfd, VIN_HIDE_WINDOW, g_ark_para);
  252. }
  253. static void* v4l2_work_thread(void *param)
  254. {
  255. int fd_t,Ret,i;
  256. if(t_cmd == DISPLAY){
  257. while(1){
  258. V4l2GetDataForStreaming(g_ark_Vdev);
  259. display_set_addr(g_ark_Vdev->Video_Data,0,0);
  260. V4l2PutDataForStreaming(g_ark_Vdev);
  261. }
  262. }
  263. else if(t_cmd == GETDATA){
  264. fd_t = open("stream.bin",O_RDWR|O_CREAT);
  265. if(fd_t < 0){
  266. printf("open error.\n");
  267. return 0;
  268. }
  269. while(1){
  270. V4l2GetDataForStreaming(g_ark_Vdev);
  271. Ret = write(fd_t,g_ark_Vdev->Cam_vbuf[g_ark_Vdev->VideoBufCurIndex],g_ark_Vdev->VideoBufMaxLen);
  272. V4l2PutDataForStreaming(g_ark_Vdev);
  273. }
  274. }
  275. else{
  276. printf("mode error t_cmd = %d.\n",t_cmd);
  277. return 0;
  278. }
  279. }
  280. void video_start(void)
  281. {
  282. //printf("video_start cmd = %d \n",t_cmd);
  283. pthread_create(&v4l2_work_id, NULL, v4l2_work_thread,NULL);
  284. }
  285. int display_demo(void)
  286. {
  287. char flag_quit[10];
  288. int Ret;
  289. t_cmd = DISPLAY;
  290. display_layer_init(g_ark_Vdev);
  291. /* start device && open display layer*/
  292. Ret = V4l2StartDevice(g_ark_Vdev);
  293. if(Ret < 0){
  294. printf("start v4l2 device error.\n");
  295. return 0;
  296. }
  297. display_show_layer();
  298. video_start();
  299. while(1){
  300. printf("exit <enter quit>:\n");
  301. scanf("%s",&flag_quit);
  302. if(strncmp(flag_quit,"quit",5) == 0){
  303. display_hide_layer();
  304. break;
  305. }
  306. }
  307. }
  308. int getdata_demo(void)
  309. {
  310. char flag_quit[10];
  311. int Ret;
  312. t_cmd = GETDATA;
  313. /* start device && open display layer*/
  314. Ret = V4l2StartDevice(g_ark_Vdev);
  315. if(Ret < 0){
  316. printf("start v4l2 device error.\n");
  317. return 0;
  318. }
  319. video_start();
  320. while(1){
  321. printf("exit <enter quit>:\n");
  322. scanf("%s",&flag_quit);
  323. if(strncmp(flag_quit,"quit",5) == 0){
  324. break;
  325. }
  326. }
  327. }
  328. static void printf_command_help(void)
  329. {
  330. printf("\n");
  331. printf("***********************command help*****************************\n");
  332. printf("* *\n");
  333. printf("*run cmd: demo-v4l2 [cmd] *\n");
  334. printf("* *\n");
  335. printf("*cmd1 option: 1.display 2.getdata *\n");
  336. printf("* *\n");
  337. printf("*example: *\n");
  338. printf("* demo-v4l2 display *\n");
  339. printf("* demo-v4l2 getdata *\n");
  340. printf("* *\n");
  341. printf("****************************************************************\n");
  342. printf("\n");
  343. }
  344. int main(int argc, char *argv[])
  345. {
  346. struct VideoDevice Ark_Vdev;
  347. struct vin_display_outpara Ark_para;
  348. int work_mode;
  349. int Ret;
  350. /* init device */
  351. Ret = V4l2InitDevice(&Ark_Vdev);
  352. if(Ret < 0){
  353. printf("init v4l2 device error.\n");
  354. return -1;
  355. }
  356. printf_command_help();
  357. g_ark_Vdev = &Ark_Vdev;
  358. g_ark_para = &Ark_para;
  359. Ark_para.layer = AUX_LAYER;
  360. if(argc == 1){
  361. work_mode = WORK_MODE_DISPLAY;
  362. }
  363. else if(argc == 2){
  364. if(strcmp("display",argv[1]) == 0)
  365. work_mode = WORK_MODE_DISPLAY;
  366. else if(strcmp("getdata",argv[1]) == 0)
  367. work_mode = WORK_MODE_GETDATA;
  368. else{
  369. printf("cmd = %s, error!\n",argv[1]);
  370. return 0;
  371. }
  372. }
  373. else{
  374. printf("argc=%d, error!\n",argc);
  375. return 0;
  376. }
  377. printf("==>get run cmd: %s %s \n",argv[0],argv[1]);
  378. switch (work_mode){
  379. case WORK_MODE_DISPLAY:
  380. display_demo();
  381. break;
  382. case WORK_MODE_GETDATA:
  383. getdata_demo();
  384. break;
  385. default:
  386. printf("work mode none, exit!\n");
  387. break;
  388. }
  389. /*close device*/
  390. V4l2StopDevice(&Ark_Vdev);
  391. V4l2ExitDevice(&Ark_Vdev);
  392. return 0;
  393. }