1. Introduction:
As a cross-platform multimedia decoding framework, OMX is widely used on Android. Whether it is Android mobile platform or Android TV, OMX has become an inevitable choice for hard solution channels. On Android native media services, OMX It is an important underlying support of the stagefright framework. With the improvement of the Android version, media-related services are gradually refined. On Android P, OMX is included in the MediaCodec service.
2. OMX service startup and plug-in loading:
The Android init.rc
script will execute [email protected]
the script (framework/av/services/mediacodec):
service vendor.media.omx /vendor/bin/hw/[email protected]
class main
user mediacodec
group camera drmrpc mediadrm
capabilities SYS_NICE
ioprio rt 4
writepid /dev/cpuset/foreground/tasks
The script will start the [email protected] service. You can see from the mk in the corresponding path that this service is main_codecservice.cpp
compiled. Let's take a look at its main function:
int main(int argc __unused, char** argv)
{
strcpy(argv[0], "media.codec");
LOG(INFO) << "mediacodecservice starting";
signal(SIGPIPE, SIG_IGN);
SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
android::ProcessState::initWithDriver("/dev/vndbinder");
android::ProcessState::self()->startThreadPool();
::android::hardware::configureRpcThreadpool(64, false);
// Registration of customized codec services
void *registrantLib = dlopen(
"libmedia_codecserviceregistrant.so",
RTLD_NOW | RTLD_LOCAL);
if (registrantLib) {
RegisterCodecServicesFunc registerCodecServices =
reinterpret_cast<RegisterCodecServicesFunc>(
dlsym(registrantLib, "RegisterCodecServices"));
if (registerCodecServices) {
registerCodecServices();
} else {
LOG(WARNING) << "Cannot register additional services "
"-- corrupted library.";
}
} else {
// Default codec services
using namespace ::android::hardware::media::omx::V1_0;
sp<IOmxStore> omxStore = new implementation::OmxStore();
if (omxStore == nullptr) {
LOG(ERROR) << "Cannot create IOmxStore HAL service.";
} else if (omxStore->registerAsService() != OK) {
LOG(ERROR) << "Cannot register IOmxStore HAL service.";
}
/* 实例化OMX */
sp<IOmx> omx = new implementation::Omx();
if (omx == nullptr) {
LOG(ERROR) << "Cannot create IOmx HAL service.";
} else if (omx->registerAsService() != OK) {
LOG(ERROR) << "Cannot register IOmx HAL service.";
} else {
LOG(INFO) << "IOmx HAL service created.";
}
}
::android::hardware::joinRpcThreadpool();
}
OMX will be instantiated in the main function, look at the constructor of OMX:
Omx::Omx() :
mMaster(new OMXMaster()),
mParser() {
}
Here it will be instantiated OMXMaster
:
OMXMaster::OMXMaster()
: mVendorLibHandle(NULL) {
pid_t pid = getpid();
char filename[20];
snprintf(filename, sizeof(filename), "/proc/%d/comm", pid);
int fd = open(filename, O_RDONLY);
if (fd < 0) {
ALOGW("couldn't determine process name");
strlcpy(mProcessName, "<unknown>", sizeof(mProcessName));
} else {
ssize_t len = read(fd, mProcessName, sizeof(mProcessName));
if (len < 2) {
ALOGW("couldn't determine process name");
strlcpy(mProcessName, "<unknown>", sizeof(mProcessName));
} else {
// the name is newline terminated, so erase the newline
mProcessName[len - 1] = 0;
}
close(fd);
}
/* 加载硬解库和软解库 */
addVendorPlugin();
addPlugin(new SoftOMXPlugin);
}
We focus on addVendorPlugin()
:
void OMXMaster::addVendorPlugin() {
addPlugin("libstagefrighthw.so");
}
Take a look addPlugin
:
void OMXMaster::addPlugin(const char *libname) {
mVendorLibHandle = android_load_sphal_library(libname, RTLD_NOW);
if (mVendorLibHandle == NULL) {
return;
}
typedef OMXPluginBase *(*CreateOMXPluginFunc)();
CreateOMXPluginFunc createOMXPlugin =
(CreateOMXPluginFunc)dlsym(
mVendorLibHandle, "createOMXPlugin");
if (!createOMXPlugin)
createOMXPlugin = (CreateOMXPluginFunc)dlsym(
mVendorLibHandle, "_ZN7android15createOMXPluginEv");
if (createOMXPlugin) {
addPlugin((*createOMXPlugin)());
}
}
Here it will load libstagefrighthw.so
and redirect to the function createOMXPlugin
. Here we need to confirm a question, libstagefrighthw.so
where does the chip platform come from, and how is the corresponding createOMXPlugin
function implemented. I am currently using the MTK chip platform. The library is compiled from a file named by MTK itself. As long as the library name is and libstagefrighthw.so
implements the interface of some OMX standard components, you can load the hard solution library of the chip platform and find the corresponding Source code and functions createOMXPlugin
:
OMXPluginBase *createOMXPlugin() {
return new MSOMXPlugin;
}
Here we will construct the class object of the chip platform itself MSOMXPlugin
:
MSOMXPlugin::MSOMXPlugin()
: mLibHandle(dlopen("libOMX.MStar.so", RTLD_NOW)),
mInit(NULL),
mDeinit(NULL),
mComponentNameEnum(NULL),
mGetHandle(NULL),
mFreeHandle(NULL),
mGetRolesOfComponentHandle(NULL),
mSetupTunnel(NULL),
mTearDownTunnel(NULL) {
ALOGD("MSOMXPlugin::MSOMXPlugin");
if (mLibHandle != NULL) {
ALOGD("Get libOMX.MStar.so");
mInit = (InitFunc)dlsym(mLibHandle, "MS_OMX_Init");
mDeinit = (DeinitFunc)dlsym(mLibHandle, "MS_OMX_DeInit");
mComponentNameEnum =
(ComponentNameEnumFunc)dlsym(mLibHandle, "MS_OMX_ComponentNameEnum");
mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "MS_OMX_GetHandle");
mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "MS_OMX_FreeHandle");
mGetRolesOfComponentHandle =
(GetRolesOfComponentFunc)dlsym(
mLibHandle, "MS_OMX_GetRolesOfComponent");
#ifdef BUILD_GOOGLETV
mSetupTunnel = (SetupTunnelFunc)dlsym(mLibHandle, "MS_OMX_SetupTunnel");
mTearDownTunnel = (SetupTunnelFunc)dlsym(mLibHandle, "MS_OMX_TearDownTunnel");
#endif
CHECK(mInit != NULL);
(*mInit)();
...
}
The function contains a lot of information. First, it will open the dynamic library of the chip platform, then redirect the important function pointers of each OMX component, and finally call the mInit
pointed function for further initialization. Here is the start analysis of the entire OMX service.
3. Summary:
1. The OMX service is a sub-item under the binder service of MediaCodec. When the system service is started, the service of MediaCodec will be loaded. The library of OMX soft solution will definitely be loaded. If the chip platform supports hardware The solution will load the OMX hard solution library;
2. Restart mediaserver
the process to reload the OMX hard solution library, and subsequent application applications for OMX components will be accessed through the OMX client;