久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程及狀態(tài)變換

時間:2019-05-13 19:14:23下載本文作者:會員上傳
簡介:寫寫幫文庫小編為你整理了多篇相關(guān)的《Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程及狀態(tài)變換》,但愿對你工作學(xué)習(xí)有幫助,當(dāng)然你在寫寫幫文庫還可以找到更多《Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程及狀態(tài)變換》。

第一篇:Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程及狀態(tài)變換

Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程

及狀態(tài)變換

從今天開始,將深入源碼中看看其c++過程,看下Agenda如下:

mediacodec.h CreateByType initMediaCodec中BufferInfo內(nèi)部類: configure過程 start BufferInfo在MediaCodec.h中對應(yīng)是一個結(jié)構(gòu)體

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin struct BufferInfo {

uint32_t mBufferID;

sp mData;

sp mEncryptedData;

sp mSharedEncryptedBuffer;

sp mNotify;

sp mFormat;

bool mOwnedByClient;};mediacodec.h的方法的聲明,位于frameworksavincludemediastagefright下

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin namespace android { struct ABuffer;struct AMessage;struct AReplyToken;struct AString;struct CodecBase;struct IBatteryStats;struct ICrypto;class IMemory;struct MemoryDealer;class IResourceManagerClient;class IResourceManagerService;struct PersistentSurface;struct SoftwareRenderer;struct Surface;struct MediaCodec : public AHandler {

enum ConfigureFlags {

CONFIGURE_FLAG_ENCODE

= 1,};

enum BufferFlags {

BUFFER_FLAG_SYNCFRAME

= 1,BUFFER_FLAG_CODECCONFIG = 2,BUFFER_FLAG_EOS

= 4,};

enum {

CB_INPUT_AVAILABLE = 1,CB_OUTPUT_AVAILABLE = 2,CB_ERROR = 3,CB_OUTPUT_FORMAT_CHANGED = 4,CB_RESOURCE_RECLAIMED = 5,};

static const pid_t kNoPid =-1;

static sp CreateByType(const sp &looper, const char *mime, bool encoder, status_t *err = NULL,pid_t pid = kNoPid);

static sp CreateByComponentName(const sp &looper, const char *name, status_t *err = NULL,pid_t pid = kNoPid);

static sp

CreatePersistentInputSurface();

status_t configure(const sp &format,const sp &nativeWindow,const sp &crypto,uint32_t flags);

status_t setCallback(const sp &callback);

status_t setOnFrameRenderedNotification(const sp ¬ify);

status_t createInputSurface(sp* bufferProducer);

status_t setInputSurface(const sp

&surface);

status_t start();

// Returns to a state in which the component remains allocated but

// unconfigured.status_t stop();

// Resets the codec to the INITIALIZED state.Can be called after an error

// has occured to make the codec usable.status_t reset();

// Client MUST call release before releasing final reference to this

// object.status_t release();

status_t flush();

status_t queueInputBuffer(size_t index,size_t offset,size_t size,int64_t presentationTimeUs,uint32_t flags,AString *errorDetailMsg = NULL);

status_t queueSecureInputBuffer(size_t index,size_t offset,const CryptoPlugin::SubSample *subSamples,size_t numSubSamples,const uint8_t key[16],const uint8_t iv[16],CryptoPlugin::Mode mode,int64_t presentationTimeUs,uint32_t flags,AString *errorDetailMsg = NULL);

status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);

status_t dequeueOutputBuffer(size_t *index,size_t *offset,size_t *size,int64_t *presentationTimeUs,uint32_t *flags,int64_t timeoutUs = 0ll);

status_t renderOutputBufferAndRelease(size_t index, int64_t timestampNs);

status_t renderOutputBufferAndRelease(size_t index);

status_t releaseOutputBuffer(size_t index);

status_t signalEndOfInputStream();

status_t getOutputFormat(sp *format)const;

status_t getInputFormat(sp *format)const;

status_t getWidevineLegacyBuffers(Vector > *buffers)const;

status_t getInputBuffers(Vector > *buffers)const;

status_t getOutputBuffers(Vector > *buffers)const;

status_t getOutputBuffer(size_t index, sp *buffer);

status_t getOutputFormat(size_t index, sp *format);

status_t getInputBuffer(size_t index, sp *buffer);

status_t setSurface(const sp &nativeWindow);

status_t requestIDRFrame();

// Notification will be posted once there “is something to do”, i.e.// an input/output buffer has become available, a format change is

// pending, an error is pending.void requestActivityNotification(const sp ¬ify);

status_t getName(AString *componentName)const;

status_t setParameters(const sp ¶ms);

// Create a MediaCodec notification message from a list of rendered or dropped render infos

// by adding rendered frame information to a base notification message.Returns the number

// of frames that were rendered.static size_t CreateFramesRenderedMessage(std::list done, sp &msg);protected:

virtual ~MediaCodec();

virtual void onMessageReceived(const sp &msg);private:

// used by ResourceManagerClient

status_t reclaim(bool force = false);

friend struct ResourceManagerClient;private:

enum State {

UNINITIALIZED,INITIALIZING,INITIALIZED,CONFIGURING,CONFIGURED,STARTING,STARTED,F(xiàn)LUSHING,F(xiàn)LUSHED,STOPPING,RELEASING,};

enum {

kPortIndexInput

= 0,kPortIndexOutput

= 1,};

enum {

kWhatInit

= 'init',kWhatConfigure

= 'conf',kWhatSetSurface

= 'sSur',kWhatCreateInputSurface

= 'cisf',kWhatSetInputSurface

= 'sisf',kWhatStart

= 'strt',kWhatStop

= 'stop',kWhatRelease

= 'rele',kWhatDequeueInputBuffer

= 'deqI',kWhatQueueInputBuffer

= 'queI',kWhatDequeueOutputBuffer

= 'deqO',kWhatReleaseOutputBuffer

= 'relO',kWhatSignalEndOfInputStream

= 'eois',kWhatGetBuffers

= 'getB',kWhatFlush

= 'flus',kWhatGetOutputFormat

= 'getO',kWhatGetInputFormat

= 'getI',kWhatDequeueInputTimedOut

= 'dITO',kWhatDequeueOutputTimedOut

= 'dOTO',kWhatCodecNotify

= 'codc',kWhatRequestIDRFrame

= 'ridr',kWhatRequestActivityNotification

= 'racN',kWhatGetName

= 'getN',kWhatSetParameters

= 'setP',kWhatSetCallback

= 'setC',kWhatSetNotification

= 'setN',};

enum {

kFlagUsesSoftwareRenderer

= 1,kFlagOutputFormatChanged

= 2,kFlagOutputBuffersChanged

= 4,kFlagStickyError

= 8,kFlagDequeueInputPending

= 16,kFlagDequeueOutputPending

= 32,kFlagIsSecure

= 64,kFlagSawMediaServerDie

= 128,kFlagIsEncoder

= 256,kFlagGatherCodecSpecificData

= 512,kFlagIsAsync

= 1024,kFlagIsComponentAllocated

= 2048,kFlagPushBlankBuffersOnShutdown = 4096,};

struct BufferInfo {

uint32_t mBufferID;

sp mData;

sp mEncryptedData;

sp mSharedEncryptedBuffer;

sp mNotify;

sp mFormat;

bool mOwnedByClient;

};

struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {

ResourceManagerServiceProxy(pid_t pid);

~ResourceManagerServiceProxy();

void init();

// implements DeathRecipient

virtual void binderDied(const wp& /*who*/);

void addResource(int64_t clientId,const sp client,const Vector &resources);

void removeResource(int64_t clientId);

bool reclaimResource(const Vector &resources);

private:

Mutex mLock;

sp mService;

pid_t mPid;

};

State mState;

bool mReleasedByResourceManager;

sp mLooper;

sp mCodecLooper;

sp mCodec;

AString mComponentName;

sp mReplyID;

uint32_t mFlags;

status_t mStickyError;

sp mSurface;

SoftwareRenderer *mSoftRenderer;

sp mOutputFormat;

sp mInputFormat;

sp mCallback;

sp mOnFrameRenderedNotification;

sp mDealer;

sp mResourceManagerClient;

sp mResourceManagerService;

bool mBatteryStatNotified;

bool mIsVideo;

int32_t mVideoWidth;

int32_t mVideoHeight;

int32_t mRotationDegrees;

// initial create parameters

AString mInitName;

bool mInitNameIsType;

bool mInitIsEncoder;

// configure parameter

sp mConfigureMsg;

// Used only to synchronize asynchronous getBufferAndFormat

// across all the other(synchronous)buffer state change

// operations, such as de/queueIn/OutputBuffer, start and

// stop/flush/reset/release.Mutex mBufferLock;

List mAvailPortBuffers[2];

Vector mPortBuffers[2];

int32_t mDequeueInputTimeoutGeneration;

sp mDequeueInputReplyID;

int32_t mDequeueOutputTimeoutGeneration;

sp mDequeueOutputReplyID;

sp mCrypto;

List > mCSD;

sp mActivityNotify;

bool mHaveInputSurface;

bool mHavePendingInputBuffers;

MediaCodec(const sp &looper, pid_t pid);

static status_t PostAndAwaitResponse(const sp &msg, sp *response);

void PostReplyWithError(const sp &replyID, int32_t err);

status_t init(const AString &name, bool nameIsType, bool encoder);

void setState(State newState);

void returnBuffersToCodec();

void returnBuffersToCodecOnPort(int32_t portIndex);

size_t updateBuffers(int32_t portIndex, const sp &msg);

status_t onQueueInputBuffer(const sp &msg);

status_t onReleaseOutputBuffer(const sp &msg);

ssize_t dequeuePortBuffer(int32_t portIndex);

status_t getBufferAndFormat(size_t portIndex, size_t index,sp *buffer, sp *format);

bool handleDequeueInputBuffer(const sp &replyID, bool newRequest = false);

bool handleDequeueOutputBuffer(const sp &replyID, bool newRequest = false);

void cancelPendingDequeueOperations();

void extractCSD(const sp &format);

status_t queueCSDInputBuffer(size_t bufferIndex);

status_t handleSetSurface(const sp &surface);

status_t connectToSurface(const sp &surface);

status_t disconnectFromSurface();

void postActivityNotificationIfPossible();

void onInputBufferAvailable();

void onOutputBufferAvailable();

void onError(status_t err, int32_t actionCode, const char *detail = NULL);

void onOutputFormatChanged();

status_t onSetParameters(const sp ¶ms);

status_t amendOutputFormatWithCodecSpecificData(const sp &buffer);

void updateBatteryStat();

bool isExecuting()const;

uint64_t getGraphicBufferSize();

void addResource(const String8 &type, const String8 &subtype, uint64_t value);

bool hasPendingBuffer(int portIndex);

bool hasPendingBuffer();

/* called to get the last codec error when the sticky flag is set.* if no such codec error is found, returns UNKNOWN_ERROR.*/

inline status_t getStickyError()const {

return mStickyError!= 0 ? mStickyError : UNKNOWN_ERROR;

}

inline void setStickyError(status_t err){

mFlags |= kFlagStickyError;

mStickyError = err;

}

DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);};} // namespace android CreateByType

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin // static sp MediaCodec::CreateByType(const sp &looper, const char *mime, bool encoder, status_t *err, pid_t pid){

