유돌이

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2008. 12. 29. 23:33 델파이
DirectShow란 무엇인가를 극명하게 보여주는 것이 바로 이 GraphEdit입니다. 이것을 사용하는 것이 바로 DShow를 눈으로 보는 것이다라고 말할 수 있기 때문입니다. 만일 여러분이 DirectX SDK를 설치하셨고 제가 앞서 말씀드렸듯이 바탕화면에 바로가기를 설정해 놓았다면 이제 이 프로그램을 실행시켜 보시길 바랍니다.
  
[1] 대체 DirectShow란 무엇인가.
 
DShow는 필터들의 연결입니다. 이 말을 쉽게 해설하기 위해서 저는 GraphEdit라는 유틸을 사용할 것입니다. 일단 이 프로그램을 실행시켰다면 간단하게 동영상을 한번 랜더링(실행)시켜 보도록 합시다.
File 메뉴의 Render Media File... 을 실행시키고 동영상 파일하나를 선택합니다. 만일 여러분의 컴퓨터에 현재 동영상을 재생하는데 필요한 코덱이 설치되어 있다고 하더라도 이곳에서는 다음과 같은 메시지가 나올 수가 있습니다. '비디오 스트림을 재생할 수 가 없습니다. 적절한 압축 풀기 프로그램을 찾을 수가 없습니다.' 그러면서 오디오 부분만이 설정이 되어 화면에 나타날 수가 있습니다.

해결방법은 몇가지가 있겠으나, ffdshow를 설치하라고 권하고 싶습니다. 인터넷에서 다운받아서 ffdshow를 설치하시기 바랍니다. FFDShow는 오픈소스로서 공개되어 있습니다. 여기에는 XVid, DivX를 비롯하여 아무튼 Mpeg 압축의 스탠다드 코덱들이 총 망라되어 있습니다. 곰TV도 이 소스를 가지고서 만들었다는 이야기가 있는데요, 확인해 보지 않아서 모르겟습니다만 충분히 가능성 있는 이야기입니다. 만일 여러분이 Mpeg 알고리즘을 공부한다면 기초가 될 소스가 바로 이 FFDShow 소스일 것입니다. 혹시 FFShow를 찾기 힘들다는 분은 XVid 코덱을 다운받아 설치하시면 될것 같습니다. 아무튼 해결하시고요...  (FFDShow는 실행판과 소스판이 별도로 존재합니다. 이곳 자료실에 소스판을 올려놓아도 좋을까 고민이 좀 되네요.)

문제가 해결되었다고 보고요, graphedit를 보시면 화면 가득히 박스들이 보이실 것입니다. 그런데 이 박스들이 그냥 있는게 아니라 화살표를 꽁지에 꽁지를 물고 늘어져 있는 것이 보이실 것입니다. 이 박스 하나 하나가 바로 필터객체를 의미하며 화살표의 연결방향이 바로 연속적인 스트림의 진행방향을 의미합니다.

일단 여기까지 설명하고 실행을 시켜 보도록 하겠습니다. 위의 단축버튼중에서 왼쪽에서 여덟번째을 보시면 일반적인 동영상 실행 아이콘으로 표시된 스피드 버튼을 찾으실 수가 있을 것입니다. 이것을 클릭하시면 별도의 동영상 랜더링 윈도우가 뜨면서 동영상이  재생되는 것이 보일 것입니다. 자 별로 대단한 것은 아닙니다만 우리는 간단히 동영상을 로딩해서 랜더링하고 있는 것입니다. 

이제 윈도우를 종료하고 다시 GraphEdit로 돌아와 봅니다. 화면 상단에 가득 채워진 정체불명의 박스들을 한번 마우스로 집어서 이동시켜 봅니다. 여러분이 원하시는대로 움직이는데 유독 화살표는 자신이 원래 잡고있던  위치에서 벗어나지 않으려고 늘어지거나 줄어들거나 할뿐입니다.
즉 스트림의 방향은 수정할 수가 없다는 말인데요 이것은 사실 중요한 의미입니다만, 여기서는 단지 그렇다라고 이해하시면 되겠습니다. 여기서 박스(이하 필터라고 하겠습니다.)을 클릭한채 Delete키를 누르면 선택한 필터를 삭제할 수도 있습니다. 지금 삭제하지는 마십시요. 나중에 확인하도록 하고요, 여기까지를 일단 정리하여야 하겠습니다. 

[2] 필터들의 연결과 방향.

