当前位置: 代码迷 >> 综合 >> 【Audio】配置文档(二)media_codec.xml
  详细解决方案

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

热度:71   发布时间:2023-12-05 20:42:48.0

文章目录

  • 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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 解析文件

在这里插入图片描述

关于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应该是有一个打分机制,后续再追。
在这里插入图片描述

3 小结

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

  相关解决方案