/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaCodecList"
#include <utils/Log.h>

#include <binder/IServiceManager.h>

#include <media/IMediaCodecList.h>
#include <media/IMediaPlayerService.h>
#include <media/MediaCodecInfo.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
#include <media/stagefright/CCodec.h>
#include <media/stagefright/Codec2InfoBuilder.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaCodecListOverrides.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/OmxInfoBuilder.h>
#include <media/stagefright/PersistentSurface.h>

#include <sys/stat.h>
#include <utils/threads.h>

#include <cutils/properties.h>

#include <algorithm>
#include <regex>

namespace android {

namespace {

Mutex sInitMutex;

Mutex sRemoteInitMutex;

constexpr const char* kProfilingResults =
        MediaCodecsXmlParser::defaultProfilingResultsXmlPath;

bool isProfilingNeeded() {
    int8_t value = property_get_bool("debug.stagefright.profilecodec", 0);
    if (value == 0) {
        return false;
    }

    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;
}

OmxInfoBuilder sOmxInfoBuilder{true /* allowSurfaceEncoders */};
OmxInfoBuilder sOmxNoSurfaceEncoderInfoBuilder{false /* allowSurfaceEncoders */};

Mutex sCodec2InfoBuilderMutex;
std::unique_ptr<MediaCodecListBuilderBase> sCodec2InfoBuilder;

MediaCodecListBuilderBase *GetCodec2InfoBuilder() {
    Mutex::Autolock _l(sCodec2InfoBuilderMutex);
    if (!sCodec2InfoBuilder) {
        sCodec2InfoBuilder.reset(new Codec2InfoBuilder);
    }
    return sCodec2InfoBuilder.get();
}

std::vector<MediaCodecListBuilderBase *> GetBuilders() {
    std::vector<MediaCodecListBuilderBase *> builders;
    // if plugin provides the input surface, we cannot use OMX video encoders.
    // In this case, rely on plugin to provide list of OMX codecs that are usable.
    sp<PersistentSurface> surfaceTest = CCodec::CreateInputSurface();
    if (surfaceTest == nullptr) {
        ALOGD("Allowing all OMX codecs");
        builders.push_back(&sOmxInfoBuilder);
    } else {
        ALOGD("Allowing only non-surface-encoder OMX codecs");
        builders.push_back(&sOmxNoSurfaceEncoderInfoBuilder);
    }
    builders.push_back(GetCodec2InfoBuilder());
    return builders;
}

}  // unnamed namespace

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

// static
void *MediaCodecList::profilerThreadWrapper(void * /*arg*/) {
    ALOGV("Enter profilerThreadWrapper.");
    remove(kProfilingResults);  // remove previous result so that it won't be loaded to
                                // the new MediaCodecList
    sp<MediaCodecList> codecList(new MediaCodecList(GetBuilders()));
    if (codecList->initCheck() != OK) {
        ALOGW("Failed to create a new MediaCodecList, skipping codec profiling.");
        return nullptr;
    }

    const auto& infos = codecList->mCodecInfos;
    ALOGV("Codec profiling started.");
    profileCodecs(infos, kProfilingResults);
    ALOGV("Codec profiling completed.");
    codecList = new MediaCodecList(GetBuilders());
    if (codecList->initCheck() != OK) {
        ALOGW("Failed to parse profiling results.");
        return nullptr;
    }

    {
        Mutex::Autolock autoLock(sInitMutex);
        sCodecList = codecList;
    }
    return nullptr;
}

// static
sp<IMediaCodecList> MediaCodecList::getLocalInstance() {
    Mutex::Autolock autoLock(sInitMutex);

    if (sCodecList == nullptr) {
        MediaCodecList *codecList = new MediaCodecList(GetBuilders());
        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, nullptr, profilerThreadWrapper, nullptr) != 0) {
                    ALOGW("Failed to create thread for codec profiling.");
                }
            }
        } else {
            // failure to initialize may be temporary. retry on next call.
            delete codecList;
        }
    }

    return sCodecList;
}

sp<IMediaCodecList> MediaCodecList::sRemoteList;

sp<MediaCodecList::BinderDeathObserver> MediaCodecList::sBinderDeathObserver;
sp<IBinder> MediaCodecList::sMediaPlayer;  // kept since linked to death

