항공기나 선박 자동차 등에 설치돼 이동 경로와 시간 등의 운항 정보를 자동으로 기록하는 저장 장치 '블랙박스'는 오늘날 흔하게 볼 수 있을 정도로 보편화되었다. 덕분에 예기치 못하게 일어나는 교통사고에도 그 원인을 밝히기 편리해졌으며, 때때로는길거리에서 일어나는 각종 범죄 사건의 증거물이 되기도 한다.

'NDC 2017'의 두 번째 날, 원더피플의 윤대웅 TD는 과거 넥슨에서 재직하던 시절 개발한 '개발자를 위한 블랙박스'를 주제로 강단에 올랐다. 차량용 블랙박스가 사고 원인을 밝히기 편리하게 만들어줬듯, 개발자용 블랙박스는 게임에서 발생하는 버그를 발견하고, 리포팅을 더욱 편리하게 만들어 보자는 취지에서 개발된 셈이다.

하지만, 차량용 블랙박스가 단순히 주행하고 있는 도로를 계속 촬영하는 도구라고 생각해 본다면, 게임플레이 영상을 녹화할 수 있는 프로그램은 이미 시중에 많이 나와있는 상태. 과연, 이미 상용화된 녹화 프로그램 외에 개발자들을 위한 '블랙박스'가 필요했던 다른 계기는 무엇이었을까? 윤대웅 TD는 자신의 블랙박스 개발 사례를 중심으로 이야기를 시작해 나갔다.

▲ 원더피플 윤대웅 TD




▲ 목적 및 기능은 차량용 블랙박스와 다르지 않다

블랙박스는 간단히 말하면 게임 플레이 영상을 상시 녹화하는 애플리케이션이다. 녹화된 게임 플레이 영상을 통해 버그를 개발자가 직접 눈으로 볼 수 있고, 해당 버그가 실제로 발생했다는 증거로서 역할을 수행할 수 있다. 또한 FGT 등에서 게임플레이를 분석하거나 유용한 성능 분석 자료로도 쓰일 수 있다는 특징을 가지고 있다.

프랩스나 반디캠 등 기존 동영상 녹화 프로그램과 다른 점 또한 가지고 있는데, 블랙박스의 경우는 넥슨에서 서비스하는 게임 중 사전에 등록된 게임에 대해서만 구동이 되며, 촬영을 위해 버튼을 누를 필요 없이 플레이 과정이 항상 녹화된다. 또한, 버그 발생 시 원활한 리포트를 위해 JIRA에 녹화 영상과 로그 등을 포함해 즉시 보고할 수 있는 기능 등을 지원한다.

상시 녹화 기능으로만 보면 NVIDIA의 쉐도우플레이 등과 같은 더 나은 콘셉트의 상용 애플리케이션이 존재한다. 그럼에도 상용 레코딩 라이브러리를 사용하지 않은 이유는 다음과 같다.


먼저, 레코딩을 위해 획득한 화면을 가공하여 응용할 수 있는 가능성이 있는데, 영상 위에 사용자 입력이나 성능 정보, 처리된 에외 등을 쉽게 추가할 수 있으며, 게임 플레이 도중 게임이 느려지는 등의 랙(Lag) 현상을 그대로 녹화하는 것도 중요했다. 이와 같은 요소들을 통해 유저들에게 방송을 하거나, 또는 승인을 받는다면 멀리 있는 개발자의 화면을 보는 것도 가능하다.

블랙박스 앱은 말 그대로 자동차에 설치하는 블랙박스와 같이 정보의 수집과 보고에 중점을 두자고 생각했다. 본 세션에서는 블랙박스에 사용된 캡쳐 및 영상, 사운드 녹화 기술과 그밖에 다양한 기술들을 넓고 얇게 소개할 예정이며, 촬영된 영상을 바탕으로 ‘블랙박스’ 기능을 하는 애플리케이션은 개발할때까지의 과정을 설명하고자 한다.


본격적인 설명에 앞서 소개할 것이 블랙박스 프로그램의 데모 시연이다. ‘메이플스토리'와 ‘던전앤파이터'를 동시에 실행시키고, 윈도우 트레이에 있는 블랙박스를 실행시키면 두 게임 모두를 각각 녹화하고 있는 것을 확인할 수 있다.

실시간 녹화가 진행되고 있음에도 게임 성능에는 크게 영향을 주지 않으며, 플레이 도중 특이 사항을 발견했을 경우에는 ‘보고하기’ 버튼을 클릭하거나 단축키를 활용해 JIRA를 오픈, 편리하게 이슈를 보고할 수 있다. 또한 그림판과 연결해 스크린샷을 편집해 첨부 파일로 넣을 수 있는 등 소소한 기능도 제공하고 있다.

