Android NuPlayer要点详解Word文件下载.docx
《Android NuPlayer要点详解Word文件下载.docx》由会员分享,可在线阅读,更多相关《Android NuPlayer要点详解Word文件下载.docx(47页珍藏版)》请在冰豆网上搜索。
voidAHandler:
deliverMessage(constsp<
AMessage>
&
msg){
onMessageReceived(msg);
mMessageCounter++;
….
ALooper
与Ahander一一对应,负责存储消息并分发Ahandler的消息,与AMessage一对多关系
//postsamessageonthislooperwiththegiventimeout
voidALooper:
post(constsp<
msg,int64_tdelayUs){
Mutex:
AutolockautoLock(mLock);
int64_twhenUs;
if(delayUs>
0){
whenUs=GetNowUs()+delayUs;
}else{
whenUs=GetNowUs();
List<
Event>
iteratorit=mEventQueue.begin();
while(it!
=mEventQueue.end()&
&
(*it).mWhenUs<
=whenUs){
++it;
Eventevent;
event.mWhenUs=whenUs;
event.mMessage=msg;
if(it==mEventQueue.begin()){
mQueueChangedCondition.signal();
mEventQueue.insert(it,event);
----------------------------------------------------------
status_tALooper:
start(
boolrunOnCallingThread,boolcanCallJava,int32_tpriority){
if(runOnCallingThread){
{
if(mThread!
=NULL||mRunningLocally){
returnINVALID_OPERATION;
mRunningLocally=true;
do{
}while(loop());
mThread=newLooperThread(this,canCallJava);
status_terr=mThread->
run(
mName.empty()?
"
ALooper"
:
mName.c_str(),priority);
if(err!
=OK){
mThread.clear();
returnerr;
boolALooper:
loop(){
if(mThread==NULL&
!
mRunningLocally){
returnfalse;
if(mEventQueue.empty()){
mQueueChangedCondition.wait(mLock);
returntrue;
int64_twhenUs=(*mEventQueue.begin()).mWhenUs;
int64_tnowUs=GetNowUs();
if(whenUs>
nowUs){
int64_tdelayUs=whenUs-nowUs;
mQueueChangedCondition.waitRelative(mLock,delayUs*1000ll);
event=*mEventQueue.begin();
mEventQueue.erase(mEventQueue.begin());
event.mMessage->
deliver();
//seeAHandler.deliverMessage
…..
LooperThread
此线程调用ALooper的loop方法来分发消息
virtualstatus_treadyToRun(){
mThreadId=androidGetThreadId();
returnThread:
readyToRun();
virtualboolthreadLoop(){
returnmLooper->
loop();
ALooperRoaster
与Handler是一对多的关系,管理Looper和Handler一一对应关系,负责释放stalehandler
ALooper:
handler_idALooperRoster:
registerHandler(
constsp<
looper,constsp<
handler){
if(handler->
id()!
=0){
CHECK(!
"
Ahandlermustonlyberegisteredonce."
);
HandlerInfoinfo;
info.mLooper=looper;
info.mHandler=handler;
ALooper:
handler_idhandlerID=mNextHandlerID++;
//一对一
mHandlers.add(handlerID,info);
//一对多
setID(handlerID,looper);
returnhandlerID;
voidALooperRoster:
unregisterHandler(ALooper:
handler_idhandlerID){
ssize_tindex=mHandlers.indexOfKey(handlerID);
if(index<
constHandlerInfo&
info=mHandlers.valueAt(index);
handler=info.mHandler.promote();
if(handler!
=NULL){
setID(0,NULL);
mHandlers.removeItemsAt(index);
unregisterStaleHandlers(){
Vector<
sp<
>
activeLoopers;
for(size_ti=mHandlers.size();
i>
0;
){
i--;
info=mHandlers.valueAt(i);
looper=info.mLooper.promote();
ALOGV("
Unregisteringstalehandler%d"
mHandlers.keyAt(i));
mHandlers.removeItemsAt(i);
//Atthispoint'
looper'
mightbetheonlysp<
>
keeping
//theobjectalive.Topreventitfromgoingoutofscope
//andhaving~ALoopercallthismethodagainrecursively
//andthendeadlockingbecauseoftheAutolockabove,add
//ittoaVectorwhichwillgooutofscopeafterthelock
//hasbeenreleased.
activeLoopers.add(looper);
异步消息机制的创建
mLooper=newALooper;
//创建一个Alooper实例
AHandlerReflector>
mHandler=newAHandlerReflector//创建一个Ahandler实例
mLooper->
setName(“xxxxx”);
//设置looper名字
start(false,true,PRIORITY_XXX);
//根据参数创建并启动looperthread
regiserHandler(mHandler);
//registerhandler会调用AHandler的setID方法将looper设置到Handler里去
Post消息
msg=newAMessage(kWhatSayGoodbye,mHandler);
//在AMessage的构造方法里获取Ahandler对应的Looper并保存
msg->
post();
//调用looper的post方法
MessagePost的调用过程
Message:
post
↓
mEventQueue.insert
mQueueChangedCondition.signal()//如果之前没有event,通知looperthread
loop()
if(mEventQueue.empty()){//如果消息队列为空,则等待
mQueueChangedCondition.wait(mLock);
returntrue;
event=*mEventQueue.begin();
event.mMessage->
AHandler:
deliverMessage
AHandlerReflector:
onMessageReceived
具体的实现
NuPlayer
下面就进入我们的正题,NuPlayer
frameworks/av/media/libmediaplayerservice/nuplayer/
NuPlayerDriver
NuPlayerDriver是对NuPlayer的封装,继承MediaPlayerInterface接口。
通过NuPlayer来实现播放的功能。
看这部分代码的方法就是先看NuPlayerDriver里面干了啥,转头就去找NuPlayer里面的实现,一般都要再去NuPlayer的onMessageReceive中看消息的响应,最后回到NuPlayerDriver的各种notify中看流程的周转,下面附上一张播放器状态机流转图
NuPlayerDriver:
NuPlayerDriver(pid_tpid)
mState(STATE_IDLE),//对应播放器状态机的初始化状态
mIsAsyncPrepare(false),
mAsyncResult(UNKNOWN_ERROR),
mSetSurfaceInProgress(false),
mDurationUs(-1),
mPositionUs(-1),
mSeekInProgress(false),
mLooper(newALooper),
mPlayerFlags(0),
mAtEOS(false),
mLooping(false),
mAutoLoop(false){
NuPlayerDriver(%p)"
this);
//和前面所述的异步消息创建机制相符
mLooper->
setName("
NuPlayerDriverLooper"
mLooper->
false,/*runOnCallingThread*/
true,/*canCallJava*/
PRIORITY_AUDIO);
//mPlayer即NuPlayer,继承于AHandler
mPlayer=AVNuFactory:
get()->
createNuPlayer(pid);
registerHandler(mPlayer);
mPlayer->
setDriver(this);
~NuPlayerDriver(){
~NuPlayerDriver(%p)"
stop();
//整个NuPlayerDriver就是一个大ALooper
AVNuFactory
负责关键组件的create,通过它能看到:
1.每一个NuPlayer对应一个进程
2.数据流从Source-Decoder-Renderer,中间由AMessages驱动
NuPlayer>
AVNuFactory:
createNuPlayer(pid_tpid){
returnnewNuPlayer(pid);
NuPlayer:
DecoderBase>
createPassThruDecoder(
notify,
Source>
source,
Renderer>
renderer){
returnnewNuPlayer:
DecoderPassThrough(notify,source,renderer);
createDecoder(
pid_tpid,
Decoder(notify,source,pid,renderer);
createRenderer(
MediaPlayerBase:
AudioSink>
sink,
uint32_tflags){
Renderer(sink,notify,flags);
下面分别分析Source,Decoder,Renderer
Source
以setDataSource为切入点
status_tNuPlayerDriver:
setDataSource(constsp<
IStreamSource>
source){
setDataSource(%p)streamsource"
if(mState!
=STATE_IDLE){
mState=STATE_SET_DATASOURCE_PENDING;
setDataSourceAsync(source);
//因为driver只是NuPlayer的封装,所以还是要去调用NuPlayer完成实际动作
while(mState==STATE_SET_DATASOURCE_PENDING){
mCondition.wait(mLock);
returnmAsyncResult;
--------------------------------------
voidNuPlayer:
setDataSourceAsync(constsp<
msg=newAMessage(kWhatSetDataSource,this);
notify=newAMessage(kWhatSourceNotify,this);
msg->
setObject("
source"
newStreamingSource(notify,source));
//到了NuPlayer中,也不是直接进行操作,而是先发个消息,验证前面所说的一切都由AMessage驱动
---------------------------------------
onMessageReceived(constsp<
switch(msg->
what()){
casekWhatSetDataSource:
//实际的处理在这里
kWhatSetDataSource"
CHECK(mSource==NULL);
status_terr=OK;
RefBase>
obj;
CHECK(msg->
findObject("
&
obj));
if(obj!
AutolockautoLock(mSourceLock);
mSource=static_cast<
Source*>
(obj.get());
//赋值给mSource
err=UNKNOWN_ERROR;
CHECK(mDriver!
=NULL);
NuPlayerDriver>
driver=mDriver.promote();
if(driver!
driver->
notifySetDataSourceCompleted(err);
//通知driver设置完毕
break;
}......
voidNuPlayerDriver:
notifySetDataSourceCompleted(status_terr){
CHECK_EQ(mState,STATE_SET_DATASOURCE_PENDING);
mAsyncResult=err;
mState=(err==OK)?
STATE_UNPREPARED:
STATE_IDLE;
//回到driver中,流转播放器状态进入下一阶段
mCondition.broadcast();
下面就来看看具体有哪些source,它们都继承自NuPlayer:
Source(NuPlayerSource.h&
NuPlayerSource.cpp)
1.HTTP-进一步判断是以下的哪一种:
HTTPLiveSource,RTSPSource,GenericSource
2.File-GenericSource
3.StreamSource-StreamingSource
4.DataSource-GenericSource
GenericSource
nuplayer/GenericSource.h&
Ge