void MediaCodecList::BinderDeathObserver::binderDied(const wp<IBinder> &who __unused) {
    Mutex::Autolock _l(sRemoteInitMutex);
    sRemoteList.clear();
    sBinderDeathObserver.clear();
}

// static
sp<IMediaCodecList> MediaCodecList::getInstance() {
    Mutex::Autolock _l(sRemoteInitMutex);
    if (sRemoteList == nullptr) {
        sMediaPlayer = defaultServiceManager()->getService(String16("media.player"));
        sp<IMediaPlayerService> service =
            interface_cast<IMediaPlayerService>(sMediaPlayer);
        if (service.get() != nullptr) {
            sRemoteList = service->getCodecList();
            if (sRemoteList != nullptr) {
                sBinderDeathObserver = new BinderDeathObserver();
                sMediaPlayer->linkToDeath(sBinderDeathObserver.get());
            }
        }
        if (sRemoteList == nullptr) {
            // if failed to get remote list, create local list
            sRemoteList = getLocalInstance();
        }
    }
    return sRemoteList;
}

MediaCodecList::MediaCodecList(std::vector<MediaCodecListBuilderBase*> builders) {
    mGlobalSettings = new AMessage();
    mCodecInfos.clear();
    MediaCodecListWriter writer;
    for (MediaCodecListBuilderBase *builder : builders) {
        if (builder == nullptr) {
            ALOGD("ignored a null builder");
            continue;
        }
        auto currentCheck = builder->buildMediaCodecList(&writer);
        if (currentCheck != OK) {
            ALOGD("ignored failed builder");
            continue;
        } else {
            mInitCheck = currentCheck;
        }
    }
    writer.writeGlobalSettings(mGlobalSettings);
    writer.writeCodecInfos(&mCodecInfos);
    std::stable_sort(
            mCodecInfos.begin(),
            mCodecInfos.end(),
            [](const sp<MediaCodecInfo> &info1, const sp<MediaCodecInfo> &info2) {
                // null is lowest
                return info1 == nullptr
                        || (info2 != nullptr && info1->getRank() < info2->getRank());
            });

    // remove duplicate entries
    bool dedupe = property_get_bool("debug.stagefright.dedupe-codecs", true);
    if (dedupe) {
        std::set<std::string> codecsSeen;
        for (auto it = mCodecInfos.begin(); it != mCodecInfos.end(); ) {
            std::string codecName = (*it)->getCodecName();
            if (codecsSeen.count(codecName) == 0) {
                codecsSeen.emplace(codecName);
                it++;
            } else {
                it = mCodecInfos.erase(it);
            }
        }
    }
}

MediaCodecList::~MediaCodecList() {
}

status_t MediaCodecList::initCheck() const {
    return mInitCheck;
}

// legacy method for non-advanced codecs
ssize_t MediaCodecList::findCodecByType(
        const char *type, bool encoder, size_t startIndex) const {
    static const char *advancedFeatures[] = {
        "feature-secure-playback",
        "feature-tunneled-playback",
    };

    size_t numCodecInfos = mCodecInfos.size();
    for (; startIndex < numCodecInfos; ++startIndex) {
        const MediaCodecInfo &info = *mCodecInfos[startIndex];

        if (info.isEncoder() != encoder) {
            continue;
        }
        sp<MediaCodecInfo::Capabilities> capabilities = info.getCapabilitiesFor(type);
        if (capabilities == nullptr) {
            continue;
        }
        const sp<AMessage> &details = capabilities->getDetails();

        int32_t required;
        bool isAdvanced = false;
        for (size_t ix = 0; ix < ARRAY_SIZE(advancedFeatures); ix++) {
            if (details->findInt32(advancedFeatures[ix], &required) &&
                    required != 0) {
                isAdvanced = true;
                break;
            }
        }

        if (!isAdvanced) {
            return startIndex;
        }
    }

    return -ENOENT;
}

ssize_t MediaCodecList::findCodecByName(const char *name) const {
    Vector<AString> aliases;
    for (size_t i = 0; i < mCodecInfos.size(); ++i) {
        if (strcmp(mCodecInfos[i]->getCodecName(), name) == 0) {
            return i;
        }
        mCodecInfos[i]->getAliases(&aliases);
        for (const AString &alias : aliases) {
            if (alias == name) {
                return i;
            }
        }
    }

    return -ENOENT;
}

