처음에 이 글을 기획했을 때, DivX의 소스 코드를 분석하고자 했다. 그러나 DivX를 분석하기 위한 기본 개념을 설명하는 것이 필요하다는 생각이 들어 DivX의 기본 소스가 되는 DVD와 디지털 TV에 관한 내용을 먼저 살펴본 후 DivX 관련 소스 코드를 분석하여 그 구조를 알아보자. DVDDVD는 ‘Digital Versatile Disc’의 약자로, 흔히 DVD-Video를 지칭한다. 이제 DVD-Video를 다시 설명하면 DVD 포럼이라는 표준화 기관에서 만든 표준으로 비디오 영화 등을 광학 DVD 디스크(optical DVD disc)에 저장하기 위한 방법을 정하고 있다. 실제 비디오가 어떤 형식으로 저장되는지를 보면, MPEG-2 또는 MPEG-1 형식으로 저장되게 된다(하지만 MPEG-2 표준이 MPEG-1 표준에 비해 비디오 압축 화질이 뛰어나기 때문에, 거의 모든 비디오 영상이 MPEG-2 표준으로 압축된다고 생각해도 무방하다). MPEG-1과 MPEG-2에 대한 설명은 박스기사를 참조하기 바란다.DVD란 MPEG-2 비디오 압축 표준을 사용한 디스크 저장 표준이라고 설명했는데, 실제 MPEG-2 표준은 상당히 큰 표준이고 보면(원래 MPEG-3가 HDTV 표준을 정의하기로 되었는데, MPEG-2가 MPEG-3의 표준까지 통합하게 됨으로써 MPEG-2는 원래의 MPEG-2와 MPEG-3를 포괄하는 표준이라고 생각할 수 있다), DVD 표준은 MPEG-2의 일부분이게 되는데, DVD 표준과 MPEG-2 표준의 중요한 차이는 다음과 같다.
① 스트림 : DVD 비디오는 비디오 1개, 오디오 8개만을 가진다.② 압축 기법 : DVD 비디오는 MPEG-1 VBR(Variable Bit Rate)/CBR(Constant Bit Rate), MPEG-2 MP@ML(Main Profile, Main Level), SP@ML(Simple Profile, Main Level) VBR/CBR을 이용할 수 있다.③ 영상 크기 : MPEG-1을 사용하는 경우, NTSC(352×240, 352×480), PAL(352×288, 352×576)을 사용할 수 있고, MPEG-2를 사용하는 경우, 720×480, 704×480, 352×480, 352×240(NTSC) 또는 720×576, 704×576, 352×576, 352×288(PAL/SECAM)을 이용할 수 있다.④ 초당 프레임 수 : 29.97(NTSC) 또는 25(PAL/SECAM)을 지원할 수 있다.⑤ 화면 비 : 4:3 또는 16:9를 지원한다.
DVD 포럼에 의해 정의된 DVD-Video 표준 외의 표준으로는 DVD-Audio 표준이 있는데 간단히 설명하도록 한다. DVD-Audio 표준은 DVD 포럼이라는 표준화 기관에 의해 정의된 표준으로 기존의 음악 CD를 교체하려는 시도로 출발하고 있다. DVD-Audio 표준은 418GB의 음악을 담을 수 있으며, 음악을 담기 위한 압축 방법으로는 (L)PCM 형식(44.1KHz에서 192KHz까지의 주파수 샘플링으로 1초당 9.8 Mbps 필요), 돌비 디지털 5.1, MPEG-1(스테레오, MPEG-1 Audio Layer II, III), MPEG-2(multichannel), DTS, SDDS 등이 가능하다. 하지만 DVD-Audio가 그리 순탄하지만은 않은 것이 소니 등의 텔레비전을 구입하면 카탈로그에 적힌 SACD(Super Audio CD)라는 것이 있고 실제 음질면에서도 DVD-Audio와 견줄만한 좋은 품질을 보이고 있다.디지털 TV현재 HDTV가 방송 중이고 금년 10월부터는 주당 HDTV 방송 시간을 10시간 이상으로 늘린다고 한다. 하지만 여전히 HDTV 텔레비전 가격이 비싸고 실제 HDTV 방송이 많이 제작되지 않는 것을 보면 HDTV 대응 텔레비전(셋톱박스를 연결하면 HDTV 수신이 가능한 텔레비전)이 유용할 수도 있다. HDTV 이전까지의 아날로그 텔레비전은 크게 유럽식 아날로그 방식인 PAL과 SECAM, 그리고 미국식 아날로그 방식인 NTSC가 있고 각각에 대해 설명하면 다음과 같다.◆ NTSC(National Television System Committee)1953년 미국에서 정의된 아날로그 컬러 텔레비전 표준으로 현재 미국, 캐나다, 일본, 한국 등의 아시아권 국가에서 사용하고 있다. NTSC의 수평 해상도는 프레임당 525줄이며, 1초에 프레임수는 29.97프레임이 나온다. PAL 방식보다 초당 프레임 수가 많긴 하지만, 인터레이스(interlaced) 방식이라고 하여 1/30초마다 짝수, 홀수 프레임이 번갈아 나오게 되는 화질 저하가 있다.◆ PAL(Phase Alternating Line)1960년 유럽에서 정의된 아날로그 컬러 텔레비전 표준으로, 프레임당 수평 해상도가 625줄로 NTSC의 525줄보다 화질이 뛰어나다. 초당 프레임수는 NTSC의 29.97보다 낮은 25프레임이지만 사람이 느끼기에는 비슷하다. PAL 방식은 프랑스(SECAM 방식을 사용함)를 제외한 호주, 아프리카, 남미, 그리고 일부 아시아권 국가에서 사용하고 있으며, 구체적으로는 PAL B/G(보통 말하는 PAL 표준), PAL I(영국과 아일랜드에서 사용하는 PAL 방식), PAL M(NTSC와 같은 해상도를 가지면서 PAL 방식과 같은 전송 표준 및 컬러 표준을 따르는 표준) 표준으로 나뉜다. ◆ SECAM(Sequential Couleur Avec Memoire or Sequential Colour with Memory)1960년대 초에 프랑스에서 상용화된 아날로그 컬러 표준으로 PAL과 같은 대역폭을 가지고, PAL과 같이 초당 프레임은 25프레임, 수평 해상도는 625줄을 지원하고 있다. 따라서 내부적으로 PAL 방식과 동일하게 구성하고 있으며, 컬러 정보를 전송하는 경우에만 순차적으로 보내는 구조를 채택하고 있다. 이제, HDTV 텔레비전을 구입하는 경우에 다양한 형식을 지원하게 되는데, 요약하면 1080i(프레임당 1920×1080 해상도를 지원하며 인터레이스 방식임), 720i(프레임당 1280×720 해상도를 지원하며, 인터레이스 방식임), 720p (프레임당 1280×720 해상도를 프로그래시브 모드로 지원)이 있다. 이러한 정보는 현재 HDTV 수신용 셋톱 박스를 구입하는 경우에 ATSC(Advanced TV Systems Committee) 수신 모드에서 정해지고 셋톱박스의 메뉴를 눌러서 선택할 수 있다. 이러한 HDTV가 갖는 장점은, HDTV 방송이 디지털 방송이고, 방송국에서 전송한 영상과 가정에서 수신한 영상이 100% 동일한 영상이라는 점이다. 또한 가정의 DVD 레코더 등으로 녹화를 한다면 압축기법의 차이에서 나타나는 화질 저하 외에는 없게 된다. DivX이제 DivX에 대해 알아보기 전에 간단히 DivX의 역사를 알아보도록 한다. 먼저 Divx ;-) 코덱이 있다. 이 코덱은 흔히 DivX 코덱의 원조인데, MPEG-4 기술을 이용한 마이크로소프트의 WMV(Windows Media Video) 비디오 코덱을 해킹해 만든 것이 시초이다. 현재 Divx ;-) v.3.11 alpha로 불려지고 있다. 이후에 해킹 주인공들은 본격적으로 해킹 버전이 아닌 프로젝트 마요(project mayo) 또는 OpenDIVX라는 이름으로 불리는 코덱을 개발하게 됐다. DivX 4 버전이 개발되는 시점에서 프로젝트 마요를 개발하던 개발자들은 DivxNetworks라는 회사를 설립해 더 이상 공개 소스로 제공하지 않는다. 이제 또 다시 공개 소스를 주장하는 개발자들이 모여서 XVID라는 비디오 코덱 개발을 시작하게 된다. DivxNetworks에서 만들어내고 있는 Divx 5 버전의 경우는 MPEG-4 비디오 코덱과 호환되는 코덱으로 개발되고 있다. 본 기사에서 다룰 비디오 코덱은 OpenDIVX 버전 4이다. 앞으로 기억하고 있어야 할 것은 DVD 비디오는 MPEG-2 표준이고 DivX 비디오는 MPEG-4 표준의 구현이라는 것이다.DVD를 DivX로 만들기 위한 준비이제 가정용 DVD를 이용해서 DivX 비디오로 만드는 예를 통해 실제 DIVX 비디오 코덱을 분석하기 전에 실제 어떤 파일들을 고쳐나가야 되는지를 알아보자. DVD 비디오를 자동으로 다양한 형식으로 바꿔주는 프로그램들이 있고 그 중에서 FLASKMPEG과 XMPEG이라는 프로그램이 대표적이다. XMPEG은 FLASKMPEG의 여러 기능들을 보완한 기능과 쉽게 사용할 수 있다는 장점이 있다. 이제 실제로, XMPEG이나 FLASKMPEG을 사용해서 DVD 파일을 DIVX 파일로 바꾸기 전에 할 일은 DIVX 비디오 코덱을 설치하는 일이다. 참고 사이트에서 설명한 프로젝트 마요의 홈페이지에서 관련 비디오 코덱을 다운로드 받아서 설치되며, 설치 후 <화면 3>과 같이 제어판의 사운드/멀티미디어, 하드웨어 부분에서 비디오 코덱 (DIVXWINDOWS MPEG-4 Video CODEC)이 설치되어 있는 것을 확인할 수 있다. 이제 앞으로 설명하게 될 DivX 코덱은 크게 인코더(encore)와 디코더(decore)로 구성되며, 인코더와 디코더를 합한 코덱을 라이브러리 형태로 만들어, 윈도우 내의 비디오 코덱으로 설치하게 된다. 이와 같은 형태의 코덱을 소프트웨어 코덱이라 한다.
<화면 3> 비디오 코덱 설치 후 등록 정보 확인
DVD를 DivX로!이제 DVD 파일을 DivX 파일로 만들기 위해서 갖고 있는 DVD 파일을 하드디스크로 옮겨야 하며, RIPPER라고 불리는 프로그램을 이용해 하드디스크로 옮기고 나면 DVD 디스크에 저장된 파일 중에서 VOB(DVD Video Objects) 와 IFO(DVD Information) 확장자를 가진 파일들이 올라온다. VOB는 DVD-Video 디스크에 실제 저장된 영상 파일들을 담고 있으며, 실제 MPEG-2 Multiplexed 비디오 스트림, 오디오 스트림(주로 돌비 AC3 형식으로 제공됨), 그리고 타이틀(subtitle) 스트림이 포함된다. IFO는 Information의 약자로, VOB가 실제 MPEG-2 영상, 오디오, 타이틀 데이터를 담고 있는 파일이라면 IFO 파일들은 DVD 플레이어에게 DVD 각 챕터의 시작을 알리고 또는 특정 오디오 트랙이 어디에서 시작하는지 정보를 알려주게 된다. 이제, FLASKMPEG 또는 XMPEG을 사용해 특정 VOB 파일을 지정하고, 변환 시작 버튼을 누르면, DivX 파일로 변환이 시작되는데 이제 <화면 4>처럼 출력 형식을 지정해준다. 즉, 오디오의 경우는 돌비 AC3 형식으로 변환해 주고, 비디오의 경우는 720×480 해상도의 NTSC 프레임 속도를 지원하도록 변환 요청을 할 수 있다.
<화면 4>출력 형식 지정
DivX 코덱의 기본 설계 전략DVD 파일과 같은 고화질의 영상을 압축률이 높은 DivX 파일로 바꾸는 과정을 정확하게는 트랜스코딩 (transcoding)이라고 한다. 그리고 일반 RGB(8비트 3개인 24비트) 화소로 구성된 일반 영상을 DivX 등으로 만드는 경우를 코딩 또는 압축이라 한다. 이제 그 반대 경우를 디코딩 또는 ‘압축을 푼다고’ 하는데, DivX에서는 encore, decore라고 불리는 라이브러리로 제공하고 있다. MPEG-1, MPEG-2, MPEG-4의 서비스 영상이 각각 다르기는 하지만 MPEG-4의 영상 코덱 성능이 세월을 흘러오면서 발전해 왔다는 것도 사실이다. MPEG-1 코덱과 중요한 차이점을 그림으로 보이면 <그림 1>과 같다.
<그림 1>DivX와 MPEG-1 코덱과의 차이 비교
<그림 1>에서 배경 부분은 거의 움직이지 않고, 테니스 플레이어만 움직이는 영상의 경우, 배경 부분과 테니스 플레이어를 분리함으로써 효율적인 비디오 압축이 가능하게 된다. 이 때, 움직이는 테니스 플레이어를 스프라이트(sprite)라고 하고, 배경 부분을 텍스처(texture)라고 하며, 코딩 부분에서는 각각을 따로따로 스프라이트 코딩과 텍스쳐 코딩으로 분리해서 처리한다. 만약 한번의 자세한 텍스쳐 코딩 후에 전혀 배경 부분이 움직이지 않는다면 상당한 압축 효과를 기대할 수 있기 때문이다. Visual Object는 Structure(모양)와 Structure에 색을 입히기 위한 Texture(색)으로 나눈다. Texture는 비디오 프레임을 진행하면서 바뀌는 부분이며, Still 부분은 비디오 프레임을 진행하면서 바뀌지 않는 부분으로 대부분 배경 부분이다. 이와 같이 객체(object) 단위로 비디오 코덱을 구성하게 되는 경우가 MPEG-2와 MPEG-4 기반 코딩 기법이 가지는 중요한 차이점이 된다. MPEG-2와 MPEG-4를 비교한 그림은 <그림 2>와 같다. 그림에서 보는 것처럼 MPEG-2에서는 물체를 조금만 달리봐도 비디오 프레임들은 전혀 다른 형태의 영상이 되어 다시 한번 엄청난 양의 데이터를 보내야만 한다. 반면에 MPEG-4에서는 송신자와 수신자가 어느 정도의 모델을 공유하고 있으며, 단순히 MPEG-4 스트림을 타고 파라미터를 보내서 수신측에서 이미지를 만들어내는 식으로 동작한다.
<그림 2> MPEG-2와 MPEG-4 비교
DivX 코덱의 기본 원리DIVX 코딩을 위한 encore 라이브러리는 다음과 같이 구성된다.
① 주 프로그램인 encore.c② 움직임 처리를 위한 mot_code.c, mot_est_comp.c, mot_est_mb.c, mot_util.c③ DCT/IDCT 변환을 고속 수행하기 위한 text_fdct_mmx.c, text_idct_mmx.c④ 기본적인 VOP 코딩을 위한 vop_code.c⑤ 텍스처 부분의 코딩을 위한 text_dct.c, text_code_mb.c, text_code.c, text_bits.c⑥ 기본적인 이미지 객체 VOP 등을 관리하기 위한 유틸리티 함수들이 제공되는 mom_access.c와 mom_util.c⑦ RLC(Run Length Coding) 등으로 비손실 압축 부분을 구현하는 putvlc.c⑧ 실제 비트 스트림을 만들고 전송 속도를 결정하는 부분인 bitstreamc., rate_ctl.c
이제 DivX를 포함하는 MPEG-4 코딩의 기본 코딩 단위를 보면 <그림 3>와 같이, shape(모양 정보) 부분과 texture(색상 정보)로 나뉜다. 그림 왼쪽의 Video Object와 Still Object는 texture로 취급하고, 오른쪽의 mesh와 face/.body 등은 structure로 취급한다.
<그림 3>MPEG-4 기본 코딩 단위
VOP(shape 또는 texture)에 대한 전체 프로그램 동작은 간단히 <그림 4>과 같이 동작한다. 비디오 멀티플렉서로 들어가는 부분은 shape coding 부분과 motion texture coding 부분으로 나뉜다. 즉, DivX 코딩에서는 각 화면 프레임을 shape 또는 texture로 분리해서 처리한다. Texture만 사용해서 코딩한다면 이전의 MPEG-1, MPEG-2와 같은 코딩 기법을 적용하는 것이 된다.
<그림 4> VOP에 대한 전체 프로그램 동작
DivX 코덱의 핵심 1, 움직임 추정<그림 5>을 보면 움직임 추정(motion estimation) 부분이 있는데, DivX 코딩에서 해당되는 부분은 각각mot_code.c, mot_est_comp.c, mot_est_mb.c, mot_util.c이며, MPEG-4 기반의 코딩에서 이전 프레임과 현재 프레임의 변화된 부분을 찾아내는 움직임 추정(motion estimation) 부분은 중요한 부분이다.
<그림 5> DivX 코덱의 움직임 추정
MPEG-4의 움직임 추정은 VOP(Visual Object Planes) 단위로 이뤄지는데 <그림 5>과 같이 VOP들 간의 상관성을 조사한다. 이는 MPEG-1/MPEG-2에서 해왔던 것처럼 I프레임과 P프레임을 써서 B프레임을 예측하는 방법과 비슷한 방법이다. 이에 해당하는 부분은 vop_code.c에 있으며 다음과 같다.
/* -- VopCode -- Shape, texture and motion coding of the vop * * Purpose : * This function performs shape, texture and motion coding of the * vop passed to it. The input vop is assumed to be BOUNDED. * * Arguments in : * Vop *curr - pointer to vop to be coded * Vop *prev - pointer the last occurence of this vop * Vop *rec_prev - pointer to last coded occurence of this vop * Int enable_8x8_mv - 8x8 motion vectors flag (SpSc) * Int intra_dcpred_disable - disable intradc prediction * Float time - * VolConfig *vol_config - */Void VopCode(Vop *curr, Vop *reference, Vop *reconstruct, Vop *error, Int enable_8x8_mv, Float time, VolConfig *vol_config)
이제 shape 단위의 움직임 추정이 없다면 texture 단위의 움직임 추정만 있게 되며, MPEG-4에서의 움직임 추정은 16×16 크기의 MB(Macro Block) 단위로 이뤄질 수도 있지만 움직임이 세밀한 부분에서는 8×8 블럭 4개로 나뉘어 각각 따로따로 움직임 추정이 이뤄질 수도 있다(mv16_h, mv16_w, mv8_h, mv8_w). 자세한 부분은 mot_est_mb.c 부분에서 이뤄진다. 이렇게 해서 얻어진 움직임 벡터들은 mot_code.c에 의해 실제 이진 값으로 코딩된다.
DivX 코덱의 핵심 2, DCT/IDCT 변환전체 그림의 DCT 부분은 text_dct라는 부분에서 실행되는데 실제 DCT/IDCT 변환 부분은 고속화시켜야 하므로 다음과 같은 2개의 파일에 의해 구현된다.◆ text_fdct_mmx.c : 8×8 블럭을 코딩하기 위해서는 DCT(Discrete Cosine Transform)라는 변환을 하게 되는데, 이 부분이 항상 시간이 많이 걸리는 부분으로 encore 라이브러리에서는 MMX 어셈블리 형태로 바로 코딩한 것을 볼 수 있다. ◆ text_idct_mmx.c : 8×8 블럭을 코딩하기 위해서는 움직임 추정 후 보정에 의해 IDCT(Inverse Discrete Cosine Transform)이라는 DCT의 역변환을 하게 된다. 이 부분이 항상 시간이 많이 걸리는 부분으로 encore 라이브러리에서는 다음과 과 같이 MMX 어셈블리 형태로 바로 코딩한 것을 볼 수 있다.__asm {
//////////////////////////////////////////////////////////////////////// // // The high-level pseudocode for the fdct_mm32() routine : // // fdct_mm32() // { // forward_dct_col03(); // dct_column transform on cols 0-3 // forward_dct_col47(); // dct_column transform on cols 4-7 // for ( j = 0; j < 8; j=j+1 ) // forward_dct_row1(j); // dct_row transform on row #j // } mov INP, dword ptr [blk];// input data is row 0 of blk[] ;// transform the left half of the matrix (4 columns) lea TABLEF, dword ptr [tg_all_16]; mov OUT, INP;
DCT/IDCT를 수행하기 위해서는 기본적으로 이미지 객체, VOP 객체를 가져오는 유틸리티가 있어야 하고 mom_access.c와 mom_util.c가 이 기능을 제공한다.DivX 코덱의 메인, encore.c이제 코딩 부분의 주 프로그램인 encore 프로그램은 다음에 나오는 소스 코드와 같이 구성된다. encore.c는 주 프로그램에서 코딩하기 위한 다양한 변수들을 정의하고 있다. 예를 들어, 1초당 프레임 수 framerate, 통신 선로를 통해 데이터를 보내는 경우에 몇 bps로 보내고 어떤 간격으로 조정해 나갈 것인지를 판단하는 rc_period, rc_reacion_period 등이 있다. 또한 키 프레임(움직임 추정의 기본이 되는 프레임)을 어떤 간격으로 할 것인지를 결정하는 ma_key_interval, 그리고 화면의 가로 세로 크기를 결정하는 x_dim, y_dim이 있다. 또한 이전 화면과 현재의 화면의 변화된 부분을 찾기 위해 어떤 영역을 찾을 것인지를 결정하는 search_range가 있다.
typedef struct _REFERENCE{
unsigned long handle;float framerate;long bitrate;long rc_period;long rc_reaction_period;long rc_reaction_ratio;long max_key_interval;int x_dim, y_dim;int prev_rounding;int search_range;int max_quantizer;int min_quantizer;long seq;long curr_run; /* the current run before the last key frame */Vop *current; /* the current frame to be encoded */Vop *reference; /* the reference frame - reconstructed previous frame */Vop *reconstruct; /* intermediate reconstructed frame - used in inter */Vop *error; /* intermediate error frame - used in inter to hold prediction error */struct _REFERENCE *pnext;
} REFERENCE;인코더 설계가 이슈MPEG 비디오 표준과 같은 영상 압축 표준에서 중요한 사실은 표준에서는 디코더(영상을 보여주는 부분)만을 정의한다는 점이다. 따라서 필요한 사람들의 경우에는 인코더 부분을 효율적으로 설계해 상당한 압축율을 보이면서 고화질을 유지하는 인코더를 설계하는 것이 주요 관심사가 된다. 이번 호에서는 영상 압축 관련한 DVD, DivX, 디지털 TV의 기본 기술에 대해 살펴보고, 실제 DivX 비디오 코덱의 분석에 들어가기 전에 비디오 코덱의 기본적인 사용법과 관련된 용어를 설명했다. 또한, 소프트웨어 코덱을 만들기 위한 encore/decore의 구조를 살펴봤다. 다음 호에서는 미진했던 인코더 관련 내용과 새롭게 디코더 부분과 디코더를 사용한 PLAYA라는 플레이어에 대해 살펴보겠다. @