//--------- Begin of function UnitCaravan::disp_info ---------// // void UnitCaravan::disp_info(int refreshFlag) { char *nationPict = image_spict.get_ptr("V_COLCOD"); vga.active_buf->put_bitmap_trans_remap_decompress(INFO_X1+16, INFO_Y1-28, nationPict, game.get_color_remap_table(nation_recno, 0) ); vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("CARABASE") ); // disp_basic_info(INFO_Y1, refreshFlag); disp_unit_profile(10, refreshFlag); if( !config.show_ai_info && !is_own() ) return; disp_stop(INFO_Y1+54, refreshFlag); // display auto/manual button button_duplicate_caravan.create( INFO_X1+13, INFO_Y1+281, 'A', "CARACOPY" ); // manual button button_auto_trade_group[0].create( INFO_X1+BUTTON_DISTANCE+13, INFO_Y1+235, INFO_X1+BUTTON_DISTANCE+56-1, INFO_Y1+280, i_disp_auto_trade_button, ButtonCustomPara(this, 0), 0 ); // auto button button_auto_trade_group[1].create( INFO_X1+13, INFO_Y1+235, INFO_X1+56-1, INFO_Y1+280, i_disp_auto_trade_button, ButtonCustomPara(this, 1), 0 ); button_auto_trade_group[1].set_help_code( "AUTOPICK" ); button_auto_trade_group.paint( default_market_trade_mode ); button_duplicate_caravan.enable_flag = can_duplicate_caravan(); button_duplicate_caravan.paint(); disp_goods(INFO_Y1+235, refreshFlag); }
int main(int argc, char* argv[]) { int i; int key_fd = -1; struct input_event data; struct sigaction sigact; memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = handle_int; //format=V4L2_PIX_FMT_NV12; //V4L2_PIX_FMT_NV16 format = V4L2_PIX_FMT_NV12; disp_format=DISP_FORMAT_YUV420; //DISP_FORMAT_YUV422 disp_seq=DISP_SEQ_UVUV; struct v4l2_format fmt; struct v4l2_format fmt_priv; printf("*********************\n"); printf("TVD demo start!\n"); printf("Press KEY_ESC for exit\n"); printf("*********************\n"); /*if((key_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK)) < 0){//key: linux=event0, android=event2 printf("open event fail!\n"); return -1; }*/ fd = open ("/dev/video1", O_RDWR /* required */ | O_NONBLOCK, 0); int ret = -1; CLEAR (fmt_priv); fmt_priv.type = V4L2_BUF_TYPE_PRIVATE; fmt_priv.fmt.raw_data[0] =0;//interface fmt_priv.fmt.raw_data[1] =0;//system fmt_priv.fmt.raw_data[2] =0;//format 1=mb, for test only fmt_priv.fmt.raw_data[8] =2;//row fmt_priv.fmt.raw_data[9] =2;//column fmt_priv.fmt.raw_data[10] =1;//channel_index fmt_priv.fmt.raw_data[11] =2;//channel_index fmt_priv.fmt.raw_data[12] =3;//channel_index fmt_priv.fmt.raw_data[13] =4;//channel_index if (-1 == ioctl (fd, VIDIOC_S_FMT, &fmt_priv)) //设置自定义 { printf("VIDIOC_S_FMT error! a\n"); ret = -1; return ret; } // CLEAR (fmt); // fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // fmt.fmt.pix.width = 720*fmt_priv.fmt.raw_data[8];//720; // fmt.fmt.pix.height = 480*fmt_priv.fmt.raw_data[9];//576;//480; // fmt.fmt.pix.pixelformat = format;//V4L2_PIX_FMT_YUV422P;//V4L2_PIX_FMT_NV12;//V4L2_PIX_FMT_YUYV; // fmt.fmt.pix.field = V4L2_FIELD_NONE; // if (-1 == ioctl (fd, VIDIOC_S_FMT, &fmt)) //设置图像格式 // { // printf("VIDIOC_S_FMT error! b\n"); // ret = -1; // return ret; // } disp_mode=fmt_priv.fmt.raw_data[2]?DISP_MOD_MB_UV_COMBINED:DISP_MOD_NON_MB_UV_COMBINED;//DISP_MOD_NON_MB_UV_COMBINED DISP_MOD_MB_UV_COMBINED disp_size.width = fmt_priv.fmt.raw_data[8]*(fmt_priv.fmt.raw_data[2]?704:720);//width disp_size.height = fmt_priv.fmt.raw_data[9]*(fmt_priv.fmt.raw_data[1]?576:480);//height printf("disp_size.width=%d\n", disp_size.width); printf("disp_size.height=%d\n", disp_size.height); usleep(100000);//delay 100ms if you want to check the status after set fmt CLEAR (fmt_priv); fmt_priv.type = V4L2_BUF_TYPE_PRIVATE; if (-1 == ioctl (fd, VIDIOC_G_FMT, &fmt_priv)) //设置自定义 { printf("VIDIOC_G_FMT error! a\n"); ret = -1; return ret; } printf("interface=%d\n", fmt_priv.fmt.raw_data[0]); printf("system=%d\n", fmt_priv.fmt.raw_data[1]); printf("format=%d\n", fmt_priv.fmt.raw_data[2]); printf("row=%d\n", fmt_priv.fmt.raw_data[8]); printf("column=%d\n", fmt_priv.fmt.raw_data[9]); printf("channel_index[0]=%d\n", fmt_priv.fmt.raw_data[10]); printf("channel_index[1]=%d\n", fmt_priv.fmt.raw_data[11]); printf("channel_index[2]=%d\n", fmt_priv.fmt.raw_data[12]); printf("channel_index[3]=%d\n", fmt_priv.fmt.raw_data[13]); printf("status[0]=%d\n", fmt_priv.fmt.raw_data[16]); printf("status[1]=%d\n", fmt_priv.fmt.raw_data[17]); printf("status[2]=%d\n", fmt_priv.fmt.raw_data[18]); printf("status[3]=%d\n", fmt_priv.fmt.raw_data[19]); struct v4l2_requestbuffers req; CLEAR (req); req.count = 5; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; ioctl (fd, VIDIOC_REQBUFS, &req); //申请缓冲,count是申请的数量,注意,释放缓冲实际在VIDIOC_STREAMOFF内完成了。 buffers = calloc (req.count, sizeof (*buffers));//内存中建立对应空间 for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { struct v4l2_buffer buf; //驱动中的一帧 CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf)) //映射用户空间 printf ("VIDIOC_QUERYBUF error\n"); buffers[n_buffers].length = buf.length; buffers[n_buffers].start = mmap (NULL /* start anywhere */, //通过mmap建立映射关系 buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd, buf.m.offset); printf("MMAP: %p OFF: %p\n", buffers[n_buffers].start, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) printf ("mmap failed\n"); } for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == ioctl (fd, VIDIOC_QBUF, &buf))//申请到的缓冲进入列队 printf ("VIDIOC_QBUF failed\n"); } #ifdef DISPLAY disp_init(disp_size.width,disp_size.height); disp_start(); disp_on(); #endif enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (fd, VIDIOC_STREAMON, &type)) //开始捕捉图像数据 printf ("VIDIOC_STREAMON failed\n"); sigaction(SIGINT, &sigact, NULL); while(!quit) { read(key_fd, &data, sizeof(data)); if( (data.type == EV_KEY)&& (data.code == KEY_ESC)&& (data.value == 1) ){ quit = 1; } CLEAR (fmt_priv); fmt_priv.type = V4L2_BUF_TYPE_PRIVATE; if (-1 == ioctl (fd, VIDIOC_G_FMT, &fmt_priv)) //监视状态 { printf("VIDIOC_G_FMT error! a\n"); ret = -1; return ret; } //printf("status=0x%02x\n", fmt_priv.fmt.raw_data[16]); for (;;) //这一段涉及到异步IO { fd_set fds; struct timeval tv; int r; FD_ZERO (&fds);//将指定的文件描述符集清空 FD_SET (fd, &fds);//在文件描述符集合中增加一个新的文件描述符 /* Timeout. */ tv.tv_sec = 2; tv.tv_usec = 0; r = select (fd + 1, &fds, NULL, NULL, &tv);//判断是否可读(即摄像头是否准备好),tv是定时 if (-1 == r) { if (EINTR == errno) continue; printf ("select err\n"); } if (0 == r) { fprintf (stderr, "select timeout\n"); //exit (EXIT_FAILURE); //goto close; } if (read_frame ())//如果可读,执行read_frame ()函数,并跳出循环 break; } } close: if (-1 == ioctl (fd, VIDIOC_STREAMOFF, &type)) //停止捕捉图像数据,注意,此动作同时会释放VIDIOC_REQBUFS申请的缓冲 printf ("VIDIOC_STREAMOFF failed\n"); unmap: for (i = 0; i < n_buffers; ++i) { if (-1 == munmap (buffers[i].start, buffers[i].length)) { printf ("munmap error"); } } disp_stop(); disp_exit(); close (fd); printf("TVD demo bye!\n"); return 0; }