【Audio】配置文档(二)media_codec.xml

文章目录

  • 1 内容
  • 2 加载及使用
    • 2.1 文件加载log
    • 2.2 解析文件
    • 2.3 使用
  • 3 小结

1 内容

文件路径:
code:android/device/qcom/msm8996(平台名)或者android/frameworks/av/media/libstagefright/data
设备:/vendor/etc/media_codecs.xml

        <MediaCodec name="OMX.google.amrnb.encoder" type="audio/3gpp">
            <Limit name="channel-count" max="1" />
            <Limit name="sample-rate" ranges="8000" />
            <Limit name="bitrate" range="4750-12200" />
            <Feature name="bitrate-modes" value="CBR" />
        MediaCodec>

定义当前设备所支持的编码器配置。
还有另一款"c2.android.amrnb.encoder"

2 加载及使用

2.1 文件加载log

【Audio】配置文档(二)media_codec.xml_第1张图片
在这里插入图片描述
【Audio】配置文档(二)media_codec.xml_第2张图片

2.2 解析文件

【Audio】配置文档(二)media_codec.xml_第3张图片

关于mediacodec.xml文件的解析,查看log可以发现有多处。

首先,存放media_codec.xml的文件夹有多个,所以会先查找对应的文件夹
然后,获取到了文件路径,对xml文件进行解析

重点是MediaCodecsXmlParser::parseXmlPath函数进行处理的。
最终调用到MediaCodecsXmlParser::Impl::Parser::parseXmlFile函数中,打开并遍历xml文件的节点,将xml文件中的数据存入parser中。

//处理xml文件
status_t MediaCodecsXmlParser::Impl::parseXmlPath(const std::string &path) {
    std::lock_guard<std::mutex> guard(mLock);
    //1. 获取路径
    std::string vendorPath = getVendorXmlPath(path);

    // save state (even though we should always be at toplevel here)
    State::RestorePoint rp = mState.createRestorePoint();
    Parser parser(&mState, vendorPath);
    //2. 解析xml文件
    parser.parseXmlFile();
    mState.restore(rp);

    if (parser.getStatus() != OK) {
        ALOGD("parseXmlPath(%s) failed with %s", vendorPath.c_str(), asString(parser.getStatus()));
    }
    mParsingStatus = combineStatus(mParsingStatus, parser.getStatus());
    return parser.getStatus();
}

//获取文件路径
std::string getVendorXmlPath(const std::string &path) {
    std::string vendorPath;
    std::string result = path;

    if (!strncmp(path.c_str(), "/vendor/etc/media_codecs.xml",
                    strlen("/vendor/etc/media_codecs.xml"))) {
        vendorPath = "/vendor/etc/media_codecs_vendor";
    } else if (!strncmp(path.c_str(), "/vendor/etc/media_codecs_performance.xml",
                    strlen("/vendor/etc/media_codecs_performance.xml"))) {
        vendorPath = "/vendor/etc/media_codecs_performance";
    }
}

//解析xml文件
void MediaCodecsXmlParser::Impl::Parser::parseXmlFile() {
    const char *path = mPath.c_str();
    ALOGD("parsing %s...", path);
    FILE *file = fopen(path, "r");

    mParser = std::shared_ptr<XML_ParserStruct>(
        ::XML_ParserCreate(nullptr),
        [](XML_ParserStruct *parser) { ::XML_ParserFree(parser); });
    LOG_FATAL_IF(!mParser, "XML_MediaCodecsXmlParserCreate() failed.");

    ::XML_SetUserData(mParser.get(), this);
    ::XML_SetElementHandler(mParser.get(), StartElementHandlerWrapper, EndElementHandlerWrapper);

    static constexpr int BUFF_SIZE = 512;

    while (mStatus == OK) {
        void *buff = ::XML_GetBuffer(mParser.get(), BUFF_SIZE);

        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);

        XML_Status status = ::XML_ParseBuffer(mParser.get(), bytes_read, bytes_read == 0);
    }

    mParser.reset();

    fclose(file);
}

根据代码查看,发现是OmxStore::OmxStore调用的。

OmxStore::OmxStore(){
    MediaCodecsXmlParser parser;
    parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs);
    if (profilingResultsXmlPath != nullptr) {
        parser.parseXmlPath(profilingResultsXmlPath);
    }
    mParsingStatus = toStatus(parser.getParsingStatus());
}

怀疑:
mediacodec创建的时候会执行MediaCodecList::getInstance,目前怀疑MediaCodecList应该会和omxstore有关联,代码后续继续追。

status_t MediaCodec::init(const AString &name, bool nameIsType) {
		const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
        for (const AString &codecName : { name, tmp }) {
            ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
            mCodecInfo = mcl->getCodecInfo(codecIdx);
        }
}

sp<IMediaCodecList> MediaCodecList::getInstance() {
    sRemoteList = getLocalInstance();
}

sp<IMediaCodecList> MediaCodecList::getLocalInstance() {
        MediaCodecList *codecList = new MediaCodecList(GetBuilders());
}

2.3 使用

先看下使用。
经过了mediaprofile的筛选,根据app传下来codec类型,匹配得到两个encoder,最终录制选择OMX.google.amrnb.encoder,选择哪个encoder应该是有一个打分机制,后续再追。
【Audio】配置文档(二)media_codec.xml_第4张图片

3 小结

目前只追到了OmxStore初始化的时候加载media_codec.xml文件,并存放到MediaCodecsXmlParser parser中。
根据log来看,实际使用的时候是再mediacodeclist中寻找匹配的encoder,所以怀疑最终omxstore会和mediacodeclist相关联,这个后续再追。

你可能感兴趣的:(audio配置文档,android)