유돌이

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

Notice

2008. 12. 29. 23:35 델파이

GraphEdit에 대한 설명을 위해 1,2편으로 나누었습니다. 그만큼 워낙 DShow에서는 중요한 유틸이라 설명해야할 부분이 많기 때문입니다. 
 
[1] 카메라 영상을 플레이하기.
 
강의를 하려고 보니까 GraphEdit의 왼쪽에서부터 11번째의 단축버튼을 눌렀을때 나오는 윈도우의 명칭을 무엇인가로 지칭하는게 편리할 것 같습니다. 매번 11번째 운운하면서 설명하는 것 보다는 앞으로는 '필터삽입윈도우'라고 부르겠습니다. 자, 필터삽입윈도우에 보시면  Video Capture Source 라는 카테고리가 보이실 것입니다. (계속해서 제가 카테고리라고 표현하는데는 다 이유가 있습니다. 실제로 이것은 프로그래밍 상에서 카테고리로 되어 있으며, 나중에 여러분은 이 카테고리에서 필요한 필터들을 골라내는 로직을 작성해야 할 것입니다.).
만일 여러분의 컴퓨터에 USB 카메라가 설치되어 있다면 이곳에 분명히 1개 이상의 필터가 존재해야 합니다. (DSHow를 공부할 때에는 반드시 USB 카메라가 한대 쯤은 있어야 한다.) 일단 그것을 선택하면 GraphEdit의 메인화면에 필터가 생성되어 질 것입니다. 자.. 이것은 일종의 광의의 소스필터이고, 좁게는 비디오 입력장치라고 부릅니다.

이제 여기서부터 나오는 스트림을 랜더링해야 하는데요, 그러자면 랜더링 필터가 필요합니다. 마찬가지로 필터삽입윈도우에서 이번에는 DirectShow Filters 카테고리에 들어가 봅시다. 여기에는 많은 수의 DirectShow 필터가 존재하고 있습니다. 이 말은 즉 오리지널 DShow 클래스(실은 COM 인터페이스) 내부구조를 하고 있다는 것입니다. 여기에서 Video Renderer 필터를 선택합니다. 조금 아랫쪽에 있을 것이므로 스크롤바를 밑으로 조절하셔야 할 것입니다. 

자, 이제 GraphEdit의 메인화면에는 두개의 필터가 놓여져 있을 것입니다. 왼쪽에 카메라 필터를, 오른쪽에 렌더러 필터를 위치시켜 놓은 다음에 카메라 필터의 오른쪽 꼭지에서 마우스로 콕 집어서 드래그 하여 랜더러 필터의 왼쪽 꼭지점에 갖다가 놓습니다. 이제 두개의 필터가 연결되었을 것입니다. 그런 상태에서  위쪽의 단축버튼 중에서 동영상 실행 버튼을 클릭하여 봅시다. 새로운 윈도우가 뜨면서 카메라로부터 들어온 영상이 렌더링 되는게 보여질 것입니다.   

[2] Video Renderer 필터

Video Renderer 필터의 종류가 3가지가 되는 것을 볼수 있을 것입니다. 이것에 대한 설명을 하자면 장황해 지겠으니, 가능하다면 간략하게 설명해 드리겠습니다. 일단 VMR Renderer 와 두개의 Video Renderer을 보실 수가 있을 것입니다.

