학습자료(~2017)/리눅스

Camera driver(V4L2) 에 관한 간략한 설명

단세포소년 2011. 4. 15. 19:47
반응형

Camera driver(V4L2) 에 관한 간략한 설명
원본 : Camera driver(V4L2) 에 관한 간략한 설명 - MIZI Wiki by 구글캐쉬

V4L2 프로그램 구조(카메라 드라이버와 관련된)
- 쓰는 파일오퍼레이션의 종류

mmap() - VIDIOC_REQBUFS를 통해 할당한 버퍼를 mmap을 이용해 유저 공간에 맵핑해서 사용. 원래 read(), mmap(), user pointer 세 가지 경우가 있으나 일단 지금은 mmap()의 경우만 지원함.
ioctl()
poll()

- ioctl operation의 종류

  1. VIDIOC_QUERYCAP (Query Capability) : 드라이버가 할 수 있는 정도를 유저가 요청
  2. VIDIOC_G_FMT (Get format) : 현재 드라이버에서 사용하는 format을 유저가 요청
  3. VIDIOC_S_FMT (Set format) : 드라이버에서 사용할 format을 유저가 지정
  4. VIDIOC_STREAMON (stream on) : 카메라의 스트림을 켬
  5. VIDIOC_STREAMOFF (stream off) : 카메라의 스트림을 끔
  6. VIDIOC_QUERYBUF (query buffer) : 특정 버퍼 정보 요청. offset값을 얻을때 사용.
  7. VIDIOC_QBUF (queue buffer) : 새로운 프레임을 달라고 드라이버에 요청
  8. VIDIOC_DQBUF (dequeue buffer) : 새로운 프레임을 가지고 감
  9. VIDIOC_REQBUFS (request buffers) : 버퍼를 할당하라고 드라이버에 요구함



- 흐름

  1. .camera device를 open
  2. .VIDIOC_QUERYCAP을 통해 Capture가 가능한지(V4L2_CAP_VIDEO_CAPTURE), 스트리밍 방식인지(V4L2_CAP_STREAMING) 판별
  3. .VIDIOC_S_FMT를 통해 가지고 올 카메라 데이터의 포맷을 결정(버퍼 타입, 해상도, 컬러스페이스 등, 원래 픽셀 포맷도 결정해야 하나 일단은 이에 대해서는 지원하지 않음)
  4. .VIDIOC_REQBUFS를 통해 버퍼를 결정(버퍼의 개수, 버퍼 타입, read, mmap, user pointer 방식 선택)
  5. .VIDIOC_QUERYBUF를 통해, 원하는 버퍼의 인덱스를 넘겨주고 그 버퍼의 오프셋 정보를 가져옴. 이 정보를 이용해 mmap()을 통해 버퍼를 유저공간에 맵핑함. 버퍼에 할당하는 공간만큼 메모리를 할당받아서( calloc(req.count, sizeof(*buffers)) ) 각각의 버퍼에 대해 따로 mmap()을 통해 공간을 할당함. 즉 버퍼가 4개라면 0번 버퍼의 정보를 얻기 위해 VIDIOC_QUERYBUF, 인덱스는 0, ioctl을 실행하고 그 결과 넘어온 버퍼의 offset값에 따라 mmap을 통해 그 버퍼에 대한 공간을 맵핑. 1번, 2번, 3번에 대해서도 똑같은 작업을 반복함. VIDIOC_QUERYBUF와 mmap()이 각각 네 번씩 실행.
  6. .VIDIOC_QBUF를 통해 프레임을 달라고 요청
  7. .VIDIOC_STREAMON을 통해 스트림을 켬.
  8. .polling을 통해 새 프레임이 들어오기를 기다림.
  9. .새 프레임이 들어오면 DQBUF를 통해 새로 들어온 프레임의 인덱스(!)를 가져옴.
  10. .가져온 인덱스를 통해 mmap된 메모리 공간에서 이미지 데이터를 가져옴.
  11. .다시 QBUF를 통해 프레임을 달라고 요청. 이 작업을 반복해서 데이터를 계속적으로 가져감.
  12. .VIDIOC_STREAMOFF를 통해 스트림을 끔. munmap을 통해 메모리를 해제.
  13. .camera device를 close
반응형