Android NuPlayer要点详解Word文档下载推荐.docx

上传人:b****2 文档编号:3765340 上传时间:2023-05-02 格式:DOCX 页数:56 大小:104.19KB
下载 相关 举报
Android NuPlayer要点详解Word文档下载推荐.docx_第1页
第1页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第2页
第2页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第3页
第3页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第4页
第4页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第5页
第5页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第6页
第6页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第7页
第7页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第8页
第8页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第9页
第9页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第10页
第10页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第11页
第11页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第12页
第12页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第13页
第13页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第14页
第14页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第15页
第15页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第16页
第16页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第17页
第17页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第18页
第18页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第19页
第19页 / 共56页
Android NuPlayer要点详解Word文档下载推荐.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Android NuPlayer要点详解Word文档下载推荐.docx

《Android NuPlayer要点详解Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Android NuPlayer要点详解Word文档下载推荐.docx(56页珍藏版)》请在冰点文库上搜索。

Android NuPlayer要点详解Word文档下载推荐.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2