承接上一章节分析: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