이 VMR Renderer은 영상합성과 관련된 아주 중요한 필터입니다. 그래픽카드에서 이 서비스를 지원해 줘야 사용할 수가 있는 필터입니다. 이것이 무슨 말인가 하면... 일반적으로 영상을 합성한다면 버퍼링이 발생하게 됩니다. 320*240사이즈의 버퍼링이라면 문제가 되지도 않겠죠. 하지만 640*480 이상의 영상을 실시간 합성하고자 한다면 버퍼링이 엄청나게 문제가 됩니다.
왜냐하면 영상을 합성하는 알고리즘을 시스템 성능에 따라 조절해야 하기 때문입니다.
즉, 시스템 성능이 낮으면 그에 합당한 간단한 알고리즘을 사용해야 하고, 시스템 성능이 높으면 그에 따라 선명도을 증가시킬 것인가(640*480에서 720*480으로 좀더 선명한 화질의 소스에서 합성할 것인가), 아니면 합성시 거칠게 나타나는 부분을 알고리즘으로 부드럽게 처리하는  로직을 첨가할 것인가를 선택해야 합니다. 이러한 아주 긴밀하고 섬세한 선택은 물론 시스템 단가, 혹은 시장성의 선택과 결과물의 쿼리티와의 긴박한 관계에서 수많은 테스트를 거쳐서 판단하게 될 것입니다.
그러나 결론적으로 말씀을 드리자면 곧 한계가 발생하겠죠. 사람들은 환상적인 허리우드영화에 익숙해져 있기 때문에 웬만한 합성 결과물에는 반응하지 않게 되었기 때문입니다. 비록 그곳에 자신의 모습이 나온다고 할 지라도 말이죠. 

그래서 혹시 들어봤는지 모르겠지만 동영상 편집보드라는 특수한 보드를 사용하는 것입니다. '프리미어'라는 소프트웨어로 한번이라도 영상을 편집해 보신 분들은 아시겠지만, 동영상의 사이즈가 클수록 편집하는데 오랜 시간이 걸린다는 것을 잘 아실 것입니다. 이 편집보드는 가장 싸구려인 매트록스의 70만원짜리부터 수천만원이상가는 고가에 이르기까지 다양하게 시장에 나와있는 것으로 알고 있습니다.

자, 다시 돌아와서, 이러한 상태에서 영상을 합성하는 어떤 기능이 그래픽카드에 존재한다면 얼마나 좋겠습니까. 그렇다면 CPU에서 메모리에 적재된 데이터를 불러들여서  별도로 합성할 이유가 없을 터이죠. 만일 그렇게 된다면 수십만원 짜리의 영상편집보드를 별도로 구입할 필요가 없어지고 상업용 시스템 단가가 그만큼 떨어질수가 있다는 말이 됩니다.   

저희가 한창 영상합성 시스템을 개발할때에 DriectShow는 이 VMR 필터를 지원하지 않았습니다. 그래서 우리는 어쩔 수 없이 CPU를 사용해서 영상을 합성할 수밖에 없었는데요, DirectX SDK의 버전이 9.0을 넘자 VMR이라는게 생긴 것이었습니다. 그당시 얼마나 기뻤는지 모릅니다. 이것을 사용하면 CPU의 부담을 그만큼 줄일 수가 있고, 그렇다면 좀 더 복잡한 합성 알고리즘으로 합성된 영상물의 거친 부분들을 다듬을 수가 있을 터였기 때문이었습니다.

그러나 아쉽게도 그당시 그래픽카드가 VMR을 지원하는 것은 단 하나였고, 그나마 매트록스의 그래픽 카드는 지원이 되지 않았습니다. 매트록스 회사에 전화를 걸어보니 DirectShow 9.0을 완벽히 지원하려면 6개월 이상이 걸릴 것이라는 이야기를  들어야 했습니다. 물론 이 이야기는 아주 오래적의 일입니다.
제가 이런 이야기를 하는 것은 VMR Renderer이란 무엇인가를 아주 효과적으로 여러분에게 납득시킬 수가 있기 때문입니다. 아무튼 우리 회사로서는 반드시 매트록스 그래픽 카드를 사용해야만 할 터였습니다. 모든 시스템이 이 그래픽 카드에 맞춰져 있는 상태였기 때문이죠. 해서, 그당시 VMR Renderer를 결국 포기해야만 했던 경험이 있습니다. 