sp codec = new MediaCodec(looper, pid);//這果實際上new出MediaCodec對象

const status_t ret = codec->init(mime, true /* nameIsType */, encoder);

if(err!= NULL){

*err = ret;

}

return ret == OK ? codec : NULL;// NULL deallocates codec.} 接著到init過程

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder){

mResourceManagerService->init();

// 保存 初始參數(shù),到時用于reset

mInitName = name;

mInitNameIsType = nameIsType;

mInitIsEncoder = encoder;

// 目前視頻解碼器不能馬上從OMX_FillThisBuffer返回,違反OpenMAX規(guī)格,直到提醒我們需要入駐另一個第三方的looper釋放在事件隊列中。

if(nameIsType ||!strncasecmp(name.c_str(), “omx.”, 4)){//omx.匹配

mCodec = new ACodec;//實例化ACodec

} else if(!nameIsType

&&!strncasecmp(name.c_str(), “android.filter.”, 15)){

mCodec = new MediaFilter;// 實例化MediaFilter

} else {

return NAME_NOT_FOUND;

}

bool secureCodec = false;

if(nameIsType &&!strncasecmp(name.c_str(), “video/”, 6)){

mIsVideo = true;

} else {

AString tmp = name;

if(tmp.endsWith(“.secure”)){

secureCodec = true;

tmp.erase(tmp.size()-7, 7);

}

const sp mcl = MediaCodecList::getInstance();

if(mcl == NULL){

mCodec = NULL;// remove the codec.return NO_INIT;// if called from Java should raise IOException

}

ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());

if(codecIdx >= 0){

const sp info = mcl->getCodecInfo(codecIdx);

Vector mimes;

info->getSupportedMimes(&mimes);

for(size_t i = 0;i < mimes.size();i++){

if(mimes[i].startsWith(“video/”)){

mIsVideo = true;

break;

}

}

}

}

