Android 13 - Media框架(18)- CodecBase

从这一节开始我们会回到上层来看ACodec的实现,在这之前我们会先了解ACodec的基类CodecBase。CodecBase.h 中除了声明有自身接口外,还定义有内部类 CodecCallback、BufferCallback,以及另一个基类 BufferChannelBase,接下来我们会一一了解它们的作用。

1、CodecBase

CodecBase 是编解码组件 framework 层应用封装的基类,ACodec 以及后续我们要学习的 CCodec 均继承于 CodecBase。

CodecBase 中声明了一些基本接口,其中一些 ACodec 和 CCodec均有实现,有的一些新的接口只有CCodec需要实现,我们这里先看 ACodec需要实现的部分都由哪些,具体里面是如何实现的我们到 ACodec 章节来学习。

  • setCallback:注册回调函数,用AMessage的形式将消息从CodecBase发送回MediaCodec;
  • getBufferChannel:获取 CodecBase 中的 BufferChannel,bufferchannel我们后续会做了解;
  • initiateAllocateComponent:创建一个编解码组件;
  • initiateConfigureComponent:配置编解码组件;
  • initiateCreateInputSurface:创建一个输入surface;
  • initiateSetInputSurface:设置一个输入surface;
  • initiateStart:启动编解码流程;
  • initiateShutdown:停止编解码流程,分为停止和释放两种情况;
  • onMessageReceived:AHandler 的接口;
  • setSurface:设置输出窗口;
  • signalFlush:发信号执行 flush 方法;
  • signalResume:发信号执行 resume 方法;
  • signalRequestIDRFrame:发信号请求 IDR 帧;
  • signalSetParameters:发信号设置参数;
  • signalEndOfInputStream:发信号 EOS;

2、CodecCallback

接口定义了所有从 CodecBase 发送给 MediaCodec 的事件,这些方法必须是非阻塞的!Callback 需要由 MediaCodec 实现,并且调用 setCallback 将 callback 对象设置给 CodecBase。CodecBase 收到 OMX component 上抛的事件后通过调用 Callback 对应的方法,发送指定事件给 MediaCodec。

  • onEos:通知 MediaCodec 收到 output EOS;
  • onStartCompleted:组件启动完成;
  • onStopCompleted:组件停止完成;
  • onReleaseCompleted:组件释放完成;
  • onFlushCompleted:flush 执行完成;
  • onError:通知 MediaCodec 发生错误,回传两个参数,一个是错误码,另一个是错误的严重程度(需要上层执行的内容);
  • onComponentAllocated:组件创建完成;
  • onComponentConfigured:组件配置完成;
  • onInputSurfaceCreated
  • onInputSurfaceCreationFailed
  • onInputSurfaceAccepted
  • onInputSurfaceDeclined
  • onSignaledInputEOS
  • onOutputFramesRendered:通知 MediaCodec 已经被渲染的帧的信息;
  • onOutputBuffersChanged:通知 MediaCodec output buffer 发生了变化
  • onFirstTunnelFrameReady:通知 MediaCodec 第一个 tunnel frame 准备好了;

这里有几个 Callback 调用需要注意,例如 onStartCompleted,它并不是真正等组件启动完成才调用;又例如 onStopCompleted 和 onReleaseCompleted 应该如何区分等等。

3、BufferChannelBase

BufferChannel 位于 MediaCodec 和 CodecBase 之间,它管理着 buffer 的传输。预期只有 MediaCodec 会调用这些方法,CodecBase 需要单独实现自己的接口 BufferChannelBase。

客户端可能在不同的线程中同时获取到 BufferChannelBase 对象,这里应该指的是 MediaCodec 和 CodecBase 可能会同时调用到 BufferChannel 的方法;所有的方法在持有锁时都不会依赖 CodeBase,意思就是 CodecBase 应该不会被阻塞;关键的内部代码执行时间小于 1 ms;

BufferChannel 的作用就是做 MediaCodec 和 ACodec 之间 buffer 交互的中间层,里面会封装有一些关于 buffer 处理的内容。BufferChannel 是属于 CodecBase 的,它在 CodecBase 中创建,具体如何实现需要根据不同的 CodecBase 来实现,比如 ACodec 是现有 ACodecBufferChannel,里面会定义有供 ACodec 调用的独有的功能,ACodec 通过调用这些方法将消息发送给 BufferChannel处理,这些消息进入 BufferChannel 之后会由 Callback 最终传递给 MediaCodec。

MediaCodec 通过 getBufferChannel 来获取 ACodec 创建的所有 input/output buffer,并且调用 bufferchannel 的公有接口给 CodecBase 发送 buffer 消息。

所以说 BufferChannelBase 的所有方法预期都是给 MediaCodec 调用的,不同 CodecBase需要单独实现自己的接口。
Android 13 - Media框架(18)- CodecBase_第1张图片

  • setCallback:设置 MediaCodec 的 buffer callback对象;
  • setCrypto
  • setDescrambler
  • queueInputBuffer:将一个 input buffer 加入的 bufferchannle 的队列中;
  • queueSecureInputBuffer
  • attachBuffer
  • attachEncryptedBuffer
  • renderOutputBuffer:渲染一个 output buffer;
  • discardBuffer:丢弃一个 buffer
  • getInputBufferArray:获取 CodecBase 的 input buffer 数组;
  • getOutputBufferArray:获取 CodecBase 的 output buffer 数组;

关于 buffer 的处理有四个动作:

  • 获取 input buffer:
  • 写入 input buffer:
  • 获取 output buffer:
  • 渲染/丢弃 output buffer

其中两个写入/渲染动作由 MediaCodec 主动调用 BufferChannel 的方法来完成,而获取动作却需要借助 BufferCallback 被动完成。

4、BufferCallback

接口定义了所有从 BufferChannelBase 发送给 MediaCodec 的事件,同样的,这些方法必须是非阻塞的。

  • onInputBufferAvailable:通知 MediaCodec 一个 input buffer 可以被获取;
  • onOutputBufferAvailable:通知 MediaCodec 一个 output buffer 可以被获取;

这两个 Callback 传递的都是索引,我们可以通过这个索引 和 getInputBufferArray/getOutputBufferArray 获取的数组来拿到真正的 Buffer。

你可能感兴趣的:(Android,Media,android,Framework,音视频,Media)