위의 이야기를 듣고 조금 이상하다고 생각하는 분들도 있을 것입니다. 그 분들은 DShow의 VMR Renderer을 어느정도 알고는 있으시는 분들이겠죠. 그렇습니다. VMR Renderer에서의 영상 합성의 결과물은 소프트 웨어적으로 저장할 수가 없는 것입니다. 왜냐하면 그래픽카드에서 영상이 합성되기 때문에 거기가 종착역이기 때문입니다. 물론, DriectX 의 DirectDraw 평면을 제공하기 때문에 이것을 가져와서 다시 저장할 수는 있습니다. 실제로 VMR Renderer은 이렇게 DirectDraw평명을 억세스하기위한 인터페이스를 제공하는 것으로 알고 있습니다. (하도 오래전 일이라 가물가물 하지만 본 것 같음. 아니면 말고...) 그러나 이런 방식으로 합성된 결과물을 다시 받아서 저장하는 DShow 프로그래밍은 하지를 않을 것이라고 봅니다. 이것은 로컬인 파라독스 DB를 가지고 네크워크 방식이라고 해야할까요, 아무튼 그렇게 사용하는 것과 마찬가지라고 봅니다. 차라리 그럴봐에야 직접 그래픽카드의 DreictDraw 평면을 이용하는 것이 좋지 않을까 싶네요. 어쨌든, 또다시 이야기가 삼천포로 빠졌습니다. 

VMR Renderer에서 합성된 영상을 소프트웨어적으로 저장할 수가 없다는 말은 맞습니다. 그렇다고 저장하지 못한다는 것은 아니고요. 결론적으로 말씀드려서 저장할수가 있습니다. 정확히 말하자면 DSHow의 방식으로 저장을 못한다는 말이고요, DirectDraw 평면을 직접 억세스하는 소프트웨어적이거나 혹은 우회로 돌려서 저장하는 방식이 있습니다. 즉 모니터에서 나오는 영상을 다시 자신의 컴퓨터 입력장치로 보내어 그것을 저장하는 것입니다.  

VMR Renderer을 설명하자면 한도끝도 없습니다. VMR Renderer이전에는 오버레이 믹서라는 필터를 제공하였습니다. 아마 지금도 DirectShow Filters 카테고리에 보시면 찾을 수가 있을 것입니다. 이 Overlay Mixer라는 필터는  마찬가지로 그래픽카드의 오버레이 평면을 이용하여 합성을 하는 방식입니다. 예전에는 동영상의 자막 처리를 이것으로 하였던 적이 있습니다. 지금도 그렇게 하는지는 모르겠습니다.

지금은 훨씬 다양한 방법론이 존재하기 때문입니다. VMR Renderer이 처음 나왔을때, 이것이 환상적이었던 것은 알파브렌딩 합성을 가능하게 해준다는 것이었습니다. 즉 평면의 구조가 RGB24가 아니라 ARGB32였던 것입니다. 여기서 A는 알파채널로서 아마도 포토샵을 조금만 사용해 보셨던 분들은 알파채널이 무엇인가를 알고 계실 것입니다. 이 말은 영상합성에서 그 상대적인 깊이를 마음껏 조절할 수가 있다는 의미인 것이죠. 자... 이쯤에서 VMR Renderer에 대한 설명은 접기로 하겠습니다. 

이제 나머지 두개의 동일한 이름의 Video Renderer에 대해서 설명드리겠습니다. 두개는 이름만 동일할뿐 실제로 랜더링하는 방식은 내부적으로 다릅니다. 하나는 구버전의 Video Renderer이고 하나는 나중에 VMR Renderer의 또다른 모습입니다. 즉 두개의 Video Renderer를 모두 순서대로 선택하여 GraphEdit에 생성해 놓으신다면 하나의 필터에는 입력핀쪽에 VMR 이라는 명칭이 붙어있는 것을 보실수가 있습니다. 그렇다면 대체 VMR Renderer는 무엇이고 요놈은 또 무엇인지 헷갈릴 것인데요. 간단하게 말하자면 Interlace를 받아서 처리하는 놈이라고 보시면 됩니다. 

자, 이제 종합해보겠습니다. DirectShow Fitlers 카테고리에는  렌더러 필터가 3개가 있다. 하나는 VMR Renderer9이고, 나머지 두개는 이름이 동일한 Video Renderer이다. 그렇데 나머지 두놈의 동일한 이름의 필터를 GraphEdit에다 생성해 놓고 보니 하나의 필터에는 입력핀쪽에 VMR이라고 붙어있다. 이것은 VMR Renderer9를 생성시켰을때와 동일하다. 대처 무엇때문에 이따위 짓을 해 놓았는가. 그 이유는 Interlace방식의 입력 스트림을 처리하기 위함이고, Interlace 방식이란 무엇인가는 인터넷을 찾아서 공부하시길 바랍니다. 