if(mIsVideo){

// video codec needs dedicated looper

if(mCodecLooper == NULL){

mCodecLooper = new ALooper;

mCodecLooper->setName(“CodecLooper”);//設(shè)置名字為CodecLooper

mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);

}

mCodecLooper->registerHandler(mCodec);

} else {

mLooper->registerHandler(mCodec);

}

mLooper->registerHandler(this);

mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));

sp msg = new AMessage(kWhatInit, this);

msg->setString(“name”, name);

msg->setInt32(“nameIsType”, nameIsType);

if(nameIsType){

msg->setInt32(“encoder”, encoder);

}

status_t err;

Vector resources;

const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;

const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;

resources.push_back(MediaResource(String8(type), String8(subtype), 1));

for(int i = 0;i <= kMaxRetry;++i){

if(i > 0){

// Don't try to reclaim resource for the first time.if(!mResourceManagerService->reclaimResource(resources)){

break;

}

}

sp response;

err = PostAndAwaitResponse(msg, &response);

if(!isResourceError(err)){

break;

}

}

return err;} configure過程

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin status_t MediaCodec::configure(const sp &format,const sp &surface,const sp &crypto,uint32_t flags){

sp msg = new AMessage(kWhatConfigure, this);

if(mIsVideo){

format->findInt32(“width”, &mVideoWidth);

format->findInt32(“height”, &mVideoHeight);

if(!format->findInt32(“rotation-degrees”, &mRotationDegrees)){

mRotationDegrees = 0;

}

}

msg->setMessage(“format”, format);

msg->setInt32(“flags”, flags);

msg->setObject(“surface”, surface);

if(crypto!= NULL){

msg->setPointer(“crypto”, crypto.get());

}

// save msg for reset

mConfigureMsg = msg;

status_t err;

Vector resources;

const char *type =(mFlags & kFlagIsSecure)?

kResourceSecureCodec : kResourceNonSecureCodec;

const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;

resources.push_back(MediaResource(String8(type), String8(subtype), 1));

// Don't know the buffer size at this point, but it's fine to use 1 because

// the reclaimResource call doesn't consider the requester's buffer size for now.resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));

for(int i = 0;i <= kMaxRetry;++i){

if(i > 0){

// Don't try to reclaim resource for the first time.if(!mResourceManagerService->reclaimResource(resources)){

break;

}

}

sp response;

err = PostAndAwaitResponse(msg, &response);

if(err!= OK && err!= INVALID_OPERATION){

// MediaCodec now set state to UNINITIALIZED upon any fatal error.// To maintain backward-compatibility, do a reset()to put codec

// back into INITIALIZED state.// But don't reset if the err is INVALID_OPERATION, which means

// the configure failure is due to wrong state.ALOGE(“configure failed with err 0x%08x, resetting...”, err);

reset();

}

if(!isResourceError(err)){

break;

}

}

