Live555을 이용해서 RTSP로 전달되는 (엄밀히 말하자면, RTP로 전달되는) H264 스트림을 전달 받는 방법을 알 게 되었다. 그런데 막상 받아놓은 바이트 배열을 디코딩 하려고 보니 이 배열의 어디부터 어디까지를 넣어야 하는지가 막막했다. Live555에서도 h264FramedSource와 같은 소스 필터 클래스를 제공하긴 하지만 H.264자체에 대해서는 완전 까막눈이이다보니 어떻게 활용을 해야 할지는 더 막막해 차라리 디코딩을 위해 공부해야 하는 FFmpeg부터 역으로 접근하면서 H.264에 대해 공부하면 어떨까 하고 FFmpeg부터 공부하기로 결심했다.

 

사실 이전에 XProtect라고 하는 Miliestone사의 VMS로부터 한프레임의 H.264 데이터를 통으로 받아 디코딩 해본 경험은 있지만 막상 다시 새로운 프로젝트를 만들어서 공부를 하려고 하니 어떻게 FFmpeg를 Visual studio 2010에 연동했었는지 가물가물했다. 그래서 아예 이 과정을 정리해 공유하면 나도 나중에 참고해서 사용 할 수 있고, 다른사람들도 보고 좋을거 같아 연동하는 과정을 기록해 보고자 한다.

 

Step 1. 일단 라이브러리를 다운 받아야 된다.

 

물론 FFmpeg는 오픈 소스이니까 소스코드를 다운 받고, mingw와 msys으로 gcc를 활용할 수 있는 환경을 만들어 직접 빌드해 사용 할 수 있다. 그러나 그냥 나같이 라이트하게 사용만 하고자 하는 목적이라면, 이 과정이 그닥 정신건강에 유익하지 않다. 소스 코드를 컴파일 하다가 에러 하나가 띡 하고 올라와 구글링해서 고치면 다른 에러가 띡 올라오고 그 과정에서 멘탈이 남아나질 않는다.

 

<에러와 함께 내 멘탈도 부서졌다>

 

 

하지만 인터넷 세상에는 착한 사람들이 참 많다.

https://ffmpeg.zeranoe.com/

 

요기에 가보면 어떤사람이 windows에서 사용할 수 있는 FFmpeg의 빌드 결과물을 그것도 32bit, 64bit 각자의 구미에 맞게 제공하고 있다. 홈페이지에서 build탭으로 이동해 보면 현재 최신버전.. 인지는 모르겠지만, 꾸준히 최신버전의 FFmpeg버전의 빌드를 제공하는지 제법 최신 버전의 FFmpeg빌드를 제공하고 있다. 이글을 작성하는 시점으로는 git-3ecc063을 빌드해서 올려놨다.

 

 

 

 

32bit, 64bit으로 빌드 해 놓은 것은 각자가 만들고 싶은 프로그램의 빌드 타겟과 일치하는 버전의 바이너리를 다운 받으면 되겠고... Static, Shared, Dev를 설명하자면.. 음.. 일단 ffmpeg는 라이브러리가 아니다 원래는 콘솔프로그램인데 이 콘솔 프로그램이 사용하는 많은 외부 라이브러리가 있다. 그 외부 라이브러리들을 이용해서 ffmpeg라는 콘솔프로그램이 뭐 미디어 파일을 변경하고 하는 일을 하는것이다.

 

그래서 이 ffmpeg라는 콘솔프로그램을 만들때 이 외부라이브러리 소스코드를 한데다가 싹 다 모아서 하나의 exe로 만들것인지 아니면 외부라이브러리를 dll형태로 빼 내어 다소 많은 소스코드가 들어간 exe를 가볍게 할 것인지 결정할 수 있다. 전자는 static이라고 부르고 후자는 shared라고 부른다. 그래서 각각 받아보면 static은 exe 3개만 떨렁 들어 있고, shared에는 dll파일 여러개와 exe파일 3개가 들어있다.

 

마지막으로 Dev는 shared에 들어 있는 dll파일을 개발자가 사용할 수 있도록 헤더파일과 lib파일을 제공하는데 이 파일들을 이용해서 FFmpeg가 가지고 있는 기능들을 개발자가 직접 사용할 수 있게 되는 것이다.

 

뭐 어찌됐든 다 받자. 공짜다.

 

Step 2. Visual sutdio 2010 프로젝트에 연동하기

 

아래 파일들은 shared를 눌러서 다운 받은 파일들이다. ffmpeg.exe, ffplay.exe, ffprobe.exe는 모두 다른 dll로 모듈화 되어 있는 기능을 참조하여 가져다 쓴다. 우리가 visual stduio 2010 프로젝트에 연동해야 하는 기능들도 이 dll파일들에 들어 있으니 이 dll파일을 가져다가 visual studio 프로젝트의 실행파일이 생기는 폴더로 몽땅 이동시키자.

 

<다운로드 싸이트에서 shared를 선택해 다운 받은 파일들>

 

다음으로는 프로젝트에 헤더파일과 라이브러리 파일을 가져다가 사용할 차례다. 헤더파일과 lib파일은 Dev폴더의 lib, include폴더에 들어 있다. visual studio 2010프로젝트가 해당 헤더와 lib파일의 위치를 알 수 있도록 아래와 같이 Visual studio 2010의 프로젝트 속성에서 포함파일 위치랑 라이브러리 파일 위치를 지정해준다.

 

 

<추가 포함 디렉터리>

 

<추가 라이브러리 디렉터리>

 

다음으로는 이제 헤더와 lib파일의 위치를 알려줬으니까 직접 포함도 해보고 lib파일을 연결시켜보자.

콘솔 main()함수가 있는 파일에 쓰든지 아니면 미리컴파일된 헤더에 쓰든지 적당한 곳에 아래 구문을 넣으면 된다.

 

extern "C" //FFmpeg가 C라이브러리이기 때문에 이부분이 필요하다.

{

#include "libavcodec\avcodec.h"
#include "libavdevice\avdevice.h"
#include "libavfilter\avfilter.h"
#include "libavformat\avformat.h"
#include "libavutil\avutil.h"
#include "libpostproc\postprocess.h"
#include "libswresample\swresample.h"
#include "libswscale\swscale.h"

}

 

#pragma comment ( lib, "avcodec.lib" )
#pragma comment ( lib, "avdevice.lib")
#pragma comment ( lib, "avfilter.lib")
#pragma comment ( lib, "avformat.lib")
#pragma comment ( lib, "avutil.lib")
#pragma comment ( lib, "postproc.lib")
#pragma comment ( lib, "swresample.lib")
#pragma comment ( lib, "swscale.lib")

 

복잡해 보이지만 복잡할 것 없다.

그냥 include 폴더에 들어 있는 폴더 이름이랑 같은 헤더들 다 포함시키고 동일 이름의 lib파일을 다 연결시킨 것이다.

 

Step 3. 드디어 컴파일

 

자 그럼 이제 컴파일 해보자.

그러면???

아래와 같은 에러가 발생한다.

 

 

위 에러는 헤더파일 폴더에 있는 libavutil폴더의 common.h이라는 헤더파일에서 inttypes.h라는 헤더를 포함하고 있는데 윈도우 os에서는 해당 헤더가 없기 때문에 발생하는 에러이다.. 어떻게 해결할지 구글님께 물어보자

 

stackoverflow에 보면 같은 증상을 호소하는 사람이 있다. 이 사람에게 다른사람이 알려준 inttypes.h헤더 파일이 있는데 이를 다운받아서 설치하도록 하자.

 

 

<동일한 병을 호소하는 환자 1>

 

 

<처방전>

 

this file은 여기서 다운 받을 수 있다.

http://code.google.com/p/msinttypes/downloads/list

 

여튼 이걸 다운 받고 이전단계에서 설정했던 포함 파일 디렉터리에다가 복사하자. 그리고 나서 아래와 같이 libavutile/common.h의 #include <inttypes.h>를 아래와 같이 수정해서 다운받은 헤더파일을 포함하자.

참고로 < >가 아니라 " "포함시켰다. 사용자가 만든 헤더는 " "로 포함시켜야 한다.

 

 

 

그리고 나서 아래 코드를 적어서 빌드를 해보자. 빌드가 잘 된다.

 

 

그런데 문제가 있다. 디버그 모드에서는 빌드도 되고 실행도 잘 되는데 Release모드에서는 빌드는 성공하지만 실행시키면 프로그램이 죽어버리는 것이다.이 문제에 대해서는 여러곳에서 구글링을 해봤는데 Release모드에서 다음과 같이 최적화 옵션을 변경하면 해결되는 것을 확인했다.

 

 

 

이 에러는 각 옵션이 활성화 되어 있을 때 최적화 과정에서 원치 않는 작동을 유발하여 발생하는 에러로 보인다. 그렇기 때문에 위와 같이 각 COMDAT, 참조 최적화 옵션을 disable시키면 더이상 이 에러가 발생하지 않는다.

(참고로 다른 싸이트에서 보면 프로젝트의 캐릭터 셋을 not Set으로 설정해 놓아야 한다고 하는 곳도 있는데, 유니코드로 설정해 두어도 문제는 없을 것으로 보인다.)

 

자 이제 FFmpeg를 가지고 놀 수 있는 환경이 되었다. GoGo

Posted by 굿쟌
,