프로그램에 존재하는 ‘보고하기’를 클릭해 버그리포트를 작성하게 되면, 본문에 영상과 스크린샷이 포함되고, 블랙박스가 작동하면서 수집한 CPU 및 GPU의 정보가 자동으로 기재된다.


지금부터는 동영상 촬영을 위한 사전 지식을 공유하고자 한다. 게임 플레이가 동영상이 되기까지는 비디오 소스와 오디오 소스가 각각 필요하며, 이 소스들은 인코딩과 먹싱 과정을 통해 컨테이너에 담겨 동영상이 된다. 컨테이너는 간단히 확장자라고 부르기도 한다. AVI, WMV, MP4 등 다양한 비디오 파일 컨테이너 포멧이 존재하며, 각각 지원하는 코덱 등이 다르다.

코덱은 인코더와 디코더를 합한 용어로, RAW 데이터의 어마어마한 용량을 압축/해독하는 과정을 거쳐 우리가 보는 동영상 파일로 변환하는 역할을 한다. 마찬가지로 여러 가지 코덱이 존재하지만, 아무 생각 없이 H.264 코덱을 사용하는 것을 추천한다. 우선 브라우저 호환성이 높고, HTML5를 완벽하게 지원하는 등 사실상 업계와 방송의 표준이 되어있기 때문이다.

레코딩을 위한 API및 소프트웨어, 라이브러리는 마이크로소프트가 제작한 비디오 포 윈도우즈, 다이렉트쇼, 미디어파운데이션 등과 사실상 업계의 표준으로 봐도 무방한 FFmpeg등이 존재한다. 다만, FFmpeg의 경우 라이선스가 복잡하고, 종속성과 관련한 문제도 가지고 있다.


초기 ‘블랙박스’에서는 비디오 포 윈도우즈를 채택했다. 윈도우XP 지원을 고려해서 내린 결정이었고, 컨테이너는 avi, 코덱은 H.264를 사용하기로 계획하고, 이슈 보고에만 MP4로 변환하고자 했다. 이러한 과정에서 문제는 H.264 코덱을 따로 깔아줘야 하는 번거로움과 설정 UX가 복잡해 잦은 오류가 발생한다는 것이었다. 또한 비디오 포 윈도우즈 자체가 너무 오래되어 어렵기도 했다.

이후에는 XP 지원을 포기하면서, 미디어 파운데이션을 사용하는 방향으로 결정했다. 윈도우 비스타와 7이후 운영체제만을 지원하면서, 최소 종속성으로 비디오 및 오디오 코텍을 모두 지원하자는 계획이었다.

미디어 파운데이션은 MP4컨테이너를 기본적으로 지원하며, H.264 및 AAC코덱 인코더 API가 내장되어 있었다. 호환성이 약간 떨어지긴 하지만 바로 사용할 수 있다는 것은 장점이 되었다. 또 FFmpeg를 사용할 일이 없다는 것과, 최소한의 종속성으로 배포가 편리한 것 또한 장점이다.


화면 캡쳐 소스를 획득하는 방법에는 다음과 같은 것들이 있다. 먼저 데스크탑의 Device Context를 획득해 비트맵을 생성하는 GDI를 사용하는 법인데, 이는 게임 화면 캡쳐의 성공 자체를 보장할 수 없는 방법이다. 또한 성능이 매우 느려 스크린샷 용도로는 몰라도 매 프레임마다 캡쳐를 하기는 불가능하다.

다음은 Direct3D 9을 사용하는 방법이 있다. 데스크탑 화면의 게임 윈도우를 찾아서 해당 사이즈만큼 클립한 결과물을 얻는 방식으로, 만약 게임 화면이 특정 창에 의해 가려진다면 그 또한 그대로 녹화되는 문제가 발생한다.

게임에 직접 연동해 백버퍼를 취득하는 방법도 있는데, 이 방법을 초기에 진행해본 적이 있지만 디바이스 로스트에 취약하고, 다수 프로젝트에 연동하는 것이 불편하는 등 문제를 확인했다.

Windows Media 9 SDK를 사용하는 방법도 존재한다. 화면을 캡쳐해 WMV파일로 출력하는 방법으로, 일부 브라우져에서는 따로 설치가 필요하고, WMV 출력은 고려하지 않아 테스트하지는 않았다.

윈도우8 부터 지원하는 Desktop Duplication API도 있다. API차원에서 메모리 전송을 지원하는 캡쳐 방법 중에는 성능이 가장 우월하지만, 특정 창에 화면이 가려져 있다면 그대로 녹화되므로 전체화면으로만 대응해야 하는 단점을 가지고 있다.