size_t MediaCodecList::countCodecs() const {
    return mCodecInfos.size();
}

const sp<AMessage> MediaCodecList::getGlobalSettings() const {
    return mGlobalSettings;
}

//static
bool MediaCodecList::isSoftwareCodec(const AString &componentName) {
    return componentName.startsWithIgnoreCase("OMX.google.")
            || componentName.startsWithIgnoreCase("c2.android.")
            || (!componentName.startsWithIgnoreCase("OMX.")
                    && !componentName.startsWithIgnoreCase("c2."));
}

static int compareSoftwareCodecsFirst(const AString *name1, const AString *name2) {
    // sort order 1: software codecs are first (lower)
    bool isSoftwareCodec1 = MediaCodecList::isSoftwareCodec(*name1);
    bool isSoftwareCodec2 = MediaCodecList::isSoftwareCodec(*name2);
    if (isSoftwareCodec1 != isSoftwareCodec2) {
        return isSoftwareCodec2 - isSoftwareCodec1;
    }

    // sort order 2: Codec 2.0 codecs are first (lower)
    bool isC2_1 = name1->startsWithIgnoreCase("c2.");
    bool isC2_2 = name2->startsWithIgnoreCase("c2.");
    if (isC2_1 != isC2_2) {
        return isC2_2 - isC2_1;
    }

    // sort order 3: OMX codecs are first (lower)
    bool isOMX1 = name1->startsWithIgnoreCase("OMX.");
    bool isOMX2 = name2->startsWithIgnoreCase("OMX.");
    return isOMX2 - isOMX1;
}

//static
void MediaCodecList::findMatchingCodecs(
        const char *mime, bool encoder, uint32_t flags,
        Vector<AString> *matches) {
    sp<AMessage> format;        // initializes as clear/null
    findMatchingCodecs(mime, encoder, flags, format, matches);
}

//static
void MediaCodecList::findMatchingCodecs(
        const char *mime, bool encoder, uint32_t flags, const sp<AMessage> &format,
        Vector<AString> *matches) {
    matches->clear();

    const sp<IMediaCodecList> list = getInstance();
    if (list == nullptr) {
        return;
    }

    size_t index = 0;
    for (;;) {
        ssize_t matchIndex =
            list->findCodecByType(mime, encoder, index);

        if (matchIndex < 0) {
            break;
        }

        index = matchIndex + 1;

        const sp<MediaCodecInfo> info = list->getCodecInfo(matchIndex);
        CHECK(info != nullptr);

        AString componentName = info->getCodecName();

        if (!codecHandlesFormat(mime, info, format)) {
            ALOGV("skipping codec '%s' which doesn't satisfy format %s",
                  componentName.c_str(), format->debugString(2).c_str());
            continue;
        }

        if ((flags & kHardwareCodecsOnly) && isSoftwareCodec(componentName)) {
            ALOGV("skipping SW codec '%s'", componentName.c_str());
            continue;
        }

        matches->push(componentName);
        ALOGV("matching '%s'", componentName.c_str());
    }

    if (flags & kPreferSoftwareCodecs ||
            property_get_bool("debug.stagefright.swcodec", false)) {
        matches->sort(compareSoftwareCodecsFirst);
    }

    // if we did NOT find anything maybe it's because of a profile mismatch.
    // let's recurse after trimming the profile from the format to see if that yields
    // a suitable codec.
    //
    int profile = -1;
    if (matches->empty() && format != nullptr && format->findInt32(KEY_PROFILE, &profile)) {
        ALOGV("no matching codec found, retrying without profile");
        sp<AMessage> formatNoProfile = format->dup();
        formatNoProfile->removeEntryByName(KEY_PROFILE);
        findMatchingCodecs(mime, encoder, flags, formatNoProfile, matches);
    }
}

