收藏 分销(赏)

Android-Multimedia框架总结(二十二)MediaCodec中C--中创建到start过程及状态变换.doc

上传人:仙人****88 文档编号:11227423 上传时间:2025-07-08 格式:DOC 页数:15 大小:105KB 下载积分:10 金币
下载 相关 举报
Android-Multimedia框架总结(二十二)MediaCodec中C--中创建到start过程及状态变换.doc_第1页
第1页 / 共15页
Android-Multimedia框架总结(二十二)MediaCodec中C--中创建到start过程及状态变换.doc_第2页
第2页 / 共15页


点击查看更多>>
资源描述
Android Multimedia框架总结(二十二)MediaCodec中C++中创建到start过程及状态变换 从今天开始,将深入源码中看看其c++过程,看下Agenda如下: mediacodec.h CreateByType initMediaCodec中BufferInfo内部类: configure过程 start BufferInfo在MediaCodec.h中对应是一个结构体 //create by 逆流的鱼yuiop on 2016/12/11 //blog地址: struct BufferInfo { uint32_t mBufferID; sp<ABuffer> mData; sp<ABuffer> mEncryptedData; sp<IMemory> mSharedEncryptedBuffer; sp<AMessage> mNotify; sp<AMessage> mFormat; bool mOwnedByClient; }; mediacodec.h的方法的声明,位于\frameworks\av\include\media\stagefright下 //create by 逆流的鱼yuiop on 2016/12/11 //blog地址: 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<MediaCodec> CreateByType( const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL, pid_t pid = kNoPid); static sp<MediaCodec> CreateByComponentName( const sp<ALooper> &looper, const char *name, status_t *err = NULL, pid_t pid = kNoPid); static sp<PersistentSurface> CreatePersistentInputSurface(); status_t configure( const sp<AMessage> &format, const sp<Surface> &nativeWindow, const sp<ICrypto> &crypto, uint32_t flags); status_t setCallback(const sp<AMessage> &callback); status_t setOnFrameRenderedNotification(const sp<AMessage> &notify); status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); status_t setInputSurface(const sp<PersistentSurface> &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<AMessage> *format) const; status_t getInputFormat(sp<AMessage> *format) const; status_t getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const; status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const; status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const; status_t getOutputBuffer(size_t index, sp<ABuffer> *buffer); status_t getOutputFormat(size_t index, sp<AMessage> *format); status_t getInputBuffer(size_t index, sp<ABuffer> *buffer); status_t setSurface(const sp<Surface> &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<AMessage> &notify); status_t getName(AString *componentName) const; status_t setParameters(const sp<AMessage> &params); // 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<FrameRenderTracker::Info> done, sp<AMessage> &msg); protected: virtual ~MediaCodec(); virtual void onMessageReceived(const sp<AMessage> &msg); private: // used by ResourceManagerClient status_t reclaim(bool force = false); friend struct ResourceManagerClient; private: enum State { UNINITIALIZED, INITIALIZING, INITIALIZED, CONFIGURING, CONFIGURED, STARTING, STARTED, FLUSHING, FLUSHED, 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<ABuffer> mData; sp<ABuffer> mEncryptedData; sp<IMemory> mSharedEncryptedBuffer; sp<AMessage> mNotify; sp<AMessage> mFormat; bool mOwnedByClient; }; struct ResourceManagerServiceProxy : public IBinder::DeathRecipient { ResourceManagerServiceProxy(pid_t pid); ~ResourceManagerServiceProxy(); void init(); // implements DeathRecipient virtual void binderDied(const wp<IBinder>& /*who*/); void addResource( int64_t clientId, const sp<IResourceManagerClient> client, const Vector<MediaResource> &resources); void removeResource(int64_t clientId); bool reclaimResource(const Vector<MediaResource> &resources); private: Mutex mLock; sp<IResourceManagerService> mService; pid_t mPid; }; State mState; bool mReleasedByResourceManager; sp<ALooper> mLooper; sp<ALooper> mCodecLooper; sp<CodecBase> mCodec; AString mComponentName; sp<AReplyToken> mReplyID; uint32_t mFlags; status_t mStickyError; sp<Surface> mSurface; SoftwareRenderer *mSoftRenderer; sp<AMessage> mOutputFormat; sp<AMessage> mInputFormat; sp<AMessage> mCallback; sp<AMessage> mOnFrameRenderedNotification; sp<MemoryDealer> mDealer; sp<IResourceManagerClient> mResourceManagerClient; sp<ResourceManagerServiceProxy> 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<AMessage> 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<size_t> mAvailPortBuffers[2]; Vector<BufferInfo> mPortBuffers[2]; int32_t mDequeueInputTimeoutGeneration; sp<AReplyToken> mDequeueInputReplyID; int32_t mDequeueOutputTimeoutGeneration; sp<AReplyToken> mDequeueOutputReplyID; sp<ICrypto> mCrypto; List<sp<ABuffer> > mCSD; sp<AMessage> mActivityNotify; bool mHaveInputSurface; bool mHavePendingInputBuffers; MediaCodec(const sp<ALooper> &looper, pid_t pid); static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response); void PostReplyWithError(const sp<AReplyToken> &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<AMessage> &msg); status_t onQueueInputBuffer(const sp<AMessage> &msg); status_t onReleaseOutputBuffer(const sp<AMessage> &msg); ssize_t dequeuePortBuffer(int32_t portIndex); status_t getBufferAndFormat( size_t portIndex, size_t index, sp<ABuffer> *buffer, sp<AMessage> *format); bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false); bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false); void cancelPendingDequeueOperations(); void extractCSD(const sp<AMessage> &format); status_t queueCSDInputBuffer(size_t bufferIndex); status_t handleSetSurface(const sp<Surface> &surface); status_t connectToSurface(const sp<Surface> &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<AMessage> &params); status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &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地址: // static sp<MediaCodec> MediaCodec::CreateByType( const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err, pid_t pid) { sp<MediaCodec> 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地址: status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { mResourceManagerService->init(); // 保存 初始参数,到时用于reset mInitName = name; mInitNameIsType = nameIsType; mInitIsEncoder = encoder; // 目前视频解码器不能马上从OMX_FillThisBuffer返回,违反OpenMAX规格,直到提醒我们需要入驻另一个第三方的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<IMediaCodecList> 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<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); Vector<AString> mimes; info->getSupportedMimes(&mimes); for (size_t i = 0; i < mimes.size(); i++) { if
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服