void Device::init_formats() { for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) { const VkFormat fmt = static_cast<VkFormat>(f); const VkFormatProperties props = format_properties(fmt); if (props.linearTilingFeatures) { const Format tmp = {fmt, VK_IMAGE_TILING_LINEAR, props.linearTilingFeatures}; formats_.push_back(tmp); } if (props.optimalTilingFeatures) { const Format tmp = {fmt, VK_IMAGE_TILING_OPTIMAL, props.optimalTilingFeatures}; formats_.push_back(tmp); } } EXPECT(!formats_.empty()); }
int main(int argc, char**argv){ //--- create variables and initialize them. init() char* video_device = VIDEO_DEVICE; // 1) -------- 打开设备 /dev/video*: -------- printf("--------------------------------------\n"); printf("Step 1: Open devide using V4L2.\n"); if(argc>1) { video_device=argv[1]; printf(" Select: %s\n", video_device); } // create a handler for /dev/video* device: // 采用阻塞模式打开;若为非阻塞模式:O_RDWR | O_NONBLOCK int fdwr = 0; // for /dev/video* handler if(NON_BLOCK_VIDEO){ fdwr = open(video_device, O_RDWR | O_NONBLOCK); printf(" Open: %s using NON_BLOCK mode\n", video_device); } else{ fdwr = open(video_device, O_RDWR); printf(" Open: %s using BLOCK mode\n", video_device); } assert(fdwr >= 0); printf("--------------------------------------\n"); // 2) -------- 查询设备属性 -------- printf("Step 2: v4l2_capacity check:\n"); struct v4l2_capability vid_caps; memset(&vid_caps, 0, sizeof(vid_caps)); int ret_code = 0; // for checking the V4L2 ioctl() method return status. ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps); assert(ret_code != -1); if(debug==1) print_cap(&vid_caps); // 3) 设置视频的制式和帧格式: printf("Step 3: v4l2_format check/set:\n"); struct v4l2_format vid_format; memset(&vid_format, 0, sizeof(vid_format)); // ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format); if(V4L2_BUF_TYPE == CAPTURE){ vid_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } else{ vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; } vid_format.fmt.pix.width = FRAME_WIDTH; vid_format.fmt.pix.height = FRAME_HEIGHT; vid_format.fmt.pix.pixelformat = FRAME_FORMAT; // size_t framesize; // size_t linewidth; __u32 framesize; __u32 linewidth; if(!format_properties(vid_format.fmt.pix.pixelformat, vid_format.fmt.pix.width, vid_format.fmt.pix.height, &linewidth, &framesize)) { printf("unable to guess correct settings for format '%d'\n", FRAME_FORMAT); } else{ // printf("FrameSize = %d\n", framesize); // printf("linewidth = %d\n", linewidth); } // check: http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L87 vid_format.fmt.pix.field = V4L2_FIELD_NONE; // V4L2_FIELD_ANY // check: http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L185 vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; // vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; vid_format.fmt.pix.sizeimage = framesize; vid_format.fmt.pix.bytesperline = linewidth; if(debug==1) print_format(&vid_format); ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format); assert(ret_code != -1); /* // After set v4l2_format, read it back for double check. // Just to make sure that there is no mis-set and the sys 'secretly' // set the parameters to some 'default' value. if(debug == 1){ ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format); assert(ret_code != -1); printf("after set, get it back to double check:\n"); print_format(&vid_format); } */ /* struct v4l2_fmtdesc vid_desc; vid_desc.index = 0; if(debug==1) print_desc(fdwr,&vid_desc); */ // 4) Check the video standard: // in general the standard is either PAL(720*576) for asian; or NTSC (720*480) for EU. // in our virtual camera scenario, the "v4l2_standard" does not matter much. // 4.1) get the current video standard: printf("Step 4: check the video standard.\n"); //struct v4l2_std_id vid_std_id; // 64 bit length var. struct v4l2_standard vid_std; v4l2_std_id std_id; ret_code = ioctl(fdwr, VIDIOC_G_STD, &std_id); if(ret_code == -1){ printf(" Acquire video standard ERROR:%d\n",ret_code); } else{ memset(&vid_std, 0, sizeof(vid_std)); vid_std.index = 0; // emun from the first one: while(0 == ioctl(fdwr, VIDIOC_ENUMSTD, &vid_std)){ if(vid_std.id & std_id){ printf("Current video standard: %s\n", vid_std.name); } vid_std.index++; } } struct v4l2_streamparm parm; memset(&parm, 0, sizeof(parm)); parm.type =vid_format.type; ret_code = ioctl(fdwr,VIDIOC_G_PARM,&parm); if(ret_code == -1) printf("get parameter failed."); parm.parm.output.timeperframe.numerator = 1000; parm.parm.output.timeperframe.denominator = FPS * parm.parm.output.timeperframe.numerator; if(ioctl(fdwr,VIDIOC_S_PARM,&parm)==0){ struct v4l2_fract *tf = &parm.parm.output.timeperframe; if(!tf->denominator || !tf->numerator) printf("invalid frame rate\n"); else printf(" Frame Rate =%.3f fps\n", 1.0 * tf->denominator/tf->numerator); } // printf(" v4l2_streamparm set/check:\n"); printf(" parm.type(capture=1/output=2) =%d\n", parm.type); printf(" parm.parm.output.capability =0x%4x\n", parm.parm.output.capability); printf("--------------------------------------\n"); // 5) request buffer: printf("Step 5: Request video buffers\n"); struct v4l2_requestbuffers req; req.count = NUM_BUFFER; req.memory = V4L2_MEMORY_MMAP; req.type = vid_format.type; // V4L2_BUF_TYPE_VIDEO_OUTPUT = 2; ret_code = ioctl(fdwr, VIDIOC_REQBUFS, &req); if(debug == 1){ print_requestbuffers(&req); } tp_buffers *data; // malloc() + memset (p, 0, size); data= (struct buffer*) calloc(req.count, sizeof( tp_buffers)); //data=(tp_buffers*) calloc(req.count,sizeof (tp_buffers)); if(!data){ printf ("Out of memory/n"); exit (EXIT_FAILURE); } int index = 0; // set the parameter for every buffer in the buf_arr[], // to make sure they are the same as thos in the 'req'. for(index=0; index<req.count; index++){ memset(&buf_arr[index], 0, sizeof(buf_arr[index])); buf_arr[index].index = index; buf_arr[index].type = vid_format.type; buf_arr[index].memory = req.memory; // should be V4L2_MEMORY_MMAP; // 查询序号为i 的缓冲区,得到其起始物理地址和大小 if(-1 == ioctl (fdwr, VIDIOC_QUERYBUF, &buf_arr[index])) exit(-1); data[index].length = buf_arr[index].length; // 映射内存 data[index].start = mmap(NULL, buf_arr[index].length, PROT_READ | PROT_WRITE, MAP_SHARED, fdwr, buf_arr[index].m.offset); if(MAP_FAILED == data[index].start) exit(-1); // printf(" data[%d].start = 0x%08x", index, data[index].start); printf(" data[%d].length = %d\n", index, data[index].length); // printf("buf.length = %d, framesize = %d ,buf.m.offset = %d\n", // buf_arr[index].length,(int)framesize,buf_arr[index].m.offset); } // 6) assign buffers to the queue. printf("step 6: assign buffers to the queue.\n"); // Queue buffers: for(index = 0; index < req.count; index++){ ioctl(fdwr, VIDIOC_QBUF, &buf_arr[index]); } // STREAM-ON enum v4l2_buf_type type = vid_format.type; ret_code = ioctl(fdwr, VIDIOC_STREAMON, &type); assert(ret_code != -1); // image streaming testing. // need to convert from RGBA format to YUYV format, // and then QBUF to the buffer array. int color = 128; // write AVOS mFrame image to buffers[ind]: const int BENCH = 255; FILE * bmp_fd = NULL; BYTE bmp_header[128]; int bmp_width; int bmp_height; int bmp_header_len; BYTE * rgb = NULL; BYTE * yuv = NULL; char *pic[4]={"1.bmp","2.bmp","3.bmp","4.bmp"}; // char *pic[4]={"5.bmp","5.bmp","5.bmp","5.bmp"}; while(1){ /* // set image/ if(color >= BENCH) color = color % BENCH; else color++; for(index=0; index < req.count; index++){ // memset(data[index].start, color,1179648); memset(data[index].start, 128,1024); memset(data[index].start+1024, 255,vid_format.fmt.pix.sizeimage-1024); }*/ for(index=0; index < req.count; index++){ // printf("%s\n",pic[index]); bmp_fd = fopen(pic[index],"rb"); if(!bmp_fd) { fprintf(stderr,"open bmp file failed!\n"); exit(1); } fgets(bmp_header,sizeof(bmp_header),bmp_fd); bmp_header_len = get_long_value(&bmp_header[10]); bmp_width = get_long_value(&bmp_header[18]); bmp_height = get_long_value(&bmp_header[22]); fclose(bmp_fd); // printf("hearder_len:%d\n",bmp_header_len); // printf("image :%d*%d\n",bmp_width,bmp_height); // printf("width*height*2:%d\n",bmp_width*bmp_height*2); // printf("sizeimage:%d\n",vid_format.fmt.pix.sizeimage); rgb = malloc(bmp_width*bmp_height*sizeof(RGBTRIPLE)+bmp_header_len); if(!rgb) { fprintf(stderr,"rgb malloc failed\n"); } yuv = malloc(bmp_width*bmp_height*sizeof(YUVTRIPLE)); if(!yuv) { fprintf(stderr,"yuv malloc failed\n"); } // fread(rgb,bmp_width*bmp_height*3+bmp_header_len,1,bmp_fd); bmp_fd = fopen(pic[index],"rb"); fread(rgb,bmp_width*bmp_height*sizeof(RGBTRIPLE)+bmp_header_len,1,bmp_fd); bgr2yuv(yuv,(RGBTRIPLE *)(rgb+bmp_header_len),bmp_width,bmp_height); memcpy(data[index].start, yuv,vid_format.fmt.pix.sizeimage); if(rgb) { free(rgb); } if(yuv) { free(yuv); } fclose(bmp_fd); } for(index = 0; index < req.count; index++){ //buf_arr[index].m.offset = 0; // usleep(40000); sleep(1); ioctl(fdwr, VIDIOC_QBUF, &buf_arr[index]); } <<<<<<< HEAD // usleep(1/FPS * 1000 * 1000); usleep(40000); ======= // usleep(40000); >>>>>>> d1308ed6e339365aa9876a4e3f265d74eb880e0a
int main(int argc, char**argv) { struct v4l2_capability vid_caps; struct v4l2_format vid_format; size_t framesize; size_t linewidth; __u8*buffer; __u8*check_buffer; const char*video_device=VIDEO_DEVICE; int fdwr = 0; int ret_code = 0; int i; if(argc>1) { video_device=argv[1]; printf("using output device: %s\n", video_device); } fdwr = open(video_device, O_RDWR); assert(fdwr >= 0); ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps); assert(ret_code != -1); memset(&vid_format, 0, sizeof(vid_format)); ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format); if(debug)print_format(&vid_format); vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; vid_format.fmt.pix.width = FRAME_WIDTH; vid_format.fmt.pix.height = FRAME_HEIGHT; vid_format.fmt.pix.pixelformat = FRAME_FORMAT; vid_format.fmt.pix.sizeimage = framesize; vid_format.fmt.pix.field = V4L2_FIELD_NONE; vid_format.fmt.pix.bytesperline = linewidth; vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; if(debug)print_format(&vid_format); ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format); assert(ret_code != -1); if(debug)printf("frame: format=%d\tsize=%d\n", FRAME_FORMAT, framesize); print_format(&vid_format); if(!format_properties(vid_format.fmt.pix.pixelformat, vid_format.fmt.pix.width, vid_format.fmt.pix.height, &linewidth, &framesize)) { printf("unable to guess correct settings for format '%d'\n", FRAME_FORMAT); } buffer=(__u8*)malloc(sizeof(__u8)*framesize); check_buffer=(__u8*)malloc(sizeof(__u8)*framesize); memset(buffer, 0, framesize); memset(check_buffer, 0, framesize); for (i = 0; i < framesize; ++i) { //buffer[i] = i % 2; check_buffer[i] = 0; } write(fdwr, buffer, framesize); #ifdef CHECK_REREAD do { /* check if we get the same data on output */ int fdr = open(video_device, O_RDONLY); read(fdr, check_buffer, framesize); for (i = 0; i < framesize; ++i) { if (buffer[i] != check_buffer[i]) assert(0); } close(fdr); } while(0); #endif pause(); close(fdwr); free(buffer); free(check_buffer); return 0; }