그래프 에디터에 보이는 수많은 필터들을 보시면 화살표 방향이 왼쪽에서 오른쪽으로 흘러간다는 것을 확인하실 수가 있을 것입니다. 이것을 좀더 자세히 들여다보죠. 일단 가장 왼쪽에 있는 필터를 우리는 소스필터라고 부릅니다. 말 그대로 스트림의 근원이라고 생각하시면 됩니다. 여기서부터 모든 스트림이 시작될 것입니다.

그리고 그 다음 필터를 보시면 AviSplitter 필터를(혹시 여러분이 일반적인 영화 파일이 아니라 조금 예외적인 동영상을 오픈했다면 이 필터가 보이지 않으실 수도 있습니다.) 보실수가 있는데요, 이것을 파서 필터라고 합니다. 파서필터에 대해서는 나중에 다시  설명할 기회가 있을 것입니다.

그리고 여기서 스트림이 비로소 두개로 나눠지게 되는데요, 위쪽으로 흘러가는 화살표 방향으로는 비디오 스트림이, 그리고 아랫쪽의 방향으로는 오디오 스트림이 각각 흘러가게 됩니다. 그런데 중요한 것은 여기까지의 스트림은 아직까지도 압축된 상태라는 점입니다. 다시 말하면 비디오 영상을 기준으로 각각의 프레임의 데이터 크기가 동일하지 않다는 말이죠.

예를 들어 320*240의 화면에 RGB24라면 320*240*3 byte씩의 데이터가 버퍼링되어 흘러가는 것이 아니라는 것이죠. 여기까지는 압축된 데이터이기 때문에 어떨때에는 9kByte가 되었다가  또 어떨때에는 몇백Byte가 되었다가 합니다. 물론 Mpeg 압축일 경우이고요, 만약에 동영상 스트림이 Jpeg로 압축되었다면 마찬가지로 각 프레임의 데이터 크기가 변하겠지만 Mpeg처럼 엄청나게 변하지는 않겠죠. 
( 상식에 속하지만 혹시 모르는 분을 위하여 간단히 설명하겠습니다. 동영상을 압축하는 방식으로는 일반적으로 프레임을 기준으로 앞프레임과 뒷프레임을 비교하여 그 차이점을 예측,비교하여 압축하는 기업이 있습니다. 이것의 대표적인 방식이 Mpeg방식이라고 합니다. 이러한 방식은 키프레임을 중심으로 변화량을 예측하거나 차이점만을 추려내어 압축하기 때문에 스트림의 변화가 상당히 큽니다.) 

다시 간추리자면 AviSplitter필터에서 갈라져 나온 두개의 스트림은 각각 영상과 음성의 스트림이며 여기까지는 압축된 데이터가 흘러가고 있다는 점입니다. 그리고 그 다음으로 비로소 압축을 해제하는 DeCoder필터가 붙게 되는데요, 각각 영상 DeCoder 코덱과 음성 DeCoder코덱이 붙게 됩니다.
이 각각의 DeCoder 필터에서 흘러나오는 스트림이 비로소 압축이 해제된(다른 말로는 뻥튀기되어 데이터가 엄청 불어난) 데이터이며 이것을 가지고 여러가지 합성을 하거나 변형을 하거나 할수가 있는 것입니다. 그리고 다음으로는 완전한 동영상 스트림 데이터를 랜더링할 수 있는 랜더러 필터가 붙게 되는 것이죠. 물론 각각의 비디오 랜더러 필터와 오디오 랜더러 필터를 의미합니다.  이것을 한번 부족하나마 도식으로 그려봅시다. 


  소스필터 --> 파서필터 --> 비디오 DeCoder 필터 --> 비디오 랜더러 필터. 
                             |-----> 오디오 DeCoder 필터 --> 오디오 랜더러 필터. 


