一、总体架构
以 aac 解码 process 为例App (MediaCodec)->Framework (CCodec)->Binder (HIDL/AIDL)->mediaswcodec 进程->SimpleC2Component (基类循环)->C2SoftAacDec::process
Android 调用到libcodec2_soft_aacdec.so里的process的关键步骤是:
- 加载库:系统启动
mediaswcodec服务进程,根据配置加载libcodec2_soft_aacdec.so并创建C2SoftAacDec对象。 - 基类驱动:该对象启动时会创建一个后台线程(由基类
SimpleC2Component管理)。 - 循环处理:后台线程运行
processQueue()循环,等待输入数据。 - 虚函数调用:一旦收到数据,基类直接调用
process()虚函数。 - 具体执行:执行流进入
C2SoftAacDec::process,完成 AAC 解码。
二、函数分析
1. SimpleC2Component::processQueue
1.1 函数功能
- 队列管理:从工作队列中取出任务,处理flush和排空操作
- 资源初始化:首次使用时初始化输出块池
- 配置更新:处理工作项中的配置参数更新
- 任务处理:调用具体的process函数处理音视频数据
- 结果返回:根据处理状态立即返回结果或将工作放入挂起队列
- 错误处理:处理各种异常情况并通知监听器
1.2 函数注释
boolSimpleC2Component::processQueue(){// 声明变量:工作项、代际、排空模式等std::unique_ptr<C2Work>work;uint64_tgeneration;int32_tdrainMode;boolisFlushPending=false;boolhasQueuedWork=false;{// 获取工作队列的锁Mutexed<WorkQueue>::Lockedqueue(mWorkQueue);// 检查队列是否为空if(queue->empty()){returnfalse;// 队列为空,返回false表示没有工作需要处理}// 获取当前队列的代际信息(用于检测flush操作)generation=queue->generation();// 获取排空模式drainMode=queue->drainMode();// 检查是否有待处理的flush操作isFlushPending=queue->popPendingFlush();// 从队列前端取出一个工作项work=queue->pop_front();// 检查队列是否还有剩余工作hasQueuedWork=!queue->empty();}// 如果有待处理的flush操作,执行flushif(isFlushPending){ALOGV("processing pending flush");// 调用flush处理函数c2_status_t err=onFlush_sm();if(err!=C2_OK){ALOGD("flush err: %d",err);// TODO: 错误处理}}// 如果输出块池尚未初始化,进行初始化if(!mOutputBlockPool){c2_status_t err=[this]{// 查询输出格式配置C2StreamBufferTypeSetting::outputoutputFormat(0u);std::vector<std::unique_ptr<C2Param>>para