Android 13 - Media框架(24)- MediaCodecList

这一节我们要了解 MediaCodecList 中的信息是如何加载的,以及这些信息是如何使用到的。

cpp 复制代码
// 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;
}
相关推荐
黄林晴6 小时前
重磅更新!Kotlin协程1.11.0 发布,Flow/StateFlow 新 API 全面升级
android·kotlin
网安Ruler7 小时前
安卓逆向入门到入狱学习2
android·学习
Jomurphys7 小时前
Compose 组件 - 流式布局 FlowLayout(FlowColumn、FlowRow)
android·compose
帅次7 小时前
Navigation Compose:NavHost、NavController 与参数
android·kotlin·gradle·android jetpack·compose
小何开发7 小时前
ffmpeg 安装与使用: 将视频分片与组装
ffmpeg·音视频
EasyDSS7 小时前
私有化视频会议系统/智能会议管理系统EasyDSS打造全场景音视频协作新生态
音视频
淘小白_TXB21967 小时前
微博图文视频批量采集软件用户手册
音视频
程序员陆业聪7 小时前
架构哲学与工程化:从开发体验到CI/CD的全维度对比|跨平台框架深度对决(三)
android
程序员陆业聪7 小时前
Android网络全链路拆解:一次HTTP请求背后的性能陷阱
android
程序员陆业聪7 小时前
渲染引擎与性能拆解:自绘vs原生渲染vs Bridge的终极对决|跨平台框架深度对决②
android