자... 이제 간단하게나마 결론을 내 봅시다. DirectShow는 필터들의 연결이며 이 각각의 필터는 시작과 끝이 있다.
즉 소스필터로 시작해서 랜더러 필터로 끝난다. 여기까지 대충 정리가 되었다면 다음으로 넘어갑시다.
(우리는 나중에 이러한 필터들을 직접 코딩상에서 구현하여 연결하고 랜더링까지 할 것입니다. 간단하죠. 필터를 만들고 연결하고 랜더링한다. 이것이 DirectShow의 전부입니다. 한가지 개인적인 생각입니다만 마이크로소프트 계열의 소프트웨어적인 특성은 내부는 어쩔수 없이 복잡하지만 전체적인 구조는 간단하게라는 슬로건을 내걸고 있는 듯 싶습니다.
이것은 볼랜드 진영의 전체적인 구조는 복잡해도 좋지만 내부는 될수 있으면 간결하게라는 방향과 완전히 반대적인 성향인 것 같고요... 물론 완전히 제 개인적인 생각이지만요. 그래서 마소는 항상 시장변화에 유들유들할 수가 있는 것이고 볼랜드는 그러한 변화의 대처에 늦을 수밖에 없는 것이 아닌가 싶네요. 모든지 장점이 있다면 단점이 있듯이, 이제부터 여러분은 이 악몽같이 복잡한 DirectShow의 내부로 초대받아야 할 것입니다.)

[2] 여러가지 필터들의 카테고리.

이제 여러분은 GraphEdit의 다른 면을 보셔야 합니다. 조금더 디테일하고, 조금더 번거로우며, 조금더 난해한 구조에 익숙해져야 합니다. 동영상을 Render Media File... 로 간단하게 로딩하여 랜더링하였지만, 실은 이것들이 거저 연결된게 아닌 것입니다. 자, 이제 우리는 동영상을 랜더링하는게 아니라 USB 카메라로부터 받아 들여진 스트림을 랜더링해야 합니다. (USB카메라가 없다면 DShow를 배우기에 아직 준비가 덜 되었다는 의미가 됩니다. 가능하면 USB 카메라를 준비하셔서 그것의 해당 디바이스 드라이버를 설치하시기 바랍니다. )

GraphEdit의 메뉴중에서 New를 눌러서 기존에 있던 필터들의 연결을 제거합니다. '저장하기'라는 옵션이 뜬다면 저장하지 말고 '아니오'를 선택합니다. 이제 GraphEdit의 메인화면이 깨끗해 졌을 것입니다. 여기에서 우리는 카메라에 해당하는 소스필터를 생성해야 합니다. 이러한 필터를 우리는 직접 불러와 줘야 하는데요, GraphEdit상단의 단축버튼 중에서 왼쪽에서 11번째의 버튼을 선택합니다. 마치 네모난 상자에 양쪾으로 조그만 꼭지점이 매달려 있는 듯한 모습을 하고 있는데요, 이것이 바로 현재 사용자의 컴퓨터에 설치되어진 각종 필터들의 나열을 보여줍니다.

이 버튼을 클리하면 윈도우가 하나 뜨면서 그 캡션에 'Which Filters do you want to insert?'이라고 적혀 있을 것입니다. 이곳에서 아무거나 클릭을 하면 바로 GraphEdit의 메인화면에 선택한 필터가 생성되어 집니다. 여기서 모든 카테고리를 살펴보실 필요가 없습니다. 중요한 카테고리를 다음과 같이 정리하였습니다.

* Audio Capture Source --> 오디오를 캡쳐하기 위한 장치(혹은 광의의 필터)들의 모음입니다. 
* Audio Compressors    --> 오디오 스트림을 압축하기 위한 필터들의 모음입니다.  
* Audio Renderers         --> 오디오 스트림을 랜더링하기 위한 필터들의 모음입니다.
* DirectShow Filters        --> 가장 중요한 DirectShow용 필터들의 모음입니다. 이곳에는 다른 카테코리에 포함 되 
                                          어 역할되어지는 필터들도 포함되는데요, 이 사항에 대해서는 아래에서 해설하겠습니다.
*Video Capture Sources  --> 비디오를 캡쳐하기 위한 장치(혹은 광의의 필터)들의 모음입니다. 
*Video Compressors        --> 비디오 스트림을 압축하기 위한 필터들의 모음입니다. 

위에서 조금 깊숙히 들어가야할 필요성이 있다고 봅니다. DirectShow Filters의 카테고리에는 온갖 잡다한 필터들이 모두 포함되게 됩니다. 이곳에는 소스필터, 파서필터는 물론 비디오, 오디오 압축과 DeCoder필터들까지 포함되게 되는데요, 그렇다면 한가지 의문이 들 것입니다. 아니 엄연히 카테고리가 별도로 있는데, 어째서 DirectShow Filters라는 카테고리에는 이렇듯 다양한 필터들이 들어가 있는 것이지? 그렇다면 뭣 때문에 처음부터 카테고리를 나눠 놓은 것인가라고... 

