Android 编解码

在AwesomePlayer中会调用

mVideoSource= OMXCodec::Create(

mClient.interface(),mVideoTrack->getFormat(),

false, // createEncoder

mVideoTrack,

NULL,flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);

来获得videoSource,在这个函数中,会首先查找当前的在kKeyMIMEType并存入mime字串中,然后调用findMatchingCodecs,在这个函数中会判断是Decoder还是Encoder,以Decoder为例,会在kDecoderInfo这个结构体中查找与mime匹配的字串,如果成功获得componentName,则加入到matchingCodecs中。另外,这里要注意的是,如果flags中定义了kPreferSoftwareCodecs,则会重新排序,将软件编解码模块加到前面。

matchingCodecs->clear();

for (int index = 0;; ++index) {
const char *componentName;

if (createEncoder) {
    componentName = GetCodec(
            kEncoderInfo,
            sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
            mime, index);
} else {
    componentName = GetCodec(
            kDecoderInfo,
            sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
            mime, index);
}

if (!componentName) {
    break;
}

if (matchComponentName && strcmp(componentName, matchComponentName)) {
    continue;
}

if (((flags & kSoftwareCodecsOnly) &&   IsSoftwareCodec(componentName)) ||
    ((flags & kHardwareCodecsOnly) &&  !IsSoftwareCodec(componentName)) ||
    (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {

    matchingCodecs->push(String8(componentName));
}
}

if (flags & kPreferSoftwareCodecs) {
matchingCodecs->sort(CompareSoftwareCodecsFirst);
}

然后,对matchingCodecs中的每个编解码器,按照先后顺序,先看是否是软件编解码器,如果是的,则直接返回软件编解码器即可,如果是硬件的,则需先分配结点,调用allocateNode函数,这个是IOMX类的一个纯虚函数。这里涉及到binder机制,不是很清楚,大致描述下。首先会调用Client端的(IOMX.cpp)BnOMX的allocateNode函数,这里会调用remote的tranact(请求发送并要求返回调用结果)函数来传递ALLOCATE_NODE消息,这就会调用Server端的(OMX.cpp)BpOMX的allocateNode函数,继续会调用到mMaster(OMXMaster.cpp)的makeComponentInstance函数,这边关键是追传进去的name参数。接着会调用到plugin的makeComponentInstance函数,这边会先由指定的name生成index,再由index来生成OMXPluginBase类的对象plugin。

   for (size_t i = 0; i < matchingCodecs.size(); ++i) {
        componentName = matchingCodecs[i].string();

        sp<MediaSource> softwareCodec = createEncoder?
            InstantiateSoftwareEncoder(componentName, source, meta):
            InstantiateSoftwareCodec(componentName, source);

        if (softwareCodec != NULL) {
            LOGV("Successfully allocated software codec '%s'", componentName);

            return softwareCodec;
        }

        LOGV("Attempting to allocate OMX node '%s'", componentName);

        uint32_t quirks = getComponentQuirks(componentName, createEncoder);

        if (!createEncoder
                && (quirks & kOutputBuffersAreUnreadable)
                && (flags & kClientNeedsFramebuffer)) {
            if (strncmp(componentName, "OMX.SEC.", 8)) {
                // For OMX.SEC.* decoders we can enable a special mode that
                // gives the client access to the framebuffer contents.

                LOGW("Component '%s' does not give the client access to "
                     "the framebuffer contents. Skipping.",
                     componentName);

                continue;
            }
        }

        status_t err = omx->allocateNode(componentName, observer, &node);
        if (err == OK) {
            LOGV("Successfully allocated OMX node '%s'", componentName);

            sp<OMXCodec> codec = new OMXCodec(
                    omx, node, quirks,
                    createEncoder, mime, componentName,
                    source, nativeWindow);

            observer->setCodec(codec);

            err = codec->configureCodec(meta, flags);

            if (err == OK) {
                return codec;
            }

            LOGV("Failed to configure codec '%s'", componentName);
        }
   }


new OMXCodec是根据获取的结点来创建编解码器的,对于后面的observer->setCodec(codec)及codec->configureCodec(meta, flags)只是对编加码器的一些配置工作,没有细看。

转载请注明出处:http://blog.csdn.net/qq69696698

你可能感兴趣的:(android,server,String,null,Access,Codec)