우리라이프

[개발 - 포맷] AVI Structure(AVI 구조) 본문

IT/개발 지식

[개발 - 포맷] AVI Structure(AVI 구조)

적당히벌고아주잘살자 2018. 2. 5. 15:05
반응형

 

 

 

RTSP 스트림 데이터를 전송받아 AVI 파일로 저장하는 프로젝트를 진행하였다. 

전처리로 AVI 파일 구조를 분석하였다.


Microsoft AVI 파일 포맷

오디오/비디오 순서의 캡춰, 편집, 재생을 실시하는 애플리케이션으로 사용되는 RIFF 파일 사양이다. 일반적으로, AVI 파일에는 다른 종류의 데이터의 스트림이 복수 포함된다.

대부분의 AVI 순서는, 오디오 스트림과 비디오 스트림의 양쪽 모두를 사용한다. 단순한 AVI 순서에서는, 비디오 데이터만을 사용해, 오디오 스트림은 필요로 하지 않는다.

AVI 파일 구조

RIFF 파일 사양

RIFF(Resource Interchange File Format, 리소스 교환 파일 형식) 동영상 재생을 위해 마이크로소프트가 만든 내부 데이터 포맷

 

AVI Main Header

'hdrl'리스트는 AVI 메인 헤더로 시작되어, 이 메인 헤더는 'avih'체크에 포함되어 있다. 메인 헤더에는, 파일내의 스트림수, AVI 순서의 폭과 높이 등, AVI 파일 전체에 관한 글로벌 정보가 포함된다. 메인헤더 체크는,AVIMAINHEADER 구조체로 구성되어 있다.

AVI Main Header Structure

Main AVI Header (avih)
typedef struct {
  DWORD dwMicroSecPerFrame;
  DWORD dwMaxBytesPerSec;
  DWORD dwPaddingGranularity;
  DWORD dwFlags;
  DWORD dwTotalFrames;
  DWORD dwInitialFrames;
  DWORD dwStreams;
  DWORD dwWidth;
  DWORD dwHeight;
  DWORD dwReserved[4];
} MainAVIHeader;

dwFlags

  • AVIF_HASINDEX : The file has an index
  • AVIF_MUSTUSEINDEX : The order in which the video and audio chunks must be replayed is determined by the index and may differ from the order in which those chunks occur in the file.
  • AVIF_ISINTERLEAVED : The streams are properly interleaved into each other
  • AVIF_WASCAPTUREFILE : The file was captured. The interleave might be weired.
  • AVIF_COPYRIGHTED : Ignore it

 

첨부한 문서의 mainHeader는 위 코드와 같고, 링크의 mainHeader에는 fourcc cb가 포함되어 있음.

 링크 : http://telnet.or.kr/directx/htm/avimainheaderstructure.htm

 

AVI Stream Header

메인 헤더의 다음에는, 1 개 이상의 'strl'리스트가 계속된다. 'strl'리스트는 각 데이터 스트림 마다 필요하다. 'strl'리스트에는, 파일내의 단일의 스트림에 관한 정보가 포함되어 스트림헤더 체크 ('strh')와 스트림포맛트체크 ('strf')가 반드시 포함된다.

게다가'strl'리스트에는, 스트림헤더 데이타체크 ('strd')와 스트림명 체크 ('strn')가 포함되는 경우가 있다.

스트림헤더 체크 ('strh'),AVISTREAMHEADER 구조체로 구성되어 있다스트림포맛트체크 ('strf'), 스트림헤더 체크의 뒤에 이어 기술할 필요가 있다. 스트림포맛트체크는, 스트림내의 데이터의 포맷을 기술한다. 이 체크에 포함되는 데이터는, 스트림 타입에 따라서 다르다.

Stream Header

typedef struct {
  FOURCC fccType;             /* vids -> video, auds -> audio, txts -> subtitle */
  FOURCC fccHandler;
  DWORD dwFlags;
  WORD wPriority;
  WORD wLanguage;
  DWORD dwInitialFrames;
  DWORD dwScale;
  DWORD dwRate;               /* dwRate / dwScale == frames / second */
  DWORD dwStart;
  DWORD dwLength; 
  DWORD dwSuggestedBufferSize;
  DWORD dwQuality;
  DWORD dwSampleSize;
  RECT rcFrame;
} AVIStreamHeader;

dwFlags

0x00000001 AVISF_DISABLED : The stram data should be rendered only when explicitly enabled.
0x00010000 AVISF_VIDEO_PALCHANGES : Indicates that a palette change is included in the AVI file.  This flag warns the playback software that it will need to animate the palette.

 

첩부한 문서의 streamHeader는 위 코드와 같고, 링크의  streamHeader 에는 fourcc cb가 포함되어 있음.

링크 : http://telnet.or.kr/directx/htm/avistreamheaderstructure.htm

 

