Android Media Framework(六)插件式编程与OMXStore

2024-06-16 16:52

本文主要是介绍Android Media Framework(六)插件式编程与OMXStore,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

OpenMAX IL Spec阅读到上一节就结束了,这一节开始正式进入到Framework阅读阶段,我们将了解OpenMAX框架是如何与Android Framework连接的。

1、插件式编程

插件式编程(Plugin-based Programming)是一种软件开发模式,它允许开发者通过编写独立的、可插拔的模块(称为插件)来扩展应用程序的功能,而无需修改应用程序的核心代码。这种模式使得软件具有高度可扩展性、可维护性和灵活性。

插件式编程的核心思想是将应用程序的核心功能与扩展功能分离开来。核心功能负责提供基本的、必要的服务,而扩展功能则通过插件的形式添加到应用程序中,以提供额外的、可选的功能。

如何实现插件式编程?

  • 定义插件接口:定义插件需要实现的接口,明确应用程序调用插件的方式。

  • 编写插件:根据接口规范编写插件代码,实现所需的功能。

  • 加载和卸载插件:在应用程序中编写代码来动态地加载和卸载插件。

  • 调用插件功能:在应用程序中通过接口调用插件提供的功能。

举一个简单的例子:

首先定义插件需要实现的接口PluginInterface:

// PluginInterface.h
#ifndef PLUGIN_INTERFACE_H
#define PLUGIN_INTERFACE_Hclass PluginInterface {
public:virtual void execute() = 0;
};// 应用程序调用插件的方式
typedef PluginInterface* (*CreatePluginFunc)();
typedef void (*DestroyPluginFunc)(PluginInterface*);#endif // PLUGIN_INTERFACE_H

接着实现两个插件,这里贴出插件1的代码:

// MyPlugin_1.cpp 
#include <iostream>
#include "PluginInterface.h"class MyPlugin1 : public PluginInterface {
public:void execute() override {std::cout << "MyPlugin 1 executing!" << std::endl;  }
};extern "C" PluginInterface* createPlugin() {std::cout << "create MyPlugin 1!" << std::endl;return new MyPlugin1();
}extern "C" void destroyPlugin(PluginInterface* plugin) {std::cout << "delete MyPlugin 1!" << std::endl;delete plugin;
}

注意extern “C”,这是为了确保C++的name mangling(名称修饰)不会影响这些函数的名称,从而能够准确获取到动态库中的函数。

最后是主程序加载卸载插件、调用插件功能:

// main.cpp
#include <iostream>
#include <dlfcn.h>
#include "PluginInterface.h"static int loadAndExec(const char *libname) {void* handle = dlopen(libname, RTLD_LAZY); if (!handle) {std::cout << "Cannot open library : " << libname << std::endl;  return -1;} CreatePluginFunc createPlugin = (CreatePluginFunc)dlsym(handle, "createPlugin");if (!createPlugin) {std::cout << "Cannot load symbol 'createPlugin' of library "<< libname << std::endl;dlclose(handle);handle = NULL;return -1;}DestroyPluginFunc destroyPlugin = (DestroyPluginFunc)dlsym(handle, "destroyPlugin");if (!destroyPlugin) {std::cout << "Cannot load symbol 'destroyPlugin' of library "<< libname << std::endl;dlclose(handle);handle = NULL;return -1;}PluginInterface* plugin = createPlugin();plugin->execute();destroyPlugin(plugin);plugin = NULL;dlclose(handle);handle = NULL;return 0;
}int main() {loadAndExec("./libMyPlugin_1.so");loadAndExec("./libMyPlugin_2.so");return 0;
}

代码执行结果

./test
// create MyPlugin 1!
// MyPlugin 1 executing!
// delete MyPlugin 1!
// create MyPlugin 2!
// MyPlugin 2 executing!
// delete MyPlugin 2!

在该示例中,MyPlugin1和MyPlugin2分别被编译为libMyPlugin_1.so和libMyPlugin_2.so,使用这两个插件时要用dlopen打开动态库,用dlsym获取预定义的函数。如果想用动态链接的方式链接这两个lib,由于包含同名函数,编译时就会出错了。