이 질문에 대한 해답은 이렇습니다. 처음에 말씀 드렸다시피 DirectShow는 DirectX가 나오고 나서 한참 후에나 나온 존재입니다. 그 이전에 동영상 관련 프로그램을 하기 위해서는 VFW라는 API를 지원하였고요, 그것에 맞는 각각의 장치들이 존재하였던 것입니다. (아니, 엄밀히 말하면 장치 드라이버가 먼저 제공되었고 나중에 그것을 제어할 수 있는 VFW라는 API가 지원되었다라고 해야 맞을 것 같습니다.) 

여기에 나중에 DirectShow가 탄생하면서 기존의 구조를 흡수하는 방식을 취했습니다만 그것은 완전한 방식이 될수가 없었습니다. 왜냐하면 여러분도 보시다시피 DShow라는 놈이 참으로 유별나며 COM계열중에서도 그 독특성이 유별난 놈이기 때문입니다.
(사실은 DShow가 독특해서 완전한 합병을 할수가 없었다라는 표현은 정확한게 아닙니다만 DShow의 유별난점을 강조하기 위해 한 말입니다. 보다 사실적으로 말씀드리자면 기존의 VFW적인 방식은 Class방식이 아닌 라이브러리(dll) 적인 구조를 가지고 있었기 때문에 어쩔수가 없었다라고 보시면 될것 같습니다. 하지만 그럼에도 불구하고 DShow의 유별난 COM구조가 이렇게 중복 병합되는 카테고리 구조를 유발시켰다라고도 볼수가 있을 것입니다.)

아무튼 그래서 위에서 말씀드린 각각의 카테고리는 예전 VFW의 방식으로서 존재하는 것들입니다. 자, 한가지 예를 들어 봅니다. 위의 카테고리에는 Video Compressors라는 것이 있습니다. 이곳을 들여다보면 각종 압축 코덱들이 모여 있는 것을 보실 수가 있습니다.
그런데 다시 DirectShow Filters라는 카테고리를 들여다보면 여기에도 압축 코덱들이 한두개 눈에 보이실 수도 있습니다. ( 현재까지는 한개도 보이지 않을 수도 있습니다. 그러나 DirectShow관련 코덱들을 한두개 설치하다보면 어느새 이곳에도 압축코덱필터가 자리잡고 있는게 보이실 것입니다.) 자, 이 두개의 코덱의  성격은 어떤 점에서 다른 것일까요? 

예전에 저는 XVid의 소스를 해석한 적이 있었습니다. 여기서 저는 XVid라는 코덱의 소스가 실은 두가지로 되어 있는것을 보고 놀라기도 하였습니다. 그것은 내부에 하나의 완성적인 압축 로직이 있고, 이것을 DirectShow 필터 구조가 감싸고 있는 구조였기 때문입니다. 즉, 예전의 VFW 코덱의 구조를 안에 두고 그것을 다시 DirectShow 필터의 클래스 구조가 감싸안으면서 버퍼의 포인터만 연결되어져 있다는 점이었습니다. 

자, 이제 결론지어 보겠습니다. 위에서 보여드린 각각의 카테고리는 예전 VFW 방식의 분류를 의미합니다. 따라서 과거처럼 VFW의 API를 사용해서 완전히 동일하게 접근할 수가 있음을 의미합니다. 그러나 VFW방식으로는 결코 DirectShow Filters라는 카테고리에 속한 영역의 필터들에 접근할 수가 없습니다. 이들 필터들은 오직 DShow방식의 연결로서 사용되어 집니다. 또한 DShow방식은 과거 VFW 방식의 모든 카테고리에 접근하여 DShow방식으로 취급할 수  있는 서비스를 제공합니다. 이것이 바로 DShow(DirectShow) 이고, 차이입니다. 

만일 누군가가 VFW구조로 압축코덱을 개발하였다면 그는 오직 Video Compressors 카테고리에 설치할 수밖에 없습니다. 반대로 그가 DShow방식으로 압축코덱을 개발하였다면 그는 DirectShow Fitlers라는 카테고리에 코덱을 설치해야 할 것입니다. 하지만 DShow는 이 두가지 구조의 코덱을 동일한 방식으로(DShow적인 방식으로) 생성하여 실행시킬 수가 있습니다. (가물가물 한데요, DShow방식으로 압축 코덱을 개발하였다고 하더라도 Video Compressors 카테고리에 설치할 수가 있었는지... 가물가물하네요. 하지만 한가지 확실한 것은 그 반대는 안된다는 것입니다.)  

 

출처 : 델마당 dong (dongsoft) 님의 글


posted by 유돌이