Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4b4cd11 authored by Ronghua Wu's avatar Ronghua Wu Committed by Android (Google) Code Review
Browse files

Merge "libstagefright: run codec profiling in worker thread." into mnc-dev

parents a31d2372 a09152c6
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -55,7 +55,10 @@ struct MediaCodecList : public BnMediaCodecList {
    // to be used by MediaPlayerService alone
    static sp<IMediaCodecList> getLocalInstance();

    // only to be used in getLocalInstance
    // only to be used by getLocalInstance
    static void *profilerThreadWrapper(void * /*arg*/);

    // only to be used by MediaPlayerService
    void parseTopLevelXMLFile(const char *path, bool ignore_errors = false);

private:
+56 −46
Original line number Diff line number Diff line
@@ -46,8 +46,6 @@ const char *kMaxEncoderInputBuffers = "max-video-encoder-input-buffers";

static Mutex sInitMutex;

static MediaCodecList *gCodecList = NULL;

static bool parseBoolean(const char *s) {
    if (!strcasecmp(s, "true") || !strcasecmp(s, "yes") || !strcasecmp(s, "y")) {
        return true;
@@ -57,65 +55,77 @@ static bool parseBoolean(const char *s) {
    return *s != '\0' && *end == '\0' && res > 0;
}

static bool isProfilingNeeded() {
    bool profilingNeeded = true;
    FILE *resultsFile = fopen(kProfilingResults, "r");
    if (resultsFile) {
        AString currentVersion = getProfilingVersionString();
        size_t currentVersionSize = currentVersion.size();
        char *versionString = new char[currentVersionSize + 1];
        fgets(versionString, currentVersionSize + 1, resultsFile);
        if (strcmp(versionString, currentVersion.c_str()) == 0) {
            // profiling result up to date
            profilingNeeded = false;
        }
        fclose(resultsFile);
        delete[] versionString;
    }
    return profilingNeeded;
}

// static
sp<IMediaCodecList> MediaCodecList::sCodecList;

// static
sp<IMediaCodecList> MediaCodecList::getLocalInstance() {
    bool profilingNeeded = false;
void *MediaCodecList::profilerThreadWrapper(void * /*arg*/) {
    ALOGV("Enter profilerThreadWrapper.");
    MediaCodecList *codecList = new MediaCodecList();
    if (codecList->initCheck() != OK) {
        ALOGW("Failed to create a new MediaCodecList, skipping codec profiling.");
        delete codecList;
        return NULL;
    }

    Vector<sp<MediaCodecInfo>> infos;
    for (size_t i = 0; i < codecList->countCodecs(); ++i) {
        infos.push_back(codecList->getCodecInfo(i));
    }
    ALOGV("Codec profiling started.");
    profileCodecs(infos);
    ALOGV("Codec profiling completed.");
    codecList->parseTopLevelXMLFile(kProfilingResults, true /* ignore_errors */);

    {
        Mutex::Autolock autoLock(sInitMutex);

        if (gCodecList == NULL) {
            gCodecList = new MediaCodecList;
            if (gCodecList->initCheck() == OK) {
                sCodecList = gCodecList;

                FILE *resultsFile = fopen(kProfilingResults, "r");
                if (resultsFile) {
                    AString currentVersion = getProfilingVersionString();
                    size_t currentVersionSize = currentVersion.size();
                    char *versionString = new char[currentVersionSize];
                    fgets(versionString, currentVersionSize, resultsFile);
                    if (strncmp(versionString, currentVersion.c_str(), currentVersionSize) != 0) {
                        // profiling result out of date
                        profilingNeeded = true;
        sCodecList = codecList;
    }
                    fclose(resultsFile);
                    delete[] versionString;
                } else {
                    // profiling results doesn't existed
                    profilingNeeded = true;
    return NULL;
}

                if (profilingNeeded) {
                    for (size_t i = 0; i < gCodecList->countCodecs(); ++i) {
                        infos.push_back(gCodecList->getCodecInfo(i));
// static
sp<IMediaCodecList> MediaCodecList::getLocalInstance() {
    Mutex::Autolock autoLock(sInitMutex);

    if (sCodecList == NULL) {
        MediaCodecList *codecList = new MediaCodecList;
        if (codecList->initCheck() == OK) {
            sCodecList = codecList;

            if (isProfilingNeeded()) {
                ALOGV("Codec profiling needed, will be run in separated thread.");
                pthread_t profiler;
                if (pthread_create(&profiler, NULL, profilerThreadWrapper, NULL) != 0) {
                    ALOGW("Failed to create thread for codec profiling.");
                }
            }
        } else {
            // failure to initialize may be temporary. retry on next call.
                delete gCodecList;
                gCodecList = NULL;
            }
            delete codecList;
        }
    }

    if (profilingNeeded) {
        profileCodecs(infos);
    }

    {
        Mutex::Autolock autoLock(sInitMutex);
        if (profilingNeeded) {
            gCodecList->parseTopLevelXMLFile(kProfilingResults, true /* ignore_errors */);
        }

    return sCodecList;
}
}

static Mutex sRemoteInitMutex;