// static
bool MediaCodecList::codecHandlesFormat(
        const char *mime, const sp<MediaCodecInfo> &info, const sp<AMessage> &format) {

    if (format == nullptr) {
        ALOGD("codecHandlesFormat: no format, so no extra checks");
        return true;
    }

    sp<MediaCodecInfo::Capabilities> capabilities = info->getCapabilitiesFor(mime);

    // ... no capabilities listed means 'handle it all'
    if (capabilities == nullptr) {
        ALOGD("codecHandlesFormat: no capabilities for refinement");
        return true;
    }

    const sp<AMessage> &details = capabilities->getDetails();

    // if parsing the capabilities fails, ignore this particular codec
    // currently video-centric evaluation
    //
    // TODO: like to make it handle the same set of properties from
    // MediaCodecInfo::isFormatSupported()
    // not yet done here are:
    //  profile, level, bitrate, features,

    bool isVideo = false;
    if (strncmp(mime, "video/", 6) == 0) {
        isVideo = true;
    }

    if (isVideo) {
        int width = -1;
        int height = -1;

        if (format->findInt32("height", &height) && format->findInt32("width", &width)) {

            // is it within the supported size range of the codec?
            AString sizeRange;
            AString minSize,maxSize;
            AString minWidth, minHeight;
            AString maxWidth, maxHeight;
            if (!details->findString("size-range", &sizeRange)
                || !splitString(sizeRange, "-", &minSize, &maxSize)) {
                ALOGW("Unable to parse size-range from codec info");
                return false;
            }
            if (!splitString(minSize, "x", &minWidth, &minHeight)) {
                if (!splitString(minSize, "*", &minWidth, &minHeight)) {
                    ALOGW("Unable to parse size-range/min-size from codec info");
                    return false;
                }
            }
            if (!splitString(maxSize, "x", &maxWidth, &maxHeight)) {
                if (!splitString(maxSize, "*", &maxWidth, &maxHeight)) {
                    ALOGW("Unable to fully parse size-range/max-size from codec info");
                    return false;
                }
            }

            // strtol() returns 0 if unable to parse a number, which works for our later tests
            int minW = strtol(minWidth.c_str(), NULL, 10);
            int minH = strtol(minHeight.c_str(), NULL, 10);
            int maxW = strtol(maxWidth.c_str(), NULL, 10);
            int maxH = strtol(maxHeight.c_str(), NULL, 10);

            if (minW == 0 || minH == 0 || maxW == 0 || maxH == 0) {
                ALOGW("Unable to parse values from size-range from codec info");
                return false;
            }

            // finally, comparison time
            if (width < minW || width > maxW || height < minH || height > maxH) {
                ALOGV("format %dx%d outside of allowed %dx%d-%dx%d",
                      width, height, minW, minH, maxW, maxH);
                // at this point, it's a rejection, UNLESS
                // the codec allows swapping width and height
                int32_t swappable;
                if (!details->findInt32("feature-can-swap-width-height", &swappable)
                    || swappable == 0) {
                    return false;
                }
                // NB: deliberate comparison of height vs width limits (and width vs height)
                if (height < minW || height > maxW || width < minH || width > maxH) {
                    return false;
                }
            }

            // @ 'alignment' [e.g. "2x2" which tells us that both dimensions must be even]
            // no alignment == we're ok with anything
            AString alignment, alignWidth, alignHeight;
            if (details->findString("alignment", &alignment)) {
                if (splitString(alignment, "x", &alignWidth, &alignHeight) ||
                    splitString(alignment, "*", &alignWidth, &alignHeight)) {
                    int wAlign = strtol(alignWidth.c_str(), NULL, 10);
                    int hAlign = strtol(alignHeight.c_str(), NULL, 10);
                    // strtol() returns 0 if failing to parse, treat as "no restriction"
                    if (wAlign > 0 && hAlign > 0) {
                         if ((width % wAlign) != 0 || (height % hAlign) != 0) {
                            ALOGV("format dimensions %dx%d not aligned to %dx%d",
                                 width, height, wAlign, hAlign);
                            return false;
                         }
                    }
                }
            }
        }

        int32_t profile = -1;
        if (format->findInt32(KEY_PROFILE, &profile)) {
            Vector<MediaCodecInfo::ProfileLevel> profileLevels;
            capabilities->getSupportedProfileLevels(&profileLevels);
            auto it = profileLevels.begin();
            for (; it != profileLevels.end(); ++it) {
                if (profile != it->mProfile) {
                    continue;
                }
                break;
            }

            if (it == profileLevels.end()) {
                ALOGV("Codec does not support profile %d", profile);
                return false;
            }
        }
    }

    // haven't found a reason to discard this one
    return true;
}

}  // namespace android
