IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android音视频——OMX 中 Nodeinstance 列表的管理与节点的操作 -> 正文阅读

[移动开发]Android音视频——OMX 中 Nodeinstance 列表的管理与节点的操作

在我们创建Componentinstance (OMX组件实例)后,需要对它里面的Nodelnstance列表 进行管理。

  • OMX对解码器组件Component的使用,是通过OMXNodelnstance来实现的。 OMXNodelnstance
    自身的动作包括 Nodeinstance 的生成(allocateNode )和删除
    (freeNode)o其实就是对niDispatchers和mNode】DToInstance进行添加和删除。
  • mNodelDToInstance 就是一个 key 为 node id? value 为 Nodeinstance 的键/值对列表。而
    niDispatchers 就是一个 key 为 node id, value 为 OMX::CallbackDispatcher
    的键/值对列 表。并且,每个 Nodeinstance 都拥有一个 0MX::CalIbackDispatchero
  • CallbackDispatcher的主要作用是在解码器组件Component发出回调动作后,将message
    分发给对应的OMXCodec客户端。

在我们了解到OMXNodelnstance列表管理后,每个OMXNodelnstance中都有Node节 点,若你需要给这些Node节点分配一些Buffer,下面看看对Node节点的操作过程。
在/frameworks/av/media/libstagefright/include/OMXNodeInstance.h 中:

struct OMXNodeInstance {
    OMXNodeInstance(
            OMX *owner, const sp<IOMXObserver> &observer, const char *name);
             void setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle);
 status_t prepareForAdaptivePlayback(
            OMX_U32 portIndex, OMX_BOOL enable,
           OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight);
    status_t useBuffer(
           OMX_U32 portIndex, const sp<IMemory> &params,
            OMX::buffer_id *buffer, OMX_U32 allottedSize);
//OMX: :Client通过此鹵数将已分配好的Buffer传给OMX服务器端组件,让其使用

 status_t allocateBuffer(
           OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
            void **buffer_data);
            //Client通过调用此函数让Component分配Buffer
   status_t allocateBufferWithBackup(
           OMX_U32 portIndex, const sp<IMemory> &params,
           OMX::buffer_id *buffer, OMX_U32 allottedSize);
 status_t freeBuffer(OMX_U32 portIndex, OMX::buffer_id buffer);
 //Client通过调用此函数让Component释放allocateBuffer分配的Buffer
 status_t fillBuffer(OMX::buffer_id buffer, int fenceFd);
 //Client通过调用此函数传递空的Buffer给Component?让其将处理好的
//数据填入其中。此函数会调用OMX标准接口 OMX_FillThisBuffer 

 static OMX_ERRORTYPE OnEmptyBufferDone(
           OMX_IN OMX_HANDLETYPE hComponent,
            OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
//Buffer的读取后,调用此回调函数,向Client发送EmptyBufferDone消息 

 static OMX_ERRORTYPE OnFillBufferDone(
            OMX_IN OMX_HANDLETYPE hComponent,
           OMX_IN OMX_PTR pAppData,
          OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
//在Component莞成相应的处理操作并将输出数据填入输出Buffer后,调用此回调 //函数,向 Client 发送 FillBufferDone 消息

sp<GraphicBufferSource> getGraphicBufferSource();
   void setGraphicBufferSource(const sp<GraphicBufferSource>& bufferSource);

    // 处理| msg 124;,并可以对其进行修改。返回true iff完全处理并 
    // |msg| does not need to be sent to the event listener.
    bool handleMessage(omx_message &msg);
    OMXNodeInstance(const OMXNodeInstance &);
    OMXNodeInstance &operator=(const OMXNodeInstance &);

当执行这些函数时,都是先通过findinstance在mNodelDToInstance列表中找到对应的 Nodeinstance,然后调用Nodelnstance对应的方法。
OMXCodec对具体的component函数的操作,是通过OMXNodelnstance来实现的,如 filIBuffer> emptyBuffer> sendCommand等,它们都是通过OMX Core.h中的宏定义间接调用 OMX_Component.h 的 OMX_COMPONENTTYPE 中的相应函数指针来完成的。OMX_Core.h 和OMX_Compoiient.h都是OpenMAX标准头文件。

OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
&OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
};
它把3个OMXNodelnstance类的静态方法注册给了 kCallbacks。kCallbacks实际就是struct OMX COMPONENTTYPE和struct OMX_CALLBACKTYPE的具体实现,而这两者就是在 OMX Core.h 和 OMX_Component.h 中定义的。
在哪里使用kCallbacks呢?下面看看OMX.cpp中的allocateNode函数:

status_t OMX::allocateNode(
        const char *name, const sp<IOMXObserver> &observer, node_id *node) {
   Mutex::Autolock autoLock(mLock);

   *node = 0;

    OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name);

    OMX_COMPONENTTYPE *handle;
    OMX_ERRORTYPE err = mMaster->makeComponentInstance(
           name, &OMXNodeInstance::kCallbacks,
            instance, &handle);

    if (err != OMX_ErrorNone) {
        ALOGE("FAILED to allocate omx component '%s' err=%s(%#x)", name, asString(err), err);

       instance->onGetHandleFailed();

       return StatusFromOMXError(err);
    }

    *node = makeNodeID(instance);
    mDispatchers.add(*node, new CallbackDispatcher(instance));

    instance->setHandle(*node, handle);

    mLiveNodes.add(IInterface::asBinder(observer), instance);
    IInterface::asBinder(observer)->linkToDeath(this);

    return OK;
}

事件处理函数传给了组件Componentinstance,也就是传给了具体芯片平台相关的OMX IL 层。
当组件有事件发生时,就会调用OMXNodelnstance中这几个注册过的事件处理函数:

OMX_ERRORTYPE OMXNodelnstance::OnEmptyBufferDone
OMX_ERRORTYPE OMXNodelnstance::OnFillBufferDone
OMX_ERRORTYPE OMXNodelnstance::OnEvent
而这几个函数又会调用OMX中对应的函数,也就是下面这3个函数:
OMX_ERRORTYPE OMX::OnEmptyBufferDone
OMX_ERRORTYPE OMX::OnFillBufferDone
OMX_ERRORTYPE OMX::OnEvent

总结一下,这儿个函数都采用相同的方式,即根据n odeid找到Cal I back Dispatcher,并把 事件信息传递出去,也就是findDispatcher(node)->post(msg)o
进一步地,需要了解CallbackDispatcher的实现机制。它内部开启了一个线程,使用了信 号量(signal)机制。
findDispatcher(node)->post(msg)是一个异步操作,只把消息传递过去,不会等待事件处理 完毕就返回。
问题来了,那么CallbackDispatcher是怎么处理接收到的消息的呢?查看以下代码:

bool OMX::CallbackDispatcher::loop() {
    for (;;) {
        std::list<omx_message> messages;
        {
            Mutex::Autolock autoLock(mLock);
           while (!mDone && mQueue.empty()) {
                mQueueChanged.wait(mLock);
            }
            if (mDone) {
                break;
            }
           messages.swap(mQueue);
        }
        dispatch(messages);
    }
    return false;
}

这样事件最终还是跨Binder传到OMXCodec里面,交给OMXCodecObserver 了? ?旦有 关于回调的过程,再从OMX服务器端发送到OMX客户端。我们又知道AwesomePlayer类中 持有OMX客户端,所以这些从OMX组件通知上来的消息就可以到达AwesomePlayer中。这 样就完成了 AwesomePlayer和OMX组件之间的通信。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:55:38  更:2022-08-06 10:57:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:20:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码