return err;} start過程

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin status_t MediaCodec::start(){

sp msg = new AMessage(kWhatStart, this);

status_t err;

Vector resources;

const char *type =(mFlags & kFlagIsSecure)?

kResourceSecureCodec : kResourceNonSecureCodec;

const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;

resources.push_back(MediaResource(String8(type), String8(subtype), 1));

// Don't know the buwww.tmdps.cnffer size at this point, but it's fine to use 1 because

// the reclaimResource call doesn't consider the requester's buffer size for now.resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));

for(int i = 0;i <= kMaxRetry;++i){

if(i > 0){

// Don't try to reclaim resource for the first time.if(!mResourceManagerService->reclaimResource(resources)){

break;

}

// Recover codec from previous error before retry start.err = reset();

if(err!= OK){

ALOGE(“retrying start: failed to reset codec”);

break;

}

sp response;

err = PostAndAwaitResponse(mConfigureMsg, &response);

if(err!= OK){

ALOGE(“retrying start: failed to configure codec”);

break;

}

}

sp response;

err = PostAndAwaitResponse(msg, &response);

if(!isResourceError(err)){

break;

}

}

return err;} stop過程

//create by 逆流的魚yuiop on 2016/12/11 //blog地址:http://blog.csdn.net/hejjunlin status_t MediaCodec::stop(){

sp msg = new AMessage(kWhatStop, this);

sp response;

return PostAndAwaitResponse(msg, &response);} 找到對應(yīng)的AMessage.cpp,對應(yīng)同樣有一套AHandler.cpp,及ALooper.cpp,這此組成了在c++中一套機制,接口 方法的名字和Java層保持一致。

所有message都在onMessageReceived方法中處理,MediaCodec的各個狀態(tài)的相關(guān)切換。

