android multimedia的代码边读边记

来源:互联网 发布:软件研制过程概述 编辑:程序博客网 时间:2024/05/31 19:32

system/core/include/system/window.h中的ANativeWindow其实是一个底层的API接口定义,要求实现者去具体实现其中定义的接口,比如dequeueBuffer,queueBuffer,cancelBuffer,query,perform。而在目前的实现中,Surface就是这么一个具体去实现这些接口的类,定义在frameworks/native/libs/gui/Surface.cpp这个文件中。构造函数里第一步就是定义这些接口:

  42 Surface::Surface(
  43         const sp<IGraphicBufferProducer>& bufferProducer,
  44         bool controlledByApp)
  45     : mGraphicBufferProducer(bufferProducer),
  46       mCrop(Rect::EMPTY_RECT),
  47       mGenerationNumber(0),
  48       mSharedBufferMode(false),      
  49       mAutoRefresh(false),
  50       mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
  51       mSharedBufferHasBeenQueued(false)
  52 { 
  53     // Initialize the ANativeWindow function pointers.
  54     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
  55     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
  56     ANativeWindow::cancelBuffer     = hook_cancelBuffer;
  57     ANativeWindow::queueBuffer      = hook_queueBuffer;
  58     ANativeWindow::query            = hook_query;
  59     ANativeWindow::perform          = hook_perform;

......

然而很多实现最终是交给了它的成员变量去完成具体工作,比如:

mGraphicBufferProducer->queueBuffer;

mGraphicBufferProducer的定义如下:

sp<IGraphicBufferProducer> mGraphicBufferProducer

这个又是个binder的东东,它的native侧的实现是:

frameworks/native/libs/gui/BufferQueueProducer.cpp

如果是研究video播放,到这里可以停止了,这里已经是graphics里面的producer的概念了,video只要从这里拿buffer然后把解码完的数据放进去然后再queueBuffer就行了。


关于OMX这边的一些关键代码点:

frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp文件中

 171 OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
 172     &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
 173 };

这是对于三个回调函数的定义,三个函数的注册在:

frameworks/av/media/libstagefright/omx/OMX.cpp文件中

261     OMX_ERRORTYPE err = mMaster->makeComponentInstance(
262             name, &OMXNodeInstance::kCallbacks,
263             instance, &handle);

看来ACodec那边收到的消息是从这里发出去的:

690 OMX_ERRORTYPE OMX::OnEmptyBufferDone(
691         node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd) {
692     ALOGV("OnEmptyBufferDone buffer=%p", pBuffer);
693     
694     omx_message msg;
695     msg.type = omx_message::EMPTY_BUFFER_DONE;
696     msg.node = node;
697     msg.fenceFd = fenceFd;
698     msg.u.buffer_data.buffer = buffer;
699     
700     findDispatcher(node)->post(msg);
701     
702     return OMX_ErrorNone;
703 }  

接下来就是同一个文件中的另一个类了:

OMX::CallbackDispatcher


看看调用顺序:

OMX创建了OMXMaster:

169 OMX::OMX()
170     : mMaster(new OMXMaster),
171       mNodeCounter(0) {
172 }

OMX::allocateNode创建OMXNodeInstance并调用OMXMaster::makeComponentInstance:

