Codec2使用PipelineWatcher在CCodec进程中跟踪input buffer。PipelineWatcher的UML类图如下:
一个C2Work成功送给组件后,CCodecBufferChannel会调用onWorkQueued:
void PipelineWatcher::onWorkQueued(
uint_t frameIndex,
std::vector<std::shared_ptr<C2Buffer>> &&buffers,
const Clock::time_point &queuedAt) {
auto it = mFramesInPipeline.find(frameIndex);
if (it != mFramesInPipeline.end()) {
(void)mFramesInPipeline.erase(it);
}
(void)mFramesInPipeline.try_emplace(frameIndex, std::move(buffers), queuedAt);
}
onWorkQueued很简单,先将C2Buffer和time_point封装为Frame,然后将frameIndex作为key,将Frame作为value存到FramesInPipeline中。
当送给组件的C2Buffer使用完成,onInputBufferReleased将会被调用:
std::shared_ptr<C2Buffer> PipelineWatcher::onInputBufferReleased(
uint_t frameIndex, size_t arrayIndex) {
// 1. 查找是否有frameIndex对应的entry
auto it = mFramesInPipeline.find(frameIndex);
if (it == mFramesInPipeline.end()) {
return nullptr;
}
if (it->second.buffers.size() <= arrayIndex) {
return nullptr;
}
// 2. 获取到C2Buffer,从FramesInPipeline移除Frame中的buffers,但是不会移除Frame
std::shared_ptr<C2Buffer> buffer(std::move(it->second.buffers[arrayIndex]));
return buffer;
}
这里要注意的是,onInputBufferReleased会移除Frame中的buffers,但是不会移除Frame。
当送给组件的C2Buffer使用完成,且输出一帧output,onWorkDone会被调用:
void PipelineWatcher::onWorkDone(uint_t frameIndex) {
auto it = mFramesInPipeline.find(frameIndex);
if (it == mFramesInPipeline.end()) {
if (!mTunneled) {
} else {
}
return;
}
(void)mFramesInPipeline.erase(it);
}
onWorkDone会把Frame移除,它和onInputBufferReleased有很大的区别。一般onInputBufferReleased会比onWorkDone更早被调用,所以移除Frame时,Frame中的buffers已经是NULL了。
CCodecBufferChannel将input buffer送给上层应用之前,会先调用PipelineWatcher的pipelineFull方法检查流水线是否已满,如果满了就停止回传buffer,从而实现数据的写入控制。
pipelineFull代码不长,但是可能有点难理解,我们一起思考看看:
2.1、registerFrameData
2.2、unregisterFrameData
2.3、onBufferDestroyed
2.4、main
原文阅读:
扫描下方二维码,关注公众号《青山渺渺》阅读音视频开发内容。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- hzar.cn 版权所有 赣ICP备2024042791号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务