main.c 12 KB

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