243 status_t OMX::allocateNode(
244         const char *name, const sp<IOMXObserver> &observer,
245         sp<IBinder> *nodeBinder, node_id *node) {
246     Mutex::Autolock autoLock(mLock);
247         
248     *node = 0;
249     if (nodeBinder != NULL) {
250         *nodeBinder = NULL;
251     }
252     
253     if (mNodeIDToInstance.size() == kMaxNodeInstances) {
254         // all possible node IDs are in use
255         return NO_MEMORY;
256     }
257 
258     OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name);
259 
260     OMX_COMPONENTTYPE *handle;
261     OMX_ERRORTYPE err = mMaster->makeComponentInstance(
262             name, &OMXNodeInstance::kCallbacks,
263             instance, &handle);
264 
265     if (err != OMX_ErrorNone) {
266         ALOGE("FAILED to allocate omx component '%s' err=%s(%#x)", name, asString(err), err);
267 
268         instance->onGetHandleFailed();
269 
270         return StatusFromOMXError(err);
271     }
272     
273     *node = makeNodeID_l(instance);
274     mDispatchers.add(*node, new CallbackDispatcher(instance));
275 
276     instance->setHandle(*node, handle);
277 
278     mLiveNodes.add(IInterface::asBinder(observer), instance);
279     IInterface::asBinder(observer)->linkToDeath(this);
280 
281     return OK;
282 }

OMXMaster::makeComponentInstance调用plugin的makeComponentInstance并把callbacks传进去,这个plugin就是各芯片厂商自己的实现,是在OMXMaster的构造函数里调用addVendorPlugin->addPlugin(其实就是dlopen了libstagefrighthw.so)加载进来的:

145 OMX_ERRORTYPE OMXMaster::makeComponentInstance(
146         const char *name,
147         const OMX_CALLBACKTYPE *callbacks,
148         OMX_PTR appData,
149         OMX_COMPONENTTYPE **component) {
150     ALOGI("makeComponentInstance(%s) in %s process", name, mProcessName);
151     Mutex::Autolock autoLock(mLock);
152     
153     *component = NULL;
154     
155     ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
156     
157     if (index < 0) {
158         return OMX_ErrorInvalidComponentName;
159     }
160 
161     OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
162     OMX_ERRORTYPE err =
163         plugin->makeComponentInstance(name, callbacks, appData, component);


接下来的代码就不方便帖出来了,大概就是会在某个时候调用传进去的三个callback,一路就会调到OMXNodeInstance的三个函数,比如OMXNodeInstance::OnEmptyBufferDone,进而通过下面这句调到OMX::OnEmptyBufferDone

1720     return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
1721             instance->findBufferID(pBuffer), pBuffer, fenceFd);

在这里就和前面说的连接上了,OMX::OnEmptyBufferDone会去封个消息然后post出去,然后OMX::CallbackDispatcher会在loop中把消息从队列中取出来然后dispatch出去:

130 void OMX::CallbackDispatcher::dispatch(std::list<omx_message> &messages) {
131     if (mOwner == NULL) {
132         ALOGV("Would have dispatched a message to a node that's already gone.");
133         return;
134     }
135     mOwner->onMessages(messages);
136 }

这个mOwner就是OMXNodeInstance,于是调到:

1610 void OMXNodeInstance::onMessages(std::list<omx_message> &messages) {
1611     for (std::list<omx_message>::iterator it = messages.begin(); it != messages.end(); ) {
1612         if (handleMessage(*it)) {
1613             messages.erase(it++);
1614         } else {
1615             ++it;
1616         }
1617     }
1618 
1619     if (!messages.empty()) {
1620         mObserver->onMessages(messages);
1621     }
1622 }

这个mObserver就回到ACodec了:

在ACodec的onAllocateComponent函数中,有下面这段代码段:

6381     sp<CodecObserver> observer = new CodecObserver;
6382     IOMX::node_id node = 0;
6383   
6384     status_t err = NAME_NOT_FOUND; 
6385     for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
6386             ++matchIndex) {
6387         componentName = matchingCodecs[matchIndex];
6388         quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6389   
6390         pid_t tid = gettid();
6391         int prevPriority = androidGetThreadPriority(tid); 
6392         androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
6393         err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
6394         androidSetThreadPriority(tid, prevPriority);

这里的omx就是OMX.cpp里的OMX,所以传进去的就是CodecObserver,这个CodecObserver再通过OMX的allocateNode调用new OMXNodeInstance(this, observer, name)的时候传给了OMXNodeInstance。所以前面的onMessages最后是被CodecObserver处理了:



0 0
原创粉丝点击