Chunk List

Chunk video, audio, subtitle data dwFourCC로 표현한다.dwFourCC는 스트리밍 헥사 값과 데이터 타입 ( dc = video, wb = audio, tx = text)을 포함한다.

Basic data structure

Chunks
typedef struct {
  DWORD dwFourCC
  DWORD dwSize
  BYTE data[dwSize]
} CHUNK;
 
Lists
typedef struct {
  DWORD dwList
  DWORD dwSize
  DWORD dwFourCC
  BYTE data[dwSize - 4]
} LIST;

 

AVI 스트림 데이터('movi' 리스트)

헤더 정보의 다음에 계속되는 것은, 스트림내의 실제의 데이터, , 비디오 프레임 및 오디오 샘플을 포함한 'movi'리스트이다. 데이타체크는 'movi'리스트내에 직접 기술하는 경우와'rec '에 그룹화 하는 경우가 있다.

'rec '의 그룹화는, 그룹화 한 체크는 한 번에 읽어낼 필요가 있는 것을 의미해, CD-ROM 로부터 재생하기 위해서 인터리브 된 파일의 경우에만 사용된다.

각 데이타체크를 식별하는 FOURCC , 2 자리수의 스트림 번호와 그 후에 계속되는, 체크내의 정보의 종류를 정의하는 2 문자 코드로 구성되어 있다.

FOURCC : db : 비압축 비디오 프레임, dc : 압축 비디오 프레임, pc : 팔레트의 변경, wb : 오디오 데이터 

 

AVI 인덱스 엔트리

옵션의 인텍스 ('idx1') 체크는, 'movi' 리스트의 다음에 기술할 수 있다. 인덱스에는, 데이터 체크의 리스트와 파일내에서의 그 위치가 포함되어 있다. 인덱스는 AVIOLDINDEX 구조체고 구성되어 'rect' 페크를 포함한, 각 데이터테크의 엔트리가 포함되어 있다.

파일에는 인덱스가 포함되는 경우 AVIMAINHEADER 구조체의 dwFlags 멤버에 있는 AVIF_HASINDEX 플래그를 설정한다.

AVI Old Index

typedef struct AviOldIndex {
  FOURCC fcc;
  DWORD cb;
  struct AviOldIndexEntry {
    DWORD dwChunkId;
    DWORD dwFlags;
    DWORD dwOffset;
    DWORD dwSize;
  }indexEntry[];
};

링크 : http://telnet.or.kr/directx/htm/avioldindexstructure.htm


그 외의 데이타 체크

데이터는, 필요에 따라서 'JUNK' 체크를 삽입해, AVI 파일에 정렬시킬 수가 있다. 어플리케이션은, JUNK 체크의 내용을 무시할 필요가 있다.

Structure of the 'JUNK' chunk

Name

Size

Description

ID

4 byte

four ASCII character identifier 'JUNK'

Size

4 byte

size of Data

Data

Size bytes

nothing

unused

1 byte

present if Size is odd

 

FOURCC 정의 방법

  • #include <MMSystem.h>
  • unsigned long fcc = MAKEFOURCC(A, B, C, D);
    #define MAKEFOURCC(ch0, ch1, ch2, ch3)
    ((unsigned long)(unsigned char)(ch0) | ((unsigned long)(unsigned char)(ch1) << 8) |  
    ((unsigned long)(unsigned char)(ch2) << 16) | ((unsigned long)(unsigned char)(ch3) << 24 ))

 

FOURCC Code

AVIMAINHEADER 에서 FOURCC 코드 : avih

AVISTREAMHEADER 에서 FOURCC 코드 : strh

AVIOLDINDEX 에서 FOURCC 코드 : idx1

링크 : http://www.fourcc.org/codecs.php


틀린 FPS에 대한 처리

  1-1. 기본적으로 무조건 30FPS으로 설정한다.(AVI파일은 VFR(Variable FrameRate)를 지원하지 않아서 고정된 Framerate를 가져야 한다.)

 1-2. 초당 프레임들을 메모리나 파일에 보관 후, 다른 초의 데이터가 들어올 경우 해당 데이터들을 

       Avi 파일에 쓰는데, 30프레임에 맞게 중간 Dummy Chunk(0Byte)를 넣어줘야 한다.

 - 참고: https://www.moviecodec.com/video-codecs/avi-movie-with-different-frame-rates-123751/


Chunk Odd(홀수) Size 처리

위 사이트를 보면 Chunk 데이터의 사이즈가 홀수이면 실제 데이터에 1Byte(Dummy)를 추가하고 Chunk의 Size에는 해당 1Byte를 포함시키지 않아야 된다고 명시되어 있음.

(Chunk 데이터는 2바이트 정렬이므로)

참고: http://www.fileformat.info/format/riff/egff.htm

 



반응형
Comments