標籤:集中 data ice blank init string 出圖 put roi
轉自:8745577
在移植android hal的過程中,移植的首要任務是要確保驅動完好,camera是屬於字元裝置,但是對於其測試代碼的編寫就不像一般的驅動那麼簡單啦,因為camera的測試代碼一定是要用v4l2 api,所以接下來就是介紹我們寫camera的測試代碼的流程。
1,開啟裝置
[c] view plain copy
-
- static int open_device(char *dev_name)
- {
- assert(dev_name);
-
- int fd = -1;
-
- fd = open(dev_name , O_RDWR);
- if( -1 == fd )
- {
- MYLOGD("open %s fail: %s\n", dev_name, strerror (errno));
- exit(EXIT_FAILURE);
- }
-
- MYLOGD("the fd of %s is %d ", dev_name, fd);
- return fd;
-
- }
2,初始化camera,設定camera輸出映像的格式
[c] view plain copy
- static int init_cam_device(int dev_fd)
- {
- int ret = -1;
- int input_index;
-
- //ret = fimc_v4l2_querycap(dev_fd);
- //assert(ret == 0);
- //擷取到輸入源通道
- input_index = cam_v4l2_enuminput(dev_fd);
- assert(input_index == 0);
-
- ret = cam_v4l2_s_input(dev_fd, input_index);
- assert(ret == 0);
-
- MYLOGD("VIDIOC_S_FMT start... dev_fd = %d\n", dev_fd);
-
- ret = cam_v4l2_s_format(dev_fd, IMAGE_HEIGHT, IMAGE_WIDTH, V4L2_PIX_FMT_YUYV);
- assert(ret == 0);
-
- ret = cam_v4l2_g_fmt(dev_fd);
- assert(ret == 0);
-
- init_cam_mmap(dev_fd);
-
- return 1;
-
- }
4,向核心申請buffer,並將buffer映射mmap到引用空間
struct buffer
{
void *start; //mmap後的地址;
size_t length//大小;
}user_buffers[4]; //用於記錄將核心buffer映射mmap到使用者空間的地址和大小
//申請4個buffer
cam_v4l2_reqbuf(dev_fd, 4);
//查詢申請到的buffer資訊,比如每個buffer的其實位置和大小
cam_v4l2_querybuf(dev_fd, &buf, buf_index);
//將buffer映射到使用者空間
user_buffers[buf_index].length = buf.length;
user_buffers[buf_index].start = mmap(NULL buf.length,
PROT_READ | PROT_WRITE /* required */ ,
MAP_SHARED /* recommended */ ,
dev_fd, buf.m.offset);
注釋 : NULL: /* start anywhere */
buf.length: buffer在核心的地址
buf.m.offset:核心中的buffer大小
5,將所有的buffer全部放到迴圈工作隊列中,集中管理
for (i = 0; i < max_buffers; ++i)
{
cam_v4l2_qbuf(dev_fd, i);
}
6,開始擷取映像:
ioctl(dev_fd, VIDIOC_STREAMON, &type);
7,通過select來監控camera資料是否準備好
FD_ZERO (&rd_set);
FD_SET (dev_fd, &rd_set);
ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);
if(FD_ISSET(dev_fd, &rd_set))//如果camera準備好,就可以去讀資料了
read_frame(dev_fd)
8,read_frame(dev_fd)的實現:
//select僅僅是知道有資料可以讀了,但是在多個buffer中,
//不知道是哪個buffer準備好了,所以將準備好的buffer出隊列,從而知道buffer的編號
int index = cam_v4l2_dqbuf(dev_fd);
//將buffer中的yuv420資料轉換成rgb565,
//因為lcd是沒辦法顯示yuv的,所以需要將yuv轉換成rgb565
yuyv_to_rgb(src_address, data_buf);
//將轉換好的rgb565資料方到framebuffer中去顯示
show_rgb565_img(data_buf, LCD_WIDTH, LCD_HEIGHT);
這個過程僅僅是將一個流程寫下來了,每個函數都是封裝了一次,沒辦法一一去寫出來,
所以我會將原始碼檔案上傳,給大家去下載。包含Android.mk
可以到這個連結下載:
http://download.csdn.net/detail/ldswfun/5208766
同時附上一些圖片讓大家去理解這個過程
android網路攝影機(camera)之 v4l2的c測試代碼【轉】