OMX service startup and loading

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.rcscript 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.cppcompiled. 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.soand redirect to the function createOMXPlugin. Here we need to confirm a question, libstagefrighthw.sowhere does the chip platform come from, and how is the corresponding createOMXPluginfunction 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.soimplements 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 mInitpointed 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 mediaserverthe process to reload the OMX hard solution library, and subsequent application applications for OMX components will be accessed through the OMX client;

insert image description here

Guess you like

Origin blog.csdn.net/achina2011jy/article/details/124630440