void MediaCodec::onMessageReceived(const sp &msg){

switch(mState){

case INITIALIZING://初始化中

{

setState(UNINITIALIZED);

break;

}

case CONFIGURING://配置中

{

setState(actionCode == ACTION_CODE_FATAL ?

UNINITIALIZED : INITIALIZED);

break;

}

case STARTING://start中

{

setState(actionCode == ACTION_CODE_FATAL ?

UNINITIALIZED : CONFIGURED);

break;

}

case STOPPING://停止中

case RELEASING://釋放中

{

// Ignore the error, assuming we'll still get

// the shnc630.comutdown complete notification.sendErrorResponse = false;

if(mFlags & kFlagSawMediaServerDie){

// MediaServer died, there definitely won't

// be a shutdown complete notification after

// all.// note that we're directly going from

// STOPPING->UNINITIALIZED, instead of the

// usual STOPPING->INITIALIZED state.setState(UNINITIALIZED);

if(mState == RELEASING){

mComponentName.clear();

}

STARTED);

(new AMessage)->postReply(mReplyID);

}

break;}

case FLUSHING://刷新中 {

if(actionCode == ACTION_CODE_FATAL){

setState(UNINITIALIZED);

} else {

setState((mFlags & kFlagIsAsync)? FLUSHED :

}

break;}

case FLUSHED: case STARTED: {

sendErrorResponse = false;

setStickyError(err);

postActivityNotificationIfPossible();

cancelPendingDequeueOperations();

if(mFlags & kFlagIsAsync){

onError(err, actionCode);

}

switch(actionCode){

case ACTION_CODE_TRANSIENT:

break;

case ACTION_CODE_RECOVERABLE:

setState(INITIALIZED);

break;

default:

setState(UNINITIALIZED);

break;

}

break;

}

default:

{

sendErrorResponse = false;

setStickyError(err);

postActivityNotificationIfPossible();

// actionCode in an uninitialized state is always fatal.if(mState == UNINITIALIZED){

}

actionCode = ACTION_CODE_FATAL;

}

if(mFlags & kFlagIsAsync){

onError(err, actionCode);

}

switch(actionCode){

case ACTION_CODE_TRANSIENT:

break;

case ACTION_CODE_RECOVERABLE:

setState(INITIALIZED);

break;

default:

setState(UNINITIALIZED);

break;

}

break;}

下載Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程及狀態(tài)變換word格式文檔
下載Android Multimedia框架總結(jié)(二十二)MediaCodec中C++中創(chuàng)建到start過程及狀態(tài)變換.doc
將本文檔下載到自己電腦,方便修改和收藏,請勿使用迅雷等下載。
點此處下載文檔

文檔為doc格式


聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),未作人工編輯處理,也不承擔(dān)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)有涉嫌版權(quán)的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進(jìn)行舉報,并提供相關(guān)證據(jù),工作人員會在5個工作日內(nèi)聯(lián)系你,一經(jīng)查實,本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

相關(guān)范文推薦

    主站蜘蛛池模板: 国产精品99久久精品| 亚洲高清国产av拍精品青青草原| 日韩高清在线观看不卡一区二区| 国产精品无码一区二区牛牛| av无码中出一区二区三区| 婷婷色综合视频在线观看| 男人扒开女人腿做爽爽视频| 99欧美日本一区二区留学生| 中国精学生妹品射精久久| 欧美性xxxxx极品老少| 狼友av永久网站免费观看| 苍井空毛片精品久久久| 一本精品中文字幕在线| 无码区日韩特区永久免费系列| 国产精品婷婷久久爽一下| 人人妻人人澡人人爽人人精品电影| 一区一区三区产品乱码| 色妞ww精品视频7777| 国产又黄又猛又粗又爽的a片动漫| 让少妇高潮无乱码高清在线观看| 欧美性色黄大片www喷水| 爆乳熟妇一区二区三区霸乳| 少妇无码一区二区三区| 国产成人免费视频| 国产成人无码aⅴ片在线观看导航| 亚洲 丝袜 另类 校园 欧美| av人摸人人人澡人人超碰手机版| 欧洲欧美人成视频在线| 人妻插b视频一区二区三区| 艳z门照片无码av| 美女av一区二区三区| 亚洲综合无码中文字幕第2页| 欧美亚洲国产成人一区二区三区| аⅴ资源中文在线天堂| 国产成人精品视频网站| 国产一卡二卡三新区2022| 狼狼综合久久久久综合网| 人妻忍着娇喘被中进中出视频| 亚洲r成人av久久人人爽| 国产日产精品一区二区三区四区的特点| 久久综合久久久久88|