资讯详情

NuPlayer的解码模块

介绍了解码 ,这是一个基类。真正的解码器逻辑是 NuPlayerDecoder.cpp它在文件中继承自己NuPlayerDecoderBase类。先看实例化解码器, 其位于

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayer.cpp

中:

 status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) { 
        ///音频解码器可以清除tear down。若仍在关闭 //流程,无需创建新的音频解码器。     if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) { 
                return OK;     }      sp<AMessage> format = mSource->getFormat(audio);      if (format == NULL) { 
                return -EWOULDBLOCK;     }      format->setInt32("priority", 0 /* realtime */);      if (!audio) { 
                AString mime;         CHECK(format->findString("mime", &mime));          sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);         if (mCCDecoder == NULL) { 
                    mCCDecoder = new CCDecoder(ccNotify);
        }

        if (mSourceFlags & Source::FLAG_SECURE) { 
       
            format->setInt32("secure", true);
        }

        if (mSourceFlags & Source::FLAG_PROTECTED) { 
       
            format->setInt32("protected", true);
        }

        float rate = getFrameRate();
        if (rate > 0) { 
       
           format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
        }
    }

    if (audio) { 
       
        sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
        ++mAudioDecoderGeneration;
        notify->setInt32("generation", mAudioDecoderGeneration);

        determineAudioModeChange();
        if (mOffloadAudio) { 
       
            const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
            format->setInt32("has-video", hasVideo);
            *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
        } else { 
       
            *decoder = new Decoder(notify, mSource, mPID, mRenderer);
        }
    } else { 
       
        sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
        ++mVideoDecoderGeneration;
        notify->setInt32("generation", mVideoDecoderGeneration);

        *decoder = new Decoder(
                notify, mSource, mPID, mRenderer, mSurface, mCCDecoder);

        // enable FRC if high-quality AV sync is requested, even if not
        // directly queuing to display, as this will even improve textureview
        // playback.
        { 
       
            char value[PROPERTY_VALUE_MAX];
            if (property_get("persist.sys.media.avsync", value, NULL) &&
                    (!strcmp("1", value) || !strcasecmp("true", value))) { 
       
                format->setInt32("auto-frc", 1);
            }
        }
    }
    (*decoder)->init();
    (*decoder)->configure(format);

    // allocate buffers to decrypt widevine source buffers
        Vector<sp<ABuffer> > inputBufs;
        CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);

        Vector<MediaBuffer *> mediaBufs;
        for (size_t i = 0; i < inputBufs.size(); i++) { 
       
            const sp<ABuffer> &buffer = inputBufs[i];
            MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
            mediaBufs.push(mbuf);
        }

        status_t err = mSource->setBuffers(audio, mediaBufs);
        if (err != OK) { 
       
            for (size_t i = 0; i < mediaBufs.size(); ++i) { 
       
                mediaBufs[i]->release();
            }
            mediaBufs.clear();
            ALOGE("Secure source didn't support secure mediaBufs.");
            return err;
        }
    }
    return OK;
}

上面的代码构造了 Decoder对象,且进行了初始化和构建解码器。 由于 NuPlayerDecoder 继承自 NuPlayerDecoderBase 类,所以 Configure 函数会执行 NuPlayerDecoder 的 Configure 函数,最终回调 onConfigure 函数,其位于 frameworks\av\media\ libmediaplayerservice\nuplayer\NuPIayerDecoder.cpp 中, 代码如下:

void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 
       
    CHECK(mCodec == NULL);

    mFormatChangePending = false;
    mTimeChangePending = false;

    ++mBufferGeneration;

    AString mime;
    CHECK(format->findString("mime", &mime));

    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());

    mComponentName = mime;
    mComponentName.append(" decoder");
    ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());

    mCodec = MediaCodec::CreateByType(
            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid);
    int32_t secure = 0;
    if (format->findInt32("secure", &secure) && secure != 0) { 
       
        if (mCodec != NULL) { 
       
            mCodec->getName(&mComponentName);
            mComponentName.append(".secure");
            mCodec->release();
            ALOGI("[%s] creating", mComponentName.c_str());
            mCodec = MediaCodec::CreateByComponentName(
                    mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid);
        }
    }
    if (mCodec == NULL) { 
       
        ALOGE("Failed to create %s%s decoder",
                (secure ? "secure " : ""), mime.c_str());
        handleError(UNKNOWN_ERROR);
        return;
    }
    mIsSecure = secure;
    mCodec->getName(&mComponentName);

    status_t err;
    if (mSurface != NULL) { 
       
       // MediaCodec将重新连接时断开与surface的连接
        err = native_window_api_disconnect(
                mSurface.get(), NATIVE_WINDOW_API_MEDIA);
//我们认为这是一个警告,因为这是一个准备步骤。
// Codec将尝试连接到表面
//任何错误信号都会发生。
        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
    }
    err = mCodec->configure(
           format, mSurface, NULL /* crypto */, 0 /* flags */);
    if (err != OK) { 
       
        ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
        mCodec->release();
        mCodec.clear();
        handleError(err);
        return;
    }
    rememberCodecSpecificData(format);

   // the following should work in configured state
    CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
    CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));

    mStats->setString("mime", mime.c_str());
   mStats->setString("component-name", mComponentName.c_str());

    if (!mIsAudio) { 
       
        int32_t width, height;
        if (mOutputFormat->findInt32("width", &width)
                && mOutputFormat->findInt32("height", &height)) { 
       
            mStats->setInt32("width", width);
           mStats->setInt32("height", height);
        }
    }

    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
    mCodec->setCallback(reply);

    err = mCodec->start();
    if (err != OK) { 
       
        ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
        mCodec->release();
        mCodec.clear();
       handleError(err);
        return;
    }

    releaseAndResetMediaBuffers();

    mPaused = false;
    mResumePending = false;
}

从onConfigure函数可以看到,NuPlayerDecoder引入了 MediaCodec作为解码器。通过 CreateByType/CreateByComponentName 创建了 Codec 对象。

标签: 47frc连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台