main.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. //#define DEBUG
  13. #ifdef DEBUG
  14. #define V4L2_DBG(...) printf(__VA_ARGS__)
  15. #else
  16. #define V4L2_DBG(...)
  17. #endif
  18. #define BUF_NUM 8
  19. #define DISPLAY 1
  20. #define GETDATA 2
  21. struct VideoDevice {
  22. int Vfd;
  23. int VpixelFormat;
  24. int VideoBufCurIndex;
  25. int VideoBufCnt;
  26. int VideoBufMaxLen;
  27. int src_width;
  28. int src_height;
  29. unsigned char *Cam_vbuf[BUF_NUM]; //video data virtual address
  30. unsigned char* Video_Data; //video data physical address
  31. };
  32. enum work_mode {
  33. WORK_MODE_GETDATA,
  34. WORK_MODE_END,
  35. };
  36. enum dvr_source {
  37. DVR_SOURCE_CAMERA,
  38. DVR_SOURCE_AUX,
  39. DVR_SOURCE_DVD,
  40. };
  41. struct VideoDevice *g_ark_Vdev;
  42. static pthread_t v4l2_work_id;
  43. int t_cmd;
  44. /* This function first makes the query judgmentThe space is then allocated and queued */
  45. static int V4l2InitDevice(struct VideoDevice *Vdec)
  46. {
  47. struct v4l2_fmtdesc tFmtDesc;
  48. struct v4l2_requestbuffers tV4l2buf;
  49. struct v4l2_format tV4l2Fmt;
  50. struct v4l2_buffer tV4l2Buf;
  51. struct v4l2_capability tV4l2Cap;
  52. struct v4l2_input tV4l2inp;
  53. int Fd,Ret,Error,i;
  54. Fd = open("/dev/video0",O_RDWR);
  55. if( Fd < 0 )
  56. {
  57. V4L2_DBG("open error.\n");
  58. return -1;
  59. }
  60. Vdec->Vfd = Fd;
  61. memset(&tV4l2Cap, 0, sizeof(struct v4l2_capability));
  62. Error = ioctl(Fd, VIDIOC_QUERYCAP, &tV4l2Cap);
  63. if (Error) {
  64. V4L2_DBG("unable to query device.\n");
  65. return -1;
  66. }
  67. if (!(tV4l2Cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
  68. {
  69. V4L2_DBG("device is not a video capture device.\n");
  70. return -1;
  71. }
  72. tFmtDesc.index = 0;
  73. tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74. ioctl(Fd,VIDIOC_ENUM_FMT,&tFmtDesc);
  75. Vdec->VpixelFormat = tFmtDesc.pixelformat;
  76. memset(&tV4l2Fmt, 0, sizeof(struct v4l2_format));
  77. tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  78. tV4l2Fmt.fmt.pix.pixelformat = Vdec->VpixelFormat;
  79. tV4l2Fmt.fmt.pix.width = Vdec->src_width;
  80. tV4l2Fmt.fmt.pix.height = Vdec->src_height;
  81. tV4l2Fmt.fmt.pix.field = V4L2_FIELD_ANY;
  82. Ret = ioctl(Fd, VIDIOC_S_FMT, &tV4l2Fmt);
  83. if (Ret)
  84. V4L2_DBG("Unable to set format\n");
  85. tV4l2inp.index = DVR_SOURCE_CAMERA; //set channel
  86. Ret = ioctl(Fd, VIDIOC_S_INPUT, &tV4l2inp.index);
  87. if (Ret)
  88. V4L2_DBG("Unable to set input\n");
  89. tV4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  90. tV4l2buf.memory = 1;
  91. tV4l2buf.count = BUF_NUM;
  92. ioctl(Fd,VIDIOC_REQBUFS,&tV4l2buf);
  93. Vdec->VideoBufCnt = tV4l2buf.count;
  94. for(i =0; i<Vdec->VideoBufCnt; i++)
  95. {
  96. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  97. tV4l2Buf.index = i;
  98. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  99. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  100. ioctl(Fd,VIDIOC_QUERYBUF,&tV4l2Buf);
  101. Vdec->VideoBufMaxLen = tV4l2Buf.length;
  102. V4L2_DBG("Vdec->VideoBufMaxLen = %d \n",Vdec->VideoBufMaxLen);
  103. /* 0 is start anywhere */
  104. Vdec->Cam_vbuf[i] = mmap(0,tV4l2Buf.length, PROT_READ, MAP_SHARED,Fd,tV4l2Buf.m.offset);
  105. if (Vdec->Cam_vbuf[i] == MAP_FAILED)
  106. {
  107. V4L2_DBG("Unable to map buffer\n");
  108. }
  109. }
  110. for(i =0; i<Vdec->VideoBufCnt; i++)
  111. {
  112. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  113. tV4l2Buf.index = i;
  114. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  115. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  116. Error = ioctl(Fd, VIDIOC_QBUF, &tV4l2Buf);
  117. if (Error)
  118. {
  119. V4L2_DBG("Unable to queue buffer.\n");
  120. }
  121. }
  122. return 0;
  123. }
  124. static int V4l2ExitDevice(struct VideoDevice *Vdec)
  125. {
  126. int i;
  127. for (i = 0; i < Vdec->VideoBufCnt; i++)
  128. {
  129. if (Vdec->Cam_vbuf[i])
  130. {
  131. munmap(Vdec->Cam_vbuf[i], Vdec->VideoBufMaxLen);
  132. Vdec->Cam_vbuf[i] = NULL;
  133. }
  134. }
  135. close(Vdec->Vfd);
  136. return 0;
  137. }
  138. static int V4l2GetDataForStreaming(struct VideoDevice *Vdec)
  139. {
  140. struct pollfd Fds[1];
  141. int Ret;
  142. struct v4l2_buffer tV4l2Buf;
  143. /*wait data*/
  144. Fds[0].fd = Vdec->Vfd;
  145. Fds[0].events = POLLIN;
  146. Ret = poll(Fds, 1, -1);
  147. if (Ret <= 0)
  148. {
  149. V4L2_DBG("poll error!\n");
  150. return -1;
  151. }
  152. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  153. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  154. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  155. Ret = ioctl(Vdec->Vfd, VIDIOC_DQBUF, &tV4l2Buf);
  156. if (Ret < 0)
  157. {
  158. V4L2_DBG("Unable to dequeue buffer.\n");
  159. return -1;
  160. }
  161. Vdec->VideoBufCurIndex = tV4l2Buf.index;
  162. Vdec->VideoBufMaxLen = tV4l2Buf.length;
  163. V4L2_DBG("DQBUF-->app get buf index : %d, buf : %p\n",tV4l2Buf.index,tV4l2Buf.m.offset);
  164. /*get physics data*/
  165. Vdec->Video_Data = tV4l2Buf.m.offset;
  166. return 0;
  167. }
  168. static int V4l2PutDataForStreaming(struct VideoDevice *Vdec)
  169. {
  170. struct v4l2_buffer tV4l2Buf;
  171. int Error;
  172. memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
  173. tV4l2Buf.index = Vdec->VideoBufCurIndex;
  174. tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  175. tV4l2Buf.memory = V4L2_MEMORY_MMAP;
  176. V4L2_DBG("QBUF -->app put buf index : %d\n",tV4l2Buf.index);
  177. /*Put the extracted buf in the queue*/
  178. Error = ioctl(Vdec->Vfd, VIDIOC_QBUF, &tV4l2Buf);
  179. if (Error)
  180. {
  181. V4L2_DBG("Unable to queue buffer.\n");
  182. return -1;
  183. }
  184. return 0;
  185. }
  186. static int V4l2StartDevice(struct VideoDevice *Vdec)
  187. {
  188. int Type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  189. int Error;
  190. Error = ioctl(Vdec->Vfd, VIDIOC_STREAMON, &Type);
  191. if (Error)
  192. {
  193. V4L2_DBG("Unable to start capture.\n");
  194. return -1;
  195. }
  196. return 0;
  197. }
  198. static int V4l2StopDevice(struct VideoDevice *Vdec)
  199. {
  200. int Type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  201. int Error;
  202. Error = ioctl(Vdec->Vfd, VIDIOC_STREAMOFF, &Type);
  203. if (Error)
  204. {
  205. V4L2_DBG("Unable to stop capture.\n");
  206. return -1;
  207. }
  208. return 0;
  209. }
  210. static void* display_work_thread(void *param)
  211. {
  212. int fd_t,Ret,i;
  213. if(t_cmd == GETDATA){
  214. fd_t = open("stream.yuv",O_RDWR|O_CREAT);
  215. if(fd_t < 0){
  216. V4L2_DBG("open error.\n");
  217. return 0;
  218. }
  219. while(1){
  220. V4l2GetDataForStreaming(g_ark_Vdev);
  221. Ret = write(fd_t,g_ark_Vdev->Cam_vbuf[g_ark_Vdev->VideoBufCurIndex],g_ark_Vdev->VideoBufMaxLen);
  222. V4l2PutDataForStreaming(g_ark_Vdev);
  223. }
  224. }
  225. else{
  226. V4L2_DBG("mode error t_cmd = %d.\n",t_cmd);
  227. return 0;
  228. }
  229. }
  230. void display_video_start(void)
  231. {
  232. V4L2_DBG("video_start cmd = %d \n",t_cmd);
  233. pthread_create(&v4l2_work_id, NULL, display_work_thread,NULL);
  234. }
  235. int getdata_demo(void)
  236. {
  237. char flag_quit[10];
  238. int Ret;
  239. t_cmd = GETDATA;
  240. /* start device && open display layer*/
  241. Ret = V4l2StartDevice(g_ark_Vdev);
  242. if(Ret < 0){
  243. V4L2_DBG("start v4l2 device error.\n");
  244. return 0;
  245. }
  246. display_video_start();
  247. while(1){
  248. usleep(100*1000);
  249. }
  250. }
  251. static void printf_command_help(void)
  252. {
  253. printf("\n");
  254. printf("***********************command help*****************************\n");
  255. printf("* *\n");
  256. printf("*run cmd: demo-v4l2 [width] [height] *\n");
  257. printf("* *\n");
  258. printf("* *\n");
  259. printf("*example: *\n");
  260. printf("* cvbs : ntsc demo-v4l2 720 240 *\n");
  261. printf("* pal demo-v4l2 720 288 *\n");
  262. printf("* 720p : demo-v4l2 1280 720 *\n");
  263. printf("* 1080p : demo-v4l2 1920 1080 *\n");
  264. printf("* *\n");
  265. printf("****************************************************************\n");
  266. printf("\n");
  267. }
  268. int main(int argc, char *argv[])
  269. {
  270. struct VideoDevice Ark_Vdev;
  271. int work_mode;
  272. int Ret,width,height;
  273. if(argc == 1){
  274. printf("cmd error.\n");
  275. printf_command_help();
  276. return -1;
  277. }
  278. width = atoi(argv[1]);
  279. height = atoi(argv[2]);
  280. Ark_Vdev.src_width = width;
  281. Ark_Vdev.src_height = height;
  282. /* init device */
  283. Ret = V4l2InitDevice(&Ark_Vdev);
  284. if(Ret < 0){
  285. V4L2_DBG("init v4l2 device error.\n");
  286. return -1;
  287. }
  288. g_ark_Vdev = &Ark_Vdev;
  289. work_mode = WORK_MODE_GETDATA;
  290. switch (work_mode){
  291. case WORK_MODE_GETDATA:
  292. getdata_demo();
  293. break;
  294. default:
  295. V4L2_DBG("work mode none, exit!\n");
  296. break;
  297. }
  298. /*close device*/
  299. V4l2StopDevice(&Ark_Vdev);
  300. V4l2ExitDevice(&Ark_Vdev);
  301. printf("V4l2ExitDevice done.\n");
  302. return 0;
  303. }