[3] 그래프의 저장.

현재까지 실행을 하셨다면 GraphEdit 의 메인화면에는 두개의 필터가 달랑 연결되어 있는 것을 보실수가 있을 것입니다. 이 상태를 그대로 파일로 저장했다가 나중에 다시 열어서 간단히 실행시키실 수가 있습니다. 메뉴에서 Save Graph를 선택하면 저장하기 다이알로그가 뜨는데요, 일반적인 파일저장처럼 하시면 됩니다. 이 기능은 프로그래밍적으로 사용하려고 했습니다만, 이상하게도 DirectShow의 도움말에는 그런식으로 사용하지 말라고 권고하고 있습니다. 이게 무슨 말인가 하면요...

우리는 앞으로 수많은 필터들을 생성해서 수동으로 연결해야 합니다. 적게는 대여섯개에서부터 많게는 20개 정도의 필터까지도, 혹은 그 이상이라도 필요하다면 연결해야 합니다. 그런데 이 과정에서 시간이 조금 걸립니다. 아주 짧은 시간이지만 일반 사용자들은 1초 이상의 짬을 지루해합니다. 그런데 15개 이상의 필터를 생성하여 연결하다보면 심지어 2~3초 정도가 걸리기도 합니다.(시스템 사양이 낮은 컴퓨터에서) 그런데 GraphEdit처럼 이러한 상태를 아예 파일로 저장했다가 불러들여서 실행한다면 굉장히 속도가 빠르지 않을까라고 생각했던 적이 있습니다.
실제로 그러한 코딩이 가능하고, 그러한 예제 샘플까지 존재합니다. 그러나 이상하게도 DirectShow 도움말 파일에서는 그런식으로 프로그래밍적인 사용을 하지 말라고 거의 강권하고 있습니다. 이러한 이유에 대해 개인적인 추측이 가능합니다만, 아무튼 이것은 저의 개인적인 추측일 뿐이이서 이곳에 기술하지는 않겠습니다. 

[4] Connect to Remote Graph

메뉴에 보시면 위의 제목을 한 기능이 있습니다. 이것은 참으로 유익한 기능인데요, 잘만 활용한다면 꽤 훌륭한 뚫어 기능이 됩니다. ^^. 이게 무슨 말인가 하면요, DShow 프로그래밍은 일반적인 DLL 프로그래밍과 마찬가지로 디버깅이 아주 골치가 아픕니다. DShow의 필터 하나하나도 ax 확장자만 가지고 있을뿐 실제는 DLL과 거의 비슷한 사용자 억세스 관점을 가지고 있습니다. 그래서 한번 버그가 발생하면 대체 어디에서 발생하였는지 감을 잡기가 힙듭니다. 

수십개의 필터들을 동적으로 연결시켜 놓았는데요, 그중 어느 한 부분이 연결되지 않은채 굴러간다면, 대체 어느 부분에서, 몇번째 필터에서 연결이 끊겼는지를 직접 확인해야 할 필요성이 있습니다. 여기까지는 다른 방식으로 어떻게든 알아낼 수가 있겠지요. 그런데 문제는 그 다음입니다. 분명히 연결은 제대로 되었는데도 불구하고 작동이 안되는  경우, 정말로 연결이 되었는지 눈으로 직접 보고 싶어질 때가 있습니다. 

이럴때 여러분이 만든 DShow 프로그램을 실행시킨다음 GraphEdit의 Connect to Remote Graph 메뉴를 사용하신다면, 현재 여러분이 만들어서 실행되는 DShow 프로그램의 내부 필터들의 연결을 그대로 GraphEdit에 나타내게 하실 수가 있습니다. 물론 이 기능을 위해서는 여러분의 DShow어플에 약간의 (한줄 정도의) 추가 코딩이 필요합니다. 
여기에 대해서는 뒤에 가서 간단히 실습해 보도록 하겠습니다.  
 
출처 : 델마당  dong (dongsoft) 님의 글
posted by 유돌이