代码下载:公众号后台回复PluginDemo。

链接:https://pan.baidu.com/s/1uVemskxHvOPJhDx8mv-6IQ
提取码:8888

2、OMXStore

为了让芯片厂商能够在不修改原生代码的情况下使用硬件编解码组件,Android采用了插件式编程技术来动态加载厂商的实现。

代码参考:frameworks/av/media/libstagefright/omx/OMXStore.cpp

OMXStore::OMXStore() {// ......addVendorPlugin();addPlatformPlugin();
}

OMXStore的构造函数调用了两个方法:

  • addPlatformPlugin:添加平台插件,平台指的是Android系统自带/内置的;
  • addVendorPlugin:添加厂商实现的插件,厂商指的各大芯片厂商,即OMX组件实现者;
void OMXStore::addVendorPlugin() {addPlugin("libstagefrighthw.so");
}void OMXStore::addPlatformPlugin() {addPlugin("libstagefright_softomx_plugin.so");
}

展开两个方法可以看到,OMXStore想要加载两个lib,libstagefright_softomx_plugin.so由Android平台提供,libstagefrighthw.so由厂商实现。libstagefrighthw.so应该如何实现呢?带着这个问题往下看addPlugin:

void OMXStore::addPlugin(const char *libname) {// 1.if (::android::base::GetIntProperty("vendor.media.omx", int64_t(1)) == 0) {return;}// 2. 打开libvoid *libHandle = android_load_sphal_library(libname, RTLD_NOW);if (libHandle == NULL) {return;}// 3. 获取lib中的createOMXPlugin函数指针typedef OMXPluginBase *(*CreateOMXPluginFunc)();CreateOMXPluginFunc createOMXPlugin =(CreateOMXPluginFunc)dlsym(libHandle, "createOMXPlugin");if (!createOMXPlugin)createOMXPlugin = (CreateOMXPluginFunc)dlsym(libHandle, "_ZN7android15createOMXPluginEv");// 4. OMXPluginBase *plugin = nullptr;if (createOMXPlugin) {plugin = (*createOMXPlugin)();}// 5. if (plugin) {mPlugins.push_back({ plugin, libHandle });// 6addPlugin(plugin);} else {android_unload_sphal_library(libHandle);}
}

关注公众号《青山渺渺》阅读全文

请添加图片描述

这篇关于Android Media Framework(六)插件式编程与OMXStore的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067002

相关文章

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

解决Entity Framework中自增主键的问题

《解决EntityFramework中自增主键的问题》:本文主要介绍解决EntityFramework中自增主键的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Entity Framework中自增主键问题解决办法1解决办法2解决办法3总结Entity Fram

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

CnPlugin是PL/SQL Developer工具插件使用教程

《CnPlugin是PL/SQLDeveloper工具插件使用教程》:本文主要介绍CnPlugin是PL/SQLDeveloper工具插件使用教程,具有很好的参考价值,希望对大家有所帮助,如有错... 目录PL/SQL Developer工具插件使用安装拷贝文件配置总结PL/SQL Developer工具插

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

maven中的maven-antrun-plugin插件示例详解

《maven中的maven-antrun-plugin插件示例详解》maven-antrun-plugin是Maven生态中一个强大的工具,尤其适合需要复用Ant脚本或实现复杂构建逻辑的场景... 目录1. 核心功能2. 典型使用场景3. 配置示例4. 关键配置项5. 优缺点分析6. 最佳实践7. 常见问题

MyBatis分页插件PageHelper深度解析与实践指南

《MyBatis分页插件PageHelper深度解析与实践指南》在数据库操作中,分页查询是最常见的需求之一,传统的分页方式通常有两种内存分页和SQL分页,MyBatis作为优秀的ORM框架,本身并未提... 目录1. 为什么需要分页插件?2. PageHelper简介3. PageHelper集成与配置3.

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