static int cmd_capability(struct imap_client *imap_client) { struct client *client = &imap_client->common; /* Client is required to send CAPABILITY after STARTTLS, so the capability resp-code workaround checks only pre-STARTTLS CAPABILITY commands. */ if (!client->starttls) imap_client->client_ignores_capability_resp_code = TRUE; client_send_raw(client, t_strconcat( "* CAPABILITY ", get_capability(client), "\r\n", NULL)); client_send_reply(client, IMAP_CMD_REPLY_OK, "Pre-login capabilities listed, post-login capabilities have more."); return 1; }
int main() { int i, ret; // 打开设备 fd=open_device(); // 获取驱动信息 //struct v4l2_capability cap; get_capability(); //获取当前视频设备支持的视频格式 //struct v4l2_fmtdesc fmtdesc; memset(&fmtdesc,0,sizeof(fmtdesc)); get_format(); // 设置视频格式 //struct v4l2_format fmt; //memset在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快的方法 memset(&fmt, 0, sizeof(fmt));//将fmt中的前sizeof(fmt)字节用0替换并返回fmt set_format(); // 请求分配内存 //struct v4l2_requestbuffers reqbuf; request_buf(); // 获取空间,并将其映射到用户空间,然后投放到视频输入队列 //struct v4l2_buffer buf; query_map_qbuf(); // 开始录制 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* 控制命令VIDIOC_STREAMON 功能:启动视频采集命令,应用程序调用VIDIOC_STREAMON启动视频采集命令后,视频设备驱动程序开始采集视频数据,并把采集到的视频数据保存到视频驱动的视频缓冲区中 参数说明:参数类型为V4L2的视频缓冲区类型 enum v4l2_buf_type ; enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, #if 1 //// Experimental //// V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif V4L2_BUF_TYPE_PRIVATE = 0x80, }; 返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,视频设备驱动程序开始采集视频数据,此时应用程序一般通过调用select函数来判断一帧视频数据是否采集完成,当视频设备驱动完成一帧视频数据采集并保存到视频缓冲区中时,select函数返回,应用程序接着可以读取视频数据;否则select函数阻塞直到视频数据采集完成 */ ret = ioctl(fd, VIDIOC_STREAMON, &type); if (ret < 0) { printf("VIDIOC_STREAMON failed (%d)\n", ret); return ret; } // Get frame /* 控制命令VIDIOC_DQBUF 功能:从视频缓冲区的输出队列中取得一个已经保存有一帧视频数据的视频缓冲区 参数说明:参数类型为V4L2缓冲区数据结构类型struct v4l2_buffer; 返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,相应的内核视频缓冲区中保存有当前拍摄到的视频数据,应用程序可以通过访问用户空间来读取该视频数据(前面已经通过调用函数 mmap做了用户空间和内核空间的内存映射). 说明: VIDIOC_DQBUF命令结果, 使从队列删除的缓冲帧信息传给了此buf V4L2_buffer结构体的作用就相当于申请的缓冲帧的代理,找缓冲帧的都要先问问它,通过它来联系缓冲帧,起了中间桥梁的作用 */ ret = ioctl(fd, VIDIOC_DQBUF, &buf);//VIDIOC_DQBUF命令结果, 使从队列删除的缓冲帧信息传给了此buf if (ret < 0) { printf("VIDIOC_DQBUF failed (%d)\n", ret); return ret; } // Process the frame 此时我们需要进行数据格式的改变 store_yuyv(); //对采集的数据进行转变,变换成RGB24模式,然后进行存储 /* (1)开辟出来一段内存区域来存放转换后的数据 (2)循环读取buf内存段的内容,进行转换,转换后放入到新开辟的内存区域中 (3)将新开辟出来的内存区的内容读到文件中 */ printf("********************************************\n"); int n_len; n_len=framebuf[buf.index].length*3/2; newBuf=calloc((unsigned int)n_len,sizeof(unsigned char)); if(!newBuf) { printf("cannot assign the memory !\n"); exit(0); } printf("the information about the new buffer:\n start Address:0x%x,length=%d\n\n",(unsigned int)newBuf,n_len); printf("----------------------------------\n"); //YUYV to RGB starter=(unsigned char *)framebuf[buf.index].start; yuyv2rgb();//还是这个采集的图片的效果比较好 move_noise(); //yuyv2rgb1(); //设置bmp文件的头和bmp文件的一些信息 create_bmp_header(); store_bmp(n_len); // Re-queen buffer ret = ioctl(fd, VIDIOC_QBUF, &buf); if (ret < 0) { printf("VIDIOC_QBUF failed (%d)\n", ret); return ret; } printf("re-queen buffer end\n"); // Release the resource /* 表头文件 #include<unistd.h> #include<sys/mman.h> 定义函数 int munmap(void *start,size_t length); 函数说明 munmap()用来取消参数start所指的映射内存起始地址,参数length则是欲取消的内存大小。当进程结束或利用exec相关函数来执行其他程序时,映射内存会自动解除,但关闭对应的文件描述词时不会解除映射 返回值 如果解除映射成功则返回0,否则返回-1 */ for (i=0; i< 4; i++) { munmap(framebuf[i].start, framebuf[i].length); } //free(starter); printf("free starter end\n"); //free(newBuf); printf("free newBuf end\n"); close(fd); printf("Camera test Done.\n"); return 0; }
int main() { char tent_buf[1024]; char tget_buf[1024]; char* tget_ptr = &tget_buf[0]; /* capabilities. */ const char* cm; const char* sf; const char* cs; int lines; int columns; int ret; ret = tgetent(tent_buf, getenv("TERM")); if( ret != 1 ) { printf("tgetent failed (%d).\n", ret); return 1; } lines = tgetnum("li"); columns = tgetnum("co"); printf("lines (li) = %d\n", lines); printf("columns (co) = %d\n", columns); if( !get_capability("cursor move", "cm", &cm, &tget_ptr) ) { return 1; } if( !get_capability("scroll forward", "sf", &sf, &tget_ptr) ) { return 1; } if( !get_capability("change scroll region", "cs", &cs, &tget_ptr) ) { return 1; } { const char* x; get_capability("cursor position format", "u6", &x, &tget_ptr); get_capability("query cursor position", "u7", &x, &tget_ptr); } /* sample. */ { const char* o = tgoto(cs, 5, 3); printf("change scroll region (5,3) = "); print_text(o); printf("\n"); } if( lines < REGION_ROWS + 2 ) { printf("this program requires at least %d lines, but got %d lines.\n", REGION_ROWS + 2, lines); return 1; } { int i; int top = lines - (REGION_ROWS + 2); int first = top + 1; int last = first + REGION_ROWS - 1; printf("\n"); printf("change scroll region to (%d,%d)\n", first, last); printf("NOTE: use reset(1) if console seems broken.\n"); /* move cursor to bottom-left corner and draw frame. */ tputs(tgoto(cm, 0, lines-1), 1, putchar); printf("line.%d ----\n", top + 0); for( i=1; i<=REGION_ROWS; ++i ) { printf("line.%d\n", top + i); } printf("line.%d ----", top + (REGION_ROWS + 2) - 1); fflush(stdout); /* change scroll region (last,first) and move cursor inside. */ tputs(tgoto(cs, last, first), 1, putchar); tputs(tgoto(cm, 0, first), 1, putchar); sleep(1); for( i=1; i<=5; ++i ) { if( i != 1 ) { printf("\n"); } printf("test %d/5.", i); fflush(stdout); sleep(1); } /* restore scroll region and cursor position. */ tputs(tgoto(cs, lines-1, 0), 1, putchar); tputs(tgoto(cm, 0, lines-1), 1, putchar); /* and scroll down. */ tputs(sf, 1, putchar); sleep(1); } return 0; }