그 다음으로는 DirectX 버전마다 Hooking하는 방법이 있다. 이것은 프랩스 반디캠 등 넓은 플랫폼을 대상으로 한 상용 녹화 애플리케이션들이 사용하는 방법인 만큼 효율적이지만, 블랙박스를 위해서는 선택할 수 없었다. 게임 화면 위에 런타임 에러 메시지 박스가 뜨는 것까지 녹화하고 싶거나, 윈도우 모드에서 타이틀 바까지 녹화하고 싶을 경우 등이 불가능하기 때문이었다.


그래서 선택한 것은 DWM(Desktip Window Manager)를 사용하는 것이었다. DWM은 윈도우 비스타부터 내려져 온 것으로, DWM API를 통해 일부 기능을 컨트롤하는 것이 가능했다. 윈도우7의 경우 에어로을 작동해야만 DWM GPU 컴포지션이 활성화되지만, 윈도우8 이후부터는 항상 상주하고 있다.

DWM을 고려한 이유는 바로 ALT+TAB을 눌렀을 때 활성화 된 창들의 썸네일을 실시간 갱신한다는 것을 발견한 이후였다. 썸네일 상에서 게임까지 갱신된다는 것은 윈도우가 어딘가에 DirectX 표면 형태로 화면을 가지고 있을 것이라는 판단에서였다.

DWM을 사용하면 에러 메시지나, 랙 현상, 응답 없음 등 창에서 발생하는 모든 상황을 렌더링하는것이 가능했다. 또한, 게임 뿐 아니라 대다수의 애플리케이션에서도 활용할 수 있었다. 하지만 API차원에서 캡쳐 기능을 제공하지 않는다는 문제점을 가지고 있었는데, 이를 해결하기 위해서는 Dependency Walker로 DLL을 살펴봤더니 숨겨져 있던 함수들을 발견할 수 있었다.


이 문서화 되지 않은 함수들을 분석해 정리해둔 곳을 찾아 해당 함수의 프로토타입을 획득할 수 있었고, 이를 통해서 캡쳐가 가능한지 시도해본 결과는 의외였다. 순식간에 게임 화면 텍스쳐를 가져올 수 있었던 것이다. 물론, 기존 DWM이 제공하던 유용한 기능을 전부 사용할 수는 없었지만, 대부분의 사항들은 문제 없이 활용하는 것도 가능했다.

과정은 어찌 됐든, 이것으로 블랙박스의 주 캡쳐 기술을 선정할 수 있었다. 테스트와 모니터링이 목적인 블랙박스 대다수의 경우에 적합했고, 유니티 및 언리얼 엔지 최신 버전의 에디터까지 호환성 체크도 완료했다.

영상 캡쳐를 위해서 여러 길을 돌아왔지만, 오디오 캡쳐는 비교적 간단한 원칙 하에 접근하도록 했다. 우선 짧은 지연과 마이크로 나오는 음성 채팅 소리까지 캡쳐 할 수 있는 것을 목표로, 인위저으로 스테레오 믹스를 설정하지 않고도 레코딩 할 수 있는 방법을 강구했다.


이를 위해서는 Windows Audio Session API, 일명 WASAPI를 사용하기로 했다. 윈도우의 오디오 세션을 관리하는 API인 WASAPI는 윈도우 비스타부터 사용할 수 있으며, Loopback 지원으로 윈도우 오디오 스트림의 엔드포인트에서 PCM버퍼를 획득할 수 있다.

이렇게 동영상 먹싱을 위한 두 가지 캡쳐 소스가 준비된 상황, 먹싱은 영상과 음성 소스를 추후 분리할 수 있는 형태로 합쳐주는 것을 의미하는, 영상은 H.264포맷으로, 오디오 코덱의 경우는 호환성이 높고 용량과 품질을 모두 만족하는 AAC 코덱을 사용하는 것을 선택했다.

끝으로는, 게임화면 레코더를 개발 시 고려해야 했던 점을 설명하고자 한다. 우선, 게임은 해상도 변경이 쉬운 반면, 동영상은 그렇지 못하듯 실시간 녹화 도중 게임의 해상도를 변경할 경우 또한 고민해봐야 하는 문제다. 그리고 동영상으로 만들어지는 과정에서 다운 스케일링으로 인해 게임의 성능이 비교적 향상되어 보이는 문제는 없는지 확인하는 것도 필요하며, H264의 영상 비율 제한과, 영상 크기 제한 등에 대해서 한 번쯤 공부해본 후에 들어가는 것도 좋을 것 같다.