Android multimedia structure overview AESOP(http://www.aesop.or.kr) 2011.09.09, 고현철 ( 고도리 ) 1
개요 Android multimedia framework 구조및 flow 2
Android Multimedia Framework Multimedia framework은크게네개로나눠볼수있다 Client/Server/Media Engine/Codec 즉, Binder에그기본을둔다 Libraries level의 media framework은 server만을얘기한다 Skin, 재생, 반복, 배속조절, 찾기, 볼륨조절등 Multimedia Player(Client) Application Home Contact Phone Browser App 과 core 간커뮤니케이션 Multimedia JNI interface Application Framework Package Manager Activity Manager Telephony Manager Window Manager Resource Manager Content Providers Location Manager View System Notification Manager 비디오코덱 오디오코덱 다운로드, 로컬플레이 Multimedia(Serv er, Engine, Codec) Surface Manager OpenGL ES Libraries Media Framework FreeType SQLite Webkit SGL SSL libc Android Runtime Core Lib Dalvik VM Audio/video hardware abstraction layer Audio/video HAL & Codec Driver Display Driver Keypad Driver Linux Kernel Camera Driver WiFi Driver Flash Memory Driver Audio Driver Binder(IPC) Driver Power Management 3
Android multimedia framework 의구조 Android 에서의 multimedia framework 구조는다음과같다 Stagefright Player 는다른엔진으로대체가능 4
MediaPlayer call flow MediaPlayer application 이실행되었을때의 call flow 그림에서 StagefrightPlayer 인 libstagefrightplayer.so 라이브러리는다른 player engine 으로대체가능 5
MediaPlayer class structure 6
Multimedia app. state diagram Android Multimedia App. 의 state diagram 각단계에서호출되는함수들은 client(app.) 에서 server(media engine) 으로호출되는함수이름들이다 7
Android multimedia player 구조 Client Native console mediaplayer Server gvideo mediaserver 8
Media Player Call flow(1) MediaPlayer class 의생성과 Listener 등록 Applications MediaPlayer 클래스생성 MediaPlayer() native_setup() Applications Framework android_media_mediaplayer_native_setup() : MediaPlayer 클래스생성후 Listener 생성 new JNIMediaPlayerListener() Libraries MediaPlayer() MediaPlayer::setListener() : MediaPlayer 클래스에서생성되는 message 를 JNI 쪽으로건네주는역할하는함수세팅 9
Media Player Call flow(2) Play 할 Media 의등록 setdatasource() 의호출 10
Media Player Call flow(3) Play 의시작 start() 의호출 11
gvideo client Android native console multimedia player Android 에서 multimedia 를포팅할때사용하는 test application Application 을일일이구동하는것보다 console 에서명령어를이용하여 media engine 을구동 개발용 code 두가지버전 gvideo: only server 와 engine 만 run 시키는 app http://freepine.blogspot.com/2009/02/1-native-console-app-for-videoplayback.html 해당사이트의소스를 Android 2.x 대에알맞게수정 gvideo2: gvideo1 를확장해서 server 에서 client 로보내는 message 처리루틴을추가한버전 12
gvideo android makefile LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= gvideo.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libui \ libsurfaceflinger \ libaudioflinger \ libmediaplayerservice \ libmedia LOCAL_MODULE:= gvideo LOCAL_C_INCLUDES := \ frameworks/base/include \ frameworks/base/media/libmediaplayerservice\ frameworks/base/media/libmedia #LOCAL_CFLAGS := \ # -DHAVE_CONFIG_H include $(BUILD_EXECUTABLE) 13
gvideo source 1/2 1 #include <media/mediaplayer.h> 2 #include <media/imediaplayer.h> 3 4 using namespace android; 5 6 #if 1 7 #define gprintf(fmt, args...) LOGE("%s(%d): " fmt, FUNCTION, LINE, ##args) 8 #else 9 #define gprintf(fmt, args...) 10 #endif 11 12 int 13 main(int argc, char **argv) 14 { 15 gprintf("entering main..."); 16 sp < ProcessState > proc = ProcessState::self(); 17 proc->startthreadpool(); 18 MediaPlayer mediaplayer; 19 sp < Surface > gsf; 20 21 if (argc > 1) 22 { 23 gprintf("set datasource: %s", argv[1]); 24 mediaplayer.setdatasource(argv[1], NULL); 25 } 26 else 27 { 28 gprintf("set datasource: /aa/test.mp4"); 29 mediaplayer.setdatasource("/aa/test.mp4",null); 30 } 31 32 gprintf("create SurfaceComposerClient"); 33 int pid = getpid(); 34 int nstate = 0; 14
gvideo source 2/2 36 sp < SurfaceComposerClient > videoclient = new SurfaceComposerClient; 37 38 gprintf("create video surface"); 39 sp <SurfaceControl> videosurface(videoclient->createsurface(pid, 0, 320, 240, 40 PIXEL_FORMAT_OPAQUE, 41 ISurfaceComposer::eFXSurfaceNormal ISurfaceComposer::ePushBuffers)); 42 videoclient->opentransaction(); 43 44 // set toppest z-order 45 nstate = videosurface->setlayer(int_max); 46 nstate = videosurface->show(); 47 videoclient->closetransaction(); 48 49 gprintf("set video surface to player"); 50 gsf = videosurface->getsurface(); 51 mediaplayer.setvideosurface(gsf); // for android 2.0 52 53 status_t retcode = mediaplayer.prepare(); 54 55 if (retcode < 0) 56 { 57 gprintf("prepare failed: %d\n", retcode); 58 IPCThreadState::self()->stopProcess(); 59 return -1; 60 }; 61 62 mediaplayer.start(); 63 for (int i = 0; i < 10; i++) 64 { 65 sleep(1); 66 } 67 mediaplayer.reset(); 68 69 // close binder fd, still need waiting for all binder threads exit? 70 IPCThreadState::self()->stopProcess(); 71 return 0; 72 } 15
gvideo client gvideo client : gvideo2 gvideo client : gvideo.cpp 수행부해당 - 아래는 gvideo 클라이언트동작모습이며, gvideo 클라이언트의내부를살펴본다. 16
gvideo client gvideo client setdatasource - mediaplayer의 client와 server구동의시작점 ret = mediaplayer.setdatasource(argv[1]) int main(int argc, char** argv) { dprintf("set datasource: %s\n", argv[1]); ret = mediaplayer.setdatasource(argv[1]); if( ret!= NO_ERROR) 17
gvideo client gvideo client mediaplayer.prepare - mediaplayer관련함수의두번째함수 call status_t retcode = mediaplayer.prepare() int main(int argc, char** argv) { status_t retcode = mediaplayer.prepare(); if(retcode < 0) { dprintf("prepare failed: %d\n", retcode); 18
gvideo client gvideo client mediaplayer.start - mediaplayer에 start명령을내린다. 세번째함수 call이다. mediaplayer.start() int main(int argc, char** argv) { mediaplayer.start(); dprintf("media player start...\n"); //mediaplayer.reset(); 19
gvideo client gvideo client 미디어플레이어구동순서 mediaplayer.setdatasource(); mediaplayer.prepare(); mediaplayer.start() 이후로 mediaplayer service 가동작, client 는관련 message 만처리하면되는구조중지하고싶을때는 mediaplayer.reset() 혹은 mediaplayer.stop(); mediaplayer.disconnect(); 20
Android multimedia server mediaserver mediaserver 에서실행시키는 MediaPlayerService 의동작분석 mediaserver 에서 media engine 을호출하는루틴을중점파악 21
Media server/engine 관련 source Header frameworks/base/include/media/* Client frameworks/base/media/libmedia/* Server frameworks/base/media/mediaserver/* frameworks/base/media/libmediaplayerservice/* Engine frameworks/base/media/libstagefright/* Codec frameworks/base/media/libstagefright/omx : Interface frameworks/base/media/libstagefright/codecs : codec source Renderer frameworks/base/media/libstagefright/colorconversion: video renderer 22
mediaserver mediaserver mediaserver : MediaPlayerService 에해당 - 아래는앞서살펴본 gvideo 클라이언트동작모습이며, gvideo 클라이언트수행에따른 MediaPlayerService 동작에대해살펴본다. [ 그림 2 gvideo client 동작 ] 23
mediaserver mediaserver frameworks/base/media/libmediaplayerservice/mediaplayerservice.cpp sp<imediaplayer> MediaPlayerService::create - Client 담당 Binder 생성 setdatasource() 가호출되며 Android 의 Player 들중하나가생성이된다.(eg. stagefright) sp<imediaplayer> MediaPlayerService::create sp<imediaplayer> MediaPlayerService::create(pid_t pid, const sp<imediaplayerclient>& cli ent, const char* url) { sp<client> c = new Client(this, pid, connid, client); if (NO_ERROR!= c->setdatasource(url)) { c.clear(); return c; } wp<client> w = c; Mutex::Autolock lock(mlock); mclients.add(w); return c; } 24
mediaserver mediaserver setdatasource - DataSource 설정및플레이어객체생성, 플레이어객체에 DataSource 를할당하여호출 setdatasource status_t MediaPlayerService::Client::setDataSource(const char *url) { //File 의확장자로 Playertype 을얻는다. 만족하는확장자가없으면 static play er_type getdefaultplayertype() 함수를통해 PV_PLAYER 나 STAGEFRIGHT_PLA YER 를얻는다. player_type playertype = getplayertype(url); // PlayerType 으로해당하는 Player 객체생성 sp<mediaplayerbase> p = createplayer(playertype); 25
mediaserver mediaserver setdatasource - DataSource 설정및플레이어객체생성, 플레이어객체에 DataSource 를할당하여호출 setdatasource status_t MediaPlayerService::Client::setDataSource(const char *url) { // player 객체의 setdatasource 를 url 을이용해서호출, 여기서는 stagefr ight 관련 player 임 } mstatus = p->setdatasource(url); 26
mediaserver mediaserver creatplayer - setdatasource 로얻어진플레이어타입으로플레이어생성 createplayer sp<mediaplayerbase> MediaPlayerService::Client::createPlayer(player_ty pe playertype) { sp<mediaplayerbase> p = mplayer; if (p == NULL) { p = android::createplayer(playertype, this, notify); } return p; } 27
mediaserver mediaserver sp<mediaplayerbase> creatplayer - setdatasource 로얻어진플레이어타입으로플레이어생성 sp<mediaplayerbase> createplayer static sp<mediaplayerbase> createplayer(player_type playertype, void* cookie, notify_callba ck_f notifyfunc) { sp<mediaplayerbase> p; switch (playertype) { #if BUILD_WITH_FULL_STAGEFRIGHT case STAGEFRIGHT_PLAYER: LOGV(" create StagefrightPlayer"); p = new StagefrightPlayer; break; return p; } 28
mediaserver mediaserver StagefrightPlayer::setDataSource -StagefrightPlayer 타입으로생성한플레이어객체의 setdatasource 수행플레이어 initcheck() 및 AudioSink 설정등 StagefrightPlayer::setDataSource frameworks/base/media/libmediaplayerservice/stagefrightplayer.h frameworks/base/media/libmediaplayerservice/stagefrightplayer.cpp 파일을참조 29
Android multimedia engine Media engine mediaserver 로부터호출되는 media engine routine 파악 Android 2.2 OpenCORE 와 Stagefright engine 이혼재 Android 2.3 Stagefright 로변경 기존 OpenCORE 개발사들이힘들어짐 30
OpenCORE PacketVideo 사의 Multimedia Engine 31
OpenCORE 개요 (1) Android 2.2 version 까지의표준 Multimedia Engine external/opencore/* OpenCORE 는 Google Android 의 Multimedia Framework 로서 PacketVideo 라고도불린다. OpenCORE Multimedia Framework 는 PacketVideo 를포함한 Software Layer 의이름이기도하다. OpenCORE Multimedia Framework 코드는매우크고, C++ 로작성된 Full-Featured 운영체제에통합되는구조로되어있다. OpenCORE Multimedia Framework 를거시적인관점에서볼때, 그것은주로다음과같은두가지측면을포함하고있다. PVPlayer 다양한오디오비디오스트림에대한재생기능을갖고있는미디어플레이어를위한함수들을제공 PVAuthor 오디오, 비디오스트림을녹화, 이미지캡쳐기능을위한함수들을제공 PVPlayer 및 PVAuthor 는개발자들이사용할수있는형태로 SDK 를제공한다. 32
OpenCORE 개요 (2) OSCL (Operating System Compatibility Library ) 운영체제호환성라이브러리. 다른운영체제간의호환성을위하여기본운영체제동작을지원하는기능을포함하고있다. 기본데이터형식, Configuration, String Instruments, I/O, Error handling, Thread 등을포함한 C++ 기본라이브러리와유사하다. PVMF (PacketVideo Multimedia Framework) Document Analysis(Parser) 와 Composition(Composer) 를구현한 Framework. 이안의 Codec Node 는공통적인인터페이스를상속할수있다. 사용자계층은 Node 를생성하기위하여그공통인터페이스를상속할수있다. PVPlayer 엔진및 PVAuthor 엔진 33
OpenCORE 개요 (3) Player 의입장에서 PVPlayer 는입력 (Source) 으로 Network File 혹은 Media Stream 등이될수있고, 출력 (Sink) 은오디오 / 비디오장비의입력이될수있고, 기본적인기능을포함하는미디어흐름제어와 Document Analysis, Video Streaming, Audio Decoder(Decode) 와그외의다른특징을갖고있다. Paper Document 서부터방송미디어까지포함하고있고, 또한 Network-Related RTSP Streaming 기능도포함하고있다. 미디어영역의 recording 에있어서, PVAuthor 입력 ( 원본 ) 은카메라, 마이크및기타장비, 출력 (Sink) 각종문서의동기화의흐름, 비디오 (Encode) 로작성된문서등오디오인코딩스트리밍등기능을수행한다. OpenCORE SDK 의사용에있어, 응용프로그램계층에서 Adaptor(Adaptor) 를구현하는것이필요하고, 그 Adaptor 는 PVMF 를위한 Node 의특정기능을 Common Interface 를이용해서구현해야하는데이것은상위단에서의사용을위하여 Plug-in 형태로구현하게된다. 34
Stagefright Android 2.3 서부터의표준 Multimedia Engine 35
StageFright Android 2.0 서부터새로나타난 Multimedia Engine 매우단순하고 OpenCORE solution 에비해서직관적인구조를가지고있음. Android Gingerbread 서부터공식으로채택 Engine 대부분을새롭게구성하였고적은양의코드구조를갖는다 OpenCORE 에비해서상대적으로쉬운구조이나, Parser 의경우유연한구조를갖지는않음. 36
일반 Multimedia Engine 의구조 Linux Multimedia Engine 인 mplayer 의경우 Structure 구성 37
동영상에서사용하는용어정리 Mplayer 에서의동영상처리 module 용어정리 Stream 동영상이저장되어있는파일, 네트워크등 Stagefright 에서는 DataSource 라고불림 Demuxer Parser 라고불린다. Audio, Video, Subtitle 의세가지를 Stream 에서분리하는역할을한다. StageFright 에서는 MediaExtractor 클래스이며, 일반적으로는분리되는데이터세가지를 Demuxer stream 이라고얘기하며 StageFright 에서는 MediaSource 라고불리며, AwesomePlayer 에서는 mvideotrack, maudiotrack 이라는두가지로표현이된다. Audio Codec Encoded Audio Data 를디코딩한다 StageFright 에서는 MediaSource 라고불리며, 실제로는 OMXCodec(MediaSource 에서상속됨 ) 이다 38
동영상에서사용하는용어정리 Mplayer 에서의동영상처리 module 용어정리 ( 계속 ) Audio Filter 오디오출력데이터에어떤조작을가하기위해서사용한다 StageFright에서는 AudioFlinger에서처리된다 Video Codec Audio Codec 과비슷한역할이다. Video Filter Audio Filter 와유사한역할이나, StageFright 에서는사용되지않는다. 39
Stagefright Player 의기본구조및 class 앞의 mplayer 의구조와비교했을때의 Class 구성도 40
Stagefright Player 에서의 Class 정리 Stagefright 에서사용되는 Class 들의정의는다음과같다. DataSource data input type 에대한 class - ex> file, http 각 MediaExtractor(ex> MP3Extractor) 에서는기본적으로 Sniff 함수를 DataSource 에등록시켜야한다. MediaExtractor 의 Create 함수가 AwesomePlayer() 에서호출될때각 Sniff 함수가호출된다. 해서어떤 media 가입력되었는지선택할수있도록한다. ==> 즉, demuxer 를선택할수있도록한다. MediaSource 데이터를입력으로제공한다는의미를갖는클래스이다. 즉, 데이터의소스가될수있다는의미이다. 데이터의입력은세가지로볼수있는데 Encoded Data Demuxer(Extractor) 에서분리된데이터를제공한다. MediaSource 중 Extractor 에서분리된 maudiotrack, mvideotrack 을얘기한다 Encoded Data 된데이터를 Decoding 한데이터 OMXCodec 을얘기한다 Raw Data CameraSource 와같은데이터를제공해주는소스를얘기한다. 41
Stagefright Player 에서의 Class 정리 ( 계속 ) Stagefright 에서사용되는 Class 들의정의는다음과같다. MediaExtractor Demuxer 를얘기함 MediaBuffer MediaSource 서부터다른루틴으로건네지는데이터클래스이다. MediaBufferGroup MediaBuffer 를링크드리스트로다루는헤더객체라고보면된다. 42
Stagefright 의기본구조 MediaPlayerService 소속인 StagefrightPlayer 의기본구조 43
Stagefright Class 구조도 #1 AwesomePlayer MediaExtractor MediaSource: Encoded Data MediaSource: OMX Codec Decoded Data 출력 AudioFlinger or SurfaceFlinger DataSource OMX Codec 44
Stagefright Class 구조도 #2 MediaExtractor::getTrack() AwesomePlayer DataSource 를인자로 MediaSource 생성 sp<mediasource>maudiotrack sp<mediasource>mvideotrack sp<mediasource>mvideosource OMXCodec::Create( mvideotrack ) sp<mediasource>maudiosource OMXCodec::Create( maudiotrack ) AudioPlayer *maudioplayer AudioSink 혹은 AudioTrack 이용하여 AudioFlinger 로 Audio 출력 sp<awesomerenderer> mvideorenderer; AwesomeRemoteRenderer : public AwesomeRenderer AwesomeLocalRenderer : public AwesomeRenderer VideoRenderer *mtarget class SoftwareRenderer : public VideoRenderer SurfaceFlinger 로출력 45
Stagefright Class 구조도 #3 http://freepine.blogspot.com/2010/01/overview-ofstagefrighter-player.html 사이트의그림에서발췌 참고용 클래스의구조는이와같이복잡하나, 전체 media player 의 plugin 의관점에서접근해야만구조파악이쉽다. 46
Android codec interface Android engine 에서의 codec interface 47
Common Multimedia Engine(include Android) Media Player App Media source Multimedia Engine System lib demux format Sync Application : Multimedia source handling Middleware : Media Data handling (demuxer/muxer, Audio/Video sync) AVI/MP4/MKV etc, audio Codec video Hardware engine handling (H/W codec handling through standard codec interface) H/W Engine Codec H/W : Codec interface(openmax IL or Custom interface), Audio Video Hardware data path setup (H/W codec setup, output path), 48
Media Player/Composer part Media Player App Media source Multimedia Engine System lib demux format Sync audio Codec video 1. Player 동영상 decoder 2. Composer 동영상 encoder 3. PLAYER/Composer 가다루는부분은위와같다 ex> OpenCORE/StageFright StageFright/Skype Engine/Custom engine 49
H/W Codec Engine H/W Codec Engine Audio Codec Interface Video H/W 는 Audio Codec 지원안함 Simple Profile(SP) : DivX3/4, H263, MPEG4 MP3 MPEG4 STD AAC Vorbis AC3 DTS WAV APE FLAC Data Loss Compression Data Lossless Compression MPEG2 H.264 WMV WMV7/8/9 Advanced Simple Profile(ASP) : DivX5/6, XviD Another Name: MPEG4 Part10/ AVC(Advanced Video Coding) 50
Multimedia Codec Interface Media Player App Media source Multimedia Engine System lib demux format Sync audio H/W Engine Codec Codec Audio video Codec Interface Video - Codec Interface: H/W or S/W codec handling software - Codec Interface 는표준화가되어있을수도있고, Player 에따라서는직접사용자가자기만의표준을가지고작성할수있음 - 표준화가되어있는경우 : OpenMAX IL(Intergration Intergration Layer) - 표준화가되어있지않은경우 : Player 에따라자체적으로작성. ffmpeg/mplayer mplayer/xine etc 51
Android Multimedia Codec Interface Media Player App Multimedia Engine 1 OPENCORE Media : Froyo source 까지지원 GingerBread 에서삭제 2 STAGEFRIGHT : Éclair에서부터지원 (2.3에서 main) System lib Multimedia Engine demux format Sync audio H/W Engine Codec Codec video 연결방식 1 표준규격 2 독자규격 - OpenMAX IL 보다유연한 Interface Audio Video 52
What is OpenMAX OpenMax Khronos Group 에서만들고있는표준 API Media Interface 시스템에무관하게미디어프로그램작성이가능하도록표준 API 를제공 안드로이드플랫폼에서 OpenMAX 표준규격에의한코덱과미디어플레이어설계가능 OpenMax Layer OpenMax AL (Application Layer) Platform 에무관하게 Media Interface 를제공하고사용가능 고수준미디어제어프로그램만작성이가능 저수준에해당되는 OpenMax IL 을사용하여미디어제어프로그램작성도가능 OpenMax IL (Integration Layer) Multimedia Codec 들과사용자들간의인터페이스를제공 컴포넌트기반의프로그램으로서부품을설계하듯이미디어플레이어설계가가능 이는 MS 의 DirectShow 구조와상당히흡사함 ( 표준멀티미디어규격 ) OpenMax DL (Development Layer) Audio Codec, Video Codec 개발에대한설명 일반적으로 Platform 제공자가 Wrapping 하여 OpenMax IL 로커버 즉, 미디어플레이어프로그래머는접근할필요가없는레이어 단, Codec 관련구조확인시에는참고가능 53
Android 2.3 에서의 OMX 인터페이스 Android Gingerbread 에서의 codec interface 54
Android 에서의 OPENMAX IL 의사용 1. OpenCore 에서는 Node 라는개념 (OpenCore 에서 codec 을사용하는방식 ) 에 OpenMax IL 을연결함 2. Stagefright 에서도역시 Codec 이 OpenMax IL 형식으로 wrapping 되어있음 55
Android 2.3 Stagefright 의 OMX 구조 #1 Binder Client MediaPlayerService AwesomePlayer MediaPlayerService OMX Binder Server AwesomePlayer::on VideoEvent AudioPlayer OMXMaster OMXCodec & OMXClient OMXPVCodecsPlugin(or stagefright plugin) libbinder.so Software or Hardware Codec Linux Kernel Binder Driver H/W Codec driver(ex> Samsung S.LSI 의 MFC) 56
Android 2.3 Stagefright 의 OMX 구조 #2 Binder Client AwesomePlayer::onVideoEvent or AudioPlayer OMXCodec::read() decode 된 data ready OMXCodec::on_message() message 처리 AwesomePlayer omx_message::fill_buffer_done filloutputbuffer decode 된 data 가준비되었다고 signal 을보내줌 omx_message::empty_buffer_done draininputbuffer()encoded 된 data 를읽어감 sp<mediasource>maudiotrack sp<mediasource>mvideotrack IPC fillbuffer emptybuffer OMX, OMXMaster MediaPlayerService OMXPVCodecsPlugin(or stagefright plugin) fillbuffer emptybuffer OMX_FillThisBuffer() 매크로호출 OMX_EmptyThisBuffer() 매크로호출 Binder Server OpenMAX IL Node 형태의 Codec 57
Android 에서지원하는 Component - Stagefright Features : StageFright Name Extractor/Writer Codec AAC AMR WAV MP3 AVI MP4 PVX SBC MKV MPEG2 OGG on2 G711 H264 parser DEC composer ENC parser DEC composer ENC parser composer NB WB NB WB parser DEC composer parser composer ENC parser DEC composer ENC parser composer DEC ENC parser DEC composer ENC parser DEC composer ENC parser DEC composer ENC DEC ENC DEC ENC DEC ENC 58
안드로이드지원 S/W CODEC( 기본지원 ) 1. Packet Video에서작성한 OpenCORE Framework/Stagefright 내에포함되어있음 2. H/W Codec을사용하고싶다면, 이런 S/W Codec들을제거하고, H/W Codec들을 OpenMAX IL API로 wrapping하여플러그인시켜야함. 3. Interface가복잡하기때문에제어가힘들다는단점이있음 59
Android 에서의 codec 을사용하는방법 (1) Android Multimedia Engine 를사용할경우 (Samsung SoC 의경우 ) Froyo: OpenCORE 에포함되어있는 OpenMAX IL 구조를이용 Gingerbread: StageFright 에포함되어있는 OpenMAX IL 구조를이용 장점 단점 기존에구성되어있는코덱코드를그대로사용이가능함 Skype 와같은외부 player engine 에서 OpenMAX IL 을지원하지않을경우 Android version 에따라기존의코드 (OpenCORE/StageFright) 에서사용하는 OpenMAX IL Interface 를재작업후 Skype 와연결해야한다 Skype 와같은 custom player/composer 의경우자체표준이존재할경우가많다 60
Android 에서의 codec 을사용하는방법 (2) Android Multimedia Engine 을사용하지않는경우 SoC 의코덱 (ex> Samsung S.LSI 의 MFC) 사용법을기존의코드를참고하여새로작성 이후에특정 Video Engine 의 Interface 와맞춰서직접 hardware codec 을제어하는코드를작성한다 장점 단점 skype 혹은다른엔진에서원하는방식대로코드구성이가능 기존의코드를재작성해야한다. 61
Media In/Output(MIO) Decoding 된최종결과물의출력 Audio Video AudioSink SurfaceFlinger surface vs. Overlay 62
Audio output AudioSink 일반적인 application 의경우 AudioTrack 사용 MediaPlayerService 는 AudioSink 사용 AudioSink 로부터상속받은 AudioOutput class 를사용한다 AudioSink 는실제로 AudioTrack 이다 Callback function 위주의동작 AudioTrack 은직접제어하는경우가많음 선언 AudioSink frameworks/base/include/media/mediaplayerinterface.h AudioOutput frameworks/base/media/libmediaplayerservice/mediaplayerservice.h Media Engine 에서는 Audio Thread 를동작시켜서 Audio callback 함수를이용해서 data 를 output 63
Android 2.3 Stagefright 의 Audio output Binder Client Binder Server AwesomePlayer AudioPlayer TrackHandle: public BnAudioTrack AudioFlinger MediaPlayerService class AudioOutput : public MediaPlayerBase::AudioSink 혹은 AudioTrack libbinder.so AudioFlinger HAL ALSA lib Linux Kernel Binder Driver ALSA(Sound) driver Sound Hardware 64
Video output Android surface output 은기본적으로는 SurfaceFlinger 의 LayerBuffer 를이용 기본적으로모든동영상 display routine 은 SurfaceFlinger 사용 BufferSource 를사용하는경우 OverlaySource 를사용하는경우 H/W engine 사용 OpenCORE 에서의 Surface Output routine AndroidSurfaceOutput 1. writeframebuf() 2. registerbuffers() 3. postbuffer() LayerBuffer SurfaceFlingerThread 65
Video output class flow Native Framework LayerBase ISurface LayerBaseClient BnSurface LayerBaseClient ::Surface LayerDim LayerBlur Layer Layer:: SurfaceLayer LayerBuffer LayerBuffer:: SurfaceLayerBuffer LayerBuffer:: OveraySource LayerBuffer:: Source LayerBuffer:: BufferSource Kernel Space 66
SurfaceFlinger display flow(1) JNI call threadloop() Surface SurfaceControl Java Service Native Framework LayerAAA LayerBBB LayerCCC Drawing layer eglswapbuffers to Framebuffer (start threadloop()) c Surface LayerAAA LayerBBB LayerCCC SurfaceFlinger FrameBuffer LCD device Kernel Space LayerAAA LayerBBB LayerCCC 67
SurfaceFlinger display flow(2) SurfaceFlinger::threadLoop(){ handleconsoleevents() transaction check handletransaction(tran sactionflags) transaction flag check handlepageflip() post surface if (LIKELY(hw.canDraw() &&!isfrozen())) true handlerepaint() hw.compositioncomplete(); unlockclients() postframebuffer() repaint framebuffer h/w compositing buffer swap false unlockclients() hw.compositioncomplete(); Usleep(16667) bypass composition h/w compositing 60 fps } return 68
Overlay 를이용한 H/W engine 사용 기본적으로모든동영상 display routine 은 SurfaceFlinger 사용 SurfaceFlinger 의 LayerBuffer class 를이용한 Surface display routine 사용 LayerBuffer 를사용할경우 BufferSource 를사용하면직접 LCD device driver(ex> fb) 를이용 OverlaySource 를사용할경우 H/W Layer 를이용 Overlay 를이용할경우는 LayerBuffer 를이용해서 display Entry 만유지 실제동작은 H/W Overlay 로데이터는직접전송하는구조 대부분 YUV RGB 변환루틴은 Overlay driver 를이용해서처리한다 hardware/libhardware/modules/overlay/* 혹은 vendor 의 overlay source 참조 69
Multimedia 와 SurfaceFlinger 와의관계 MediaPlayer(libmedia) Binder MediaPlayerSerivce MidiPlayer StagefrightPlayer video decoder colorconversion(renderer) 출력장치의결정 OMX codec Overlay 출력 일반 Surface 출력 LayerBuffer 출력 (ISurface 이용 ) overlay data path (Overlay class 이용 ) overlay control path (ISurface 이용 ) SurfaceFlinger Surface LayerBuffer Layer LayerBlur LayerDim OverlaySource BufferSource overlay control path overlay module OpenGL ES gralloc module User Space V4L2 or Overlay Engine FrameBuffer or Graphic Engine Kernel Space 70