정보공간_1

[3기 강북 김승현] ffmpeg 를 이용한 간단한 동영상 플레이어 제작 #1 본문

IT 놀이터/Elite Member Tech & Talk

[3기 강북 김승현] ffmpeg 를 이용한 간단한 동영상 플레이어 제작 #1

알 수 없는 사용자 2013. 3. 5. 15:32


안녕하세요 강북멤버십 김승현입니다.


이번 글 부터는 ffmpeg library를 이용해서 간단하게

동영상 플레이어 제작하기를 연재 해보겠습니다.

각 플렛폼에 종속되는 a/v 출력 부분을 제외한, ffmpeg를 이용한

디코딩을 어떻게 하는지를 연재 할 예정입니다.

ffplay.c를 해부하면 해당 버전의 ffmpeg 라이브러리의 사용법을 전부 알아 

낼 수 있지만 좀더 쉽게 개발 하는 데에 본 포스트가 도움이 되었으면 하는 바람이 있습니다.

본 포스트는 ffmpeg 1.0 stable 버전을 기준으로 작성 되었습니다.

필자는 windows 환경에서 개발을 진행 하였습니다.



1. ffmpeg 개발 환경 구축

리눅스 사용자라면, git를 이용해서 ffmpeg 소스를 받아서 빌드합니다.

본 포스트에서는 라이브러리 빌드 과정 보다는 사용법에 대해 더 집중 할 것이다.

빌드하기는 전통적인 configure, make, make install 과정을 통해서 할 수 있는데,

configure 옵션에 따라서 gpl, lgpl 여부와 각종 코덱의 포함 여부가

나뉘어 지기때문에 신중하게 하시길 바랍니다.

윈도우 사용자라면, mingw와 cygwin을 통해 빌드 할 수 있는데,

간단하게 http://ffmpeg.zeranoe.com/builds/ 에서 

dev버전을 받으면 되겠다. 윈도우는 gnu 환경이 아니라서,

inttype.h등의 헤더가 없다고 나오는데, 구글 검색으로 나오는 것을 추가 시켜주면 됩니다.



2. ffmpeg 초기화

헤더 파일에서 다음과 같은 파일들을 include 하고

lib 파일도 포함 시켜주어야 합니다.

당장 필요없는 것도 있는데, libswscale과 libswresample은 나중에 필수적으로 사용하므로

그냥 포함 시켜주면 됩니다.


extern "C"{

#include <libavformat/avformat.h> 

#include <libavcodec/avcodec.h>

#include <libswresample/swresample.h>

#include <libswscale/swscale.h>

#include <libavutil/opt.h>

};


#pragma comment(lib,"avformat.lib")

#pragma comment(lib,"avcodec.lib")

#pragma comment(lib,"swresample.lib")

#pragma comment(lib,"swscale.lib")

#pragma comment(lib,"avutil.lib")



그리고 main()안에서 다음 두개의 함수를 호출하여서
ffmpeg가 초기화 될 수 있게 합니다.

av_register_all();

avcodec_register_all();



3. 파일 열기

char * pszFileName = "c:\\test.avi"; //파일명

AVFormatContext * pInputFormatContext = NULL; //avformatcontext는 하나의 파일에 대한 인스턴스라고 생각하면 된다.

int err = avformat_open_input(&pInputFormatContext,pszFileName,NULL,NULL); //파일을 연다.


if(err < 0) //파일 열기 에러

{

return -1;

}



4. 알맞는 스트림 찾기

하나의 파일은 한개 이상의 스트림이 존재하는데, 개중에서 어떤 스트림을 사용할 것인지를

정하는 과정이라고 생각하면된다. 특히 다국어 오디오가 들어있는 파일들이있는데,

나중에 여기 부분을 수정해서 써야 할 것 입니다.


int nVideoStreamIdx = -1;

int nAudioStreamIdx = -1;


err = av_find_stream_info(pInputFormatContext); //스트림 정보를 찾는 함수 


if(err < 0)

{

return -1;

}

err = av_find_best_stream(pInputFormatContext,AVMEDIA_TYPE_VIDEO,-1,-1,&pVideoCodec,NULL); //비디오 스트림  찾기

if(err < 0)

{

nVideoStreamIdx = -1;

}

else

nVideoStreamIdx = err;


err = av_find_best_stream(pInputFormatContext,AVMEDIA_TYPE_AUDIO,-1,-1,&pAudioCodec,NULL); //오디오 스트림 찾기

if(err < 0)

{

nAudioStreamIdx = -1;

}

else

nAudioStreamIdx = err;



5. 코덱 찾기와, 코덱 열기

해당 스트림에 알맞는 코덱을 열어 주어야 한다. 코덱을 여는 법은 

다음과 같습니다.

AVCodecContext * pVideoCodecContext = NULL;

AVCodecContext * pAudioCodecContext = NULL;

pVideoCodecContext = pInputFormatContext->streams[nVideoStreamIdx]->codec;

pAudioCodecContext = pInputFormatContext->streams[nAudioStreamIdx]->codec;

err = avcodec_open2(pVideoCodecContext,pVideoCodec,NULL);

if(err < 0)

return -1;


err = avcodec_open2(pAudioCodecContext,pAudioCodec,NULL);

if(err < 0)

return -1;



다음 포스트에는...

a/v 디코딩, av_seek_frame등을 다룰 예정입니다!

....