ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [리눅스 커널] V4L2_FIELD_* & V4L2_PIX_FMT_* & MEDIA_BUS_FMT_*
    Linux/kernel 2024. 9. 22. 18:42

    글의 참고

    -

    - https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/subdev-formats.html#bayer-patterns

    -


    글의 전제

    - 밑줄로 작성된 글은 강조 표시를 의미한다.

    - 그림 출처는 항시 그림 아래에 표시했다.


    글의 내용

    - V4L2_FIELD_*

    " V4L2_FIELD_* 는 프레임(Frame) 이 어떤 포맷(Format) 으로 전송되는지를 나타낸다. 예를 들어, 1 개의 이미지가 전송될 때 Top Field 와 Bottom Field 가 번갈아 가면서 전송되는지, 모든 Top Field 가 먼저 전송되고 Bottom Field 가 전송되는지 등을 나타낸다. 참고로, Frame 과 Field 는 다른 용어다. 예를 들어, interlaced video 같은 경우 하나의 image 를 2 개의 fields 로 분리할 수 있다(홀수 fields 들만 갖는 image & 짝수 fields 들만 갖는 image). interlace 에 대한 내용은 이 글을 참고하자.

     

    V4L2_FIELD_ANY 0  
    V4L2_FIELD_NONE 1 images 들이 progressive format 일 때를 의미한다.
    V4L2_FIELD_TOP 2 1 개의 image 에 top(aka odd) field 만 포함되어 있다.
    V4L2_FIELD_BOTTOM 3 1 개의 image 에 bottom(aka even) field 만 포함되어 있다.
    V4L2_FIELD_INTERLACED 4 1 개의 image 에 2 개의 fields 들이 모두 포함된다. fields 들이 전달되는 순서는 비디오 표준에 따라 다르다. 예를 들어, M/NTSC 같은 경우는 bottom filed 를 먼저 전달한다. 그러나 다른 비디오 표준들은(BG/PAL) top field 를 먼저 전달한다.
    V4L2_FIELD_SEQ_TB 5 1 개의 image 에 2 개의 flelds 들이 모두 포함된다. 순서는 top fields 들이 먼저 모두 저장되고 그 다음 bottom fields 들이 저장된다.
    V4L2_FIELD_SEQ_BT 6 1 개의 image 에 2 개의 flelds 가 모두 포함된다. 순서는 bottom fields 들이 먼저 모두 저장되고 그 다음 top fields 들이 저장된다.
    V4L2_FIELD_ALTERNATE 7  
    V4L2_FIELD_INTERLACED_TB 8 1 개의 image 에 2 개의 flelds 가 모두 포함된다. 순서는 top field, bottom field, top field ... 순으로 image 가 구성된다.
    V4L2_FIELD_INTERLACED_BT 9 1 개의 image 에 2 개의 flelds 가 모두 포함된다. 순서는 bottom field, top field, bottom field ... 순으로 image 가 구성된

     

     

    " V4L2_FIELD_* 는 FRAME 을 구성하는 FIELD 들이 어떤 순서로 전송되는지를 의미한다. 아래 그림을 보자. 아래 그림에서 제일 첫 번째 행을 보면 총 6 개의 color 가 전달된다. 그 아래에 있는 V4L2_FIELD_TOP 이 사용되면 ODD(홀수) FIELD 만 전달되는 것을 의미한다. 아 그림에서 홀 수 번째 FIELD 만 전달될 경우 RED, GREEN, RED 순으로 FIELD 가 날라간다. 그리고 첫 번째 행을 기준으로 V4L2_FIELD_BOTTOM 은EVEN(짝수) FIELD 들을 나태낸다. 첫 번째 행에서 짝 수 번째 FIELD 만 빼면 BLUE, YELLOW, BLUE 순으로 FIELD 가 날라간다.

     


    https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/field-order.html

     

     

    " 위 케이스는 TOP FIELD 가 먼저 전달되는 경우를 의미한다. 만약 BOTTOM FIELD 전달된다면 다음과 같다.

     


    https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/field-order.html

     

     

    " 리눅스 커널에서 제공하는 V4L2_FIELD_NONE 은 progressive scan 을 의미한다.  

     

     

     

     

    - V4L2_PIX_FMT_*

    " pixel 은 color 를 표현하기 위한 하나의 단위다. 그렇다면 pixel format 이란 무엇일까? pixel 은 color 를 나타낸다고 했으니 pixel format 은 color 를 표현하기 위한 방법이라고 보면 된다. 그런데 color 를 표현하기 위한 대표적인 2 가지 방법이 있다.

     

    1. RGB
    2. YUV

     

     

    " 먼저 RGB 부터 보자. RGB 는 color 를 표현하기 위해 삼원색(RGB) 를 모두 사용하는 format 이다. 그래서 YUV 비해 color 를 표현하는데 더 많은 데이터를 사용하지만 그 만큼 color 를 더 잘 표현한다는 특징이 있다. V4L2 에서 정의된 몇 가지 RGB Color Format 을 가져와봤다. 참고로 Fourcc 는 `Four Character Code` 의 약자로 `4개의 바이크 코드` 라는 뜻으로 데이터 형식을 나타낸다. 예를 들어, 아래 표에서 `AR12` 는 `ARGB444` 의 약자라고 보면 된다. 

    Pixel Format by V4L2 Fourcc Content
    V4L2_PIX_FMT_RGB332 RGB1 RGB332 는 1 개의 pixel 을 표현하는데 0bRRRGGGBB 를 사용한다는 뜻이다. 즉, 한 개의 픽셀당 8-bit 를 사용하게 된다.
    V4L2_PIX_FMT_ARGB444 AR12 ARGB4444 는 1 개의 pixel 을 표현하는데 0bAAAARRRRGGGGBBBB 를 사용한다는 뜻이다. 즉, 한 개의 픽셀당 16-bit 를 사용하게 된다. 이 때 A 는 Alpha 의 약자로 opaque(불투명도) 를 의미한다. => V4L2 에서는 V4L2_PIX_FMT_ARGB444 로 정의했지만 실제 의미는 ARGB4444 를 의미한다.
    V4L2_PIX_FMT_XRGB555 XR15  XRGB 는 Alpha 값을 padding 으로 대체한 RGB Color 를 의미한다. 
    (Formats that contain padding bits are named XRGB (or a permutation thereof). The padding bits contain undefined values and must be ignored by applications, devices and drivers, for both Video Capture Interface and Video Output Interface devices.)
    => XRGB555 는 1 개의 pixel 을 표현하는데 0bXRRRRRGGGGGBBBBB 를 사용한다는 뜻이다. 즉, 한 개의 픽셀당 16-bit 를 사용하게 된다. 이 때 X 는 padding bit 를 의미한다. 
    V4L2_PIX_FMT_RGB565X RGBR RGB565X 는 1 개의 pixel 을 표현하는데 0bXRRRRRGGGGGGBBBBB 를 사용한다는 뜻이다. 즉, 한 개의 픽셀당 16-bit 를 사용하게 된다. 이 때 X 는 big-endian 을 의미한다. 접미사에 `X` 가 붙을 경우 big-endian 을 의미한다. 접미사에 `X` 가 없다면 little-endian 이라고 보면 된다.
    V4L2_PIX_FMT_BGR32 BGR32 RGB32 는 1 개의 pixel 을 표현하는데 0bRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA
     를 사용한다는 뜻이다. 즉, 한 개의 픽셀당 32-bit 를 사용하게 된다. 그리고 RGBA 와 동일하다고 보면된다.
    V4L2_PIX_FMT_ARGB32 BA24 ARGB32 는 1 개의 pixel 을 표현하는데 0b AAAAAAAA RRRRRRRRGGGGGGGGBBBBBBBB
     를 사용한다는 뜻이다. 즉, 한 개의 픽셀당 32-bit 를 사용하게 된다.
    V4L2_PIX_FMT_XRGB32 BX24  

     

     

    " 아래 표에서 V4L2_PIX_FMT_RGB565 와 V4L2_PIX_FMT_RGB565X 를 비교해보면 little-endian 과 big-endian 의 차이를 알 수 있다. 주의할 점은 endian 은 byte 에 적용되는 개념이다. 일반적으로 bit 에는 적용되지 않는다(bit 에 적용할때는 `bit-endian` 이라는 별도의 용어를 쓴다).


    https://www.linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/pixfmt-rgb.html

     

     

    " V4L2_PIX_FMT_RGB565 와 V4L2_PIX_FMT_RGB565X 포맷의 차이를 제대로 보려면 Byte 단위로 끊어서 봐야 한다. 아래 그림을 보면 Byte 단위로 순서가 바뀌었다는 것을 알 수 있다.

     

     

    " YUV 같은 경우는 크게 2 가지 포맷으로 나뉜다. 그런데 이 글에서 이런 기본적인 개념을 다루기에는 너무 길어질 수 있기 때문에 YUV 포맷에 대한 내용은 다른 글에서 다루도록 한다. 

    1. Packed
    2. Planar

     

     

     

    - MEDIA_BUS_FMT_*

    " MEDIA_BUS_FMT_* 은 `Media Bus Pixel Codes` 라고 하며 실제 물리적인 데이터 라인(MIPI, BT656/1120 등) 을 통해 데이터들이 어떤 image format 으로 전송되는지를 나타낸다. kernel/include/uapi/linux/media-bus-format.h 파일을 보면 알 수 있다시피 가장 대표적으로 사용하는 image format 은 3 가지 있다.

    1. RGB - MEDIA_BUS_FMT_RGB*
    2. YUV - MEDIA_BUS_FMT_YUV*
    3. BAYER - MEDIA_BUS_FMT_SBGGR_*

     

     

    " 나 같은 경우에 Media Bus 를 통해 RGB 데이터를 받는 케이스는 경험해 본적이없다. 거의 대부분이 YUV or BAYER 데이터들이었다. 대개 Nextchip 의 이미지 센서들로 부터는 YUV 데이터를 전달받았고 Sony 의 IMX 시리즈들로 부터는 BAYER 데이터를 받았다. 대개 YUV data 를 받게되는 경우 외부에서 이미 ISP 튜닝을 거친 데이터를 의미하고(그래서 SoC 내부의 ISP 를 타지 않는다) BAYER 일 경우 SoC 내부의 ISP 를 거쳐 실제 이미지가 된다. 

     

     

    " MEDIA_BUS_FMT_* 을 설정할 때는 image sensor 의 datasheet 를 참고해서 설정해야 한다. 그래서 여기서는 MEDIA_BUS_FMT_* 를 해석하는 일반적인 방법에 대해 알아보자.

    1. `MEDIA_BUS_FMT_` 뒤에는 color format[order]이 온다. 예를 들어 RGB, YUV, BAYER 가 될 수 있다. 그리고 여기에 데이터가 전달되는 순서가 따라붙는다. 예를 들어, MEDIA_BUS_FMT_SBGGR8 같은 경우 color filter array 로 BGGR 을 사용한 것이고 한 픽셀당 8 비트를 차지한다고 볼 수 있다.

    2. `MEDIA_BUS_FMT_[color format]` 뒤에는 한 픽셀을 표현하는데 사용되는 비트 (depth) 가 나온다. 예를 들어, MEDIA_BUS_FMT_SGRBG8_1X8 은 BAYER DATA 로 GRBG 형식으로 데이터가 전달되고 한 픽셀을 나타내는 8 bit 가 사용됨을 의미한다.

    3. `MEDIA_BUS_FMT_[color format[depth]]` 뒤에는 `버스 개수X버스 대역폭` 이 나온다. 예를 들어, MEDIA_BUS_FMT_YUYV8_2X8 은 한 개의 component 를 처리하는데 8-bit 가 사용되며 2 개의 8-bit Media bus 가 있음을 의미한다. YUYV8 은 한 픽셀을 표현하는데 32-bit 가 사용되고 2x8-bit 가 있으므로 한 번에 16-bit 씩 전송이 가능하다.

    4. 한 픽셀을 표현하는데 사용되는 비트수가 버스의 대역폭보다 클 경우 padding bits 가 들어갈 수 있다. 이 때 PADHI 혹은 PADLO 를 붙인다 ->
    MEDIA_BUS_FMT_RGB888_1X32_PADHI, MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE

    5. 한 픽셀을 표현하는데 사용되는 비트수가 버스의 대역폭보다 클 경우 MSB first(BE) 혹은 LSB first(LE) 할지를 결정하는 언어를 붙힌다 -> MEDIA_BUS_FMT_BGR565_2X8_BE, MEDIA_BUS_FMT_BGR565_2X8_LE

     

     

    " 위에 내용을 기반으로 아래 코드들을 해석해보길 바란다. 

    1. RGB
    - MEDIA_BUS_FMT_RGB444_1X12
    - MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE
    - MEDIA_BUS_FMT_BGR565_2X8_LE
    - MEDIA_BUS_FMT_RGB666_1X24_CPADHI
    - MEDIA_BUS_FMT_RGB101010_1X30
    
    
    
    2. YUV
    - MEDIA_BUS_FMT_UYVY8_2X8
    - MEDIA_BUS_FMT_VYUY8_2X8
    - MEDIA_BUS_FMT_VUY8_1X24
    - MEDIA_BUS_FMT_YUYV8_1X16
    - MEDIA_BUS_FMT_AYUV8_1X32
    
    
    
    3. BAYER
    - MEDIA_BUS_FMT_SBGGR8_1X8
    - MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8
    - MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8
    - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE
    - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE
    - MEDIA_BUS_FMT_SGRBG12_1X12

     

     

    " 참고로 RGB 에서 `CPADHI` 는 MSB 쪽에 padding 을 추가하는데 `0` 으로 채운다는 뜻이다. 만약, ` CPADLO` 인 경우는 LSB 쪽에 `0` 을 padding 한다. 아래 표는 CPADHI 를 사용한 케이스다. 각 바이트마다 2-bit 씩 0 으로 padding 하는 것을 볼 수 있다.  

     

     

    " Bayer Pattern 에서는 ALAW 및 DPCM 압축 방식을 사용하는 경우가 있다. 이 때 ALAW 및 DPCM 뒤에 오는 숫자는 압축된 비트수를 의미한다. 예를 들어, MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 은 기존에는 한 개의 pixel component 를 표현하는데 10-bits 가 필요했는데 ALAW 로 압축하고 나서 8-bits 로 1 개의 pixel component 를 표현할 수 있다는 뜻이다.  

     

     

    " Bayer Pattern 에서 궁금한 점이 있다. BGGR8 이라는게 blue 픽셀을 표현하기 위해 8-bits, green 픽셀을 표현하기 위해 2*8-bits, red 픽셀을 표현하기 위해 8-bits 해서 총 32-bits 를 보내는게 아니라 8-bits 한 개만 보내서 BGGR color filter array 에 패턴을 씌우는걸로 보인다. 예를 들어, 아래와 같이 0b01110101 이라는 8-bits 데이터가 BGGR 각각에 쓰워지면 다음과 같은 모습이 된다.

    0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1
    0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1

     

     

     

    - MEDIA_BUS_FMT_* vs V4L2_PIX_FMT_*

    " MEDIA_BUS_FMT_* 와 V4L2_PIX_FMT_* 을 헷갈리면 안된다. V4L2_PIX_FMT_* 은 image data 가 memory 에 저장될 때 어떤 포맷으로 저장될 지를 결정한다. 그러나 MEDIA_BUS_FMT_* 는 물리적인 Media Bus 를 통해서 전달되는 image data 포맷이 어떻게 전달되는지를 나타낸다. 얼핏보면 비슷해 보이지만 반드시 1:1 대응 관계는 아니라고 한다.

    This should not be confused with the V4L2 pixel formats that describe, using four character codes, image formats as stored in memory.

    While there is a relationship between image formats on buses and image formats in memory (a raw Bayer image won’t be magically converted to JPEG just by storing it to memory), there is no one-to-one correspondence between them.

    - https://www.kernel.org/doc/html/v5.2/media/uapi/v4l/subdev-formats.html
Designed by Tistory.