Android MediaPlayer整体架构源码分析 -【MediaCodec编解码器插件模块化注册和创建处理流程】【Part 7】【01】

本文深入分析了Android MediaCodec在初始化过程中的源码,包括PostAndAwaitResponse消息发送与响应、kWhatInit事件处理、错误处理机制、状态机转换、Surface连接与断开以及编解码器组件的创建流程。重点探讨了Binder通信、ALooper机制、错误回调、状态管理以及与OMX服务的交互等关键环节。
摘要由CSDN通过智能技术生成

承接上一章节分析:Android MediaPlayer整体架构源码分析 -【MediaCodec编解码器插件模块化注册和创建处理流程】【Part 6】
本系列文章分析的安卓源码版本:【Android 10.0 版本】

推荐涉及到的知识点:
Binder机制实现原理:Android C++底层Binder通信机制原理分析总结【通俗易懂】
ALooper机制实现原理:Android native层媒体通信架构AHandler/ALooper机制实现源码分析
Binder异常关闭监听:Android native层DeathRecipient对关联进程(如相关Service服务进程)异常关闭通知事件的监听实现源码分析

【本章节小节序号将重新开始】
PostAndAwaitResponse(msg, &response)实现分析:
立即发送AMessage消息事件【kWhatInit】并等待应答信息。关于ALooper实现机制请查看文章开头推荐文章。

// [frameworks/av/media/libstagefright/MediaCodec.cpp]
// static
status_t MediaCodec::PostAndAwaitResponse(
        const sp<AMessage> &msg, sp<AMessage> *response) {
   
    // 等待应答处理结果
    status_t err = msg->postAndAwaitResponse(response);
	// 失败直接返回
    if (err != OK) {
   
        return err;
    }
    // 成功时

    // 获取应答处理结果的错误码
    if (!(*response)->findInt32("err", &err)) {
   
    	// 若获取该错误码失败,则默认处理成功OK
        err = OK;
    }

	// 返回应答处理结果的错误码
    return err;
}

【kWhatInit】 事件消息处理:

// [frameworks/av/media/libstagefright/MediaCodec.cpp]
void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
   
    switch (msg->what()) {
   
        case kWhatInit:
        {
   
            // 获取应答消息对象
            sp<AReplyToken> replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

			// 检查状态必须为UNINITIALIZED才处理,否则应答无效操作错误码
            if (mState != UNINITIALIZED) {
   
            	// 见第1小节分析
                PostReplyWithError(replyID, INVALID_OPERATION);
                break;
            }

            // 缓存该应答消息对象,后续流程中会使用
            mReplyID = replyID;
            // 设置状态为正在初始化中 INITIALIZING
            // 见第2小节分析
            setState(INITIALIZING);

			// 获取参数值
            sp<RefBase> codecInfo;
            CHECK(msg->findObject("codecInfo", &codecInfo));
            AString name;
            CHECK(msg->findString("name", &name));
            int32_t nameIsType;
            msg->findInt32("nameIsType", &nameIsType);

            // 封装成新的(编解码器信息)格式数据消息对象
            sp<AMessage> format = new AMessage;
            format->setObject("codecInfo", codecInfo);
            format->setString("componentName", name);
            format->setInt32("nameIsType", nameIsType);

            // 执行初始化分配组件处理
            // 见第3小节分析
            mCodec->initiateAllocateComponent(format);
            break;
        }
    }
}

1、PostReplyWithError(replyID, INVALID_OPERATION)实现分析:

// [frameworks/av/media/libstagefright/MediaCodec.cpp]
void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
   
	// 此处将最终错误码做了一个调整,即若此时前面分析过的资源管理服务等被释放了,那么将会返回DEAD_OBJECT错误码
    int32_t finalErr = err;
    if (mReleasedByResourceManager) {
   
        // override the err code if MediaCodec has been released by ResourceManager.
        finalErr = DEAD_OBJECT;
    }

    sp<AMessage> response = new AMessage;
    response->setInt32("err", finalErr);
    response->postReply(replyID);
}

2、setState(INITIALIZING)实现分析:

// [frameworks/av/media/libstagefright/MediaCodec.cpp]
void MediaCodec::setState(State newState) {
   
    if (newState == INITIALIZED || newState == UNINITIALIZED) {
   
    	// 新状态为已初始化或未初始化时,初始化做一些工作
        delete mSoftRenderer;
        mSoftRenderer = NULL;

        if ( mCrypto != NULL ) {
   
            ALOGV("setState: ~mCrypto: %p (%d)",
                    mCrypto.get(), (mCrypto != NULL ? mCrypto->getStrongCount() : 0));
        }
        mCrypto.clear();
        mDescrambler.clear();
        // 处理设置Surface为null
        // 见2.1小节分析
        handleSetSurface(NULL);

        mInputFormat.clear();
        mOutputFormat.clear();
        mFlags &= ~kFlagOutputFormatChanged;
        mFlags &= ~kFlagOutputBuffersChanged;
        mFlags &= ~kFlagStickyError;
        mFlags &= ~kFlagIsEncoder;
        mFlags &= ~kFlagIsAsync;
        mStickyError = OK;

        mActivityNotify.clear();
        mCallback.clear();
    }

	// 备注:目前暂时先不分析UNINITIALIZED该状态的后续处理流程,会在后续涉及到的流程中分析到
    if (newState == UNINITIALIZED) {
   
        // return any straggling buffers, e.g. if we got here on an error
        // 返回任何散乱缓冲区buffer,也就是发生错误时的处理
        // 见2.2小节分析
        returnBuffersToCodec();

        // The component is gone, mediaserver's probably back up already
        // but should definitely be back up should we try to instantiate
        // another component.. and the cycle continues.
        mFlags &= ~kFlagSawMediaServerDie;
    }

	// 缓存当前状态
    mState = newState;

    if (mBatteryChecker != nullptr) {
   
    	// 设置(当前编解码器)是否正在执行标志
    	// 见2.3小节分析
        mBatteryChecker
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值