-
如何解决视频or相机处理。帧失败和帧渲染 同步问题的呢?TOOD 。 hardwarebuffer是28 android 9开放出来的。 ImagerReader
- 优化。先绘制到小的buffer上FBO,走glreadpixel读取yuv数据。先计算成yuv数据。帧同步。可以是多线程的。在渲染线程。thread mudex
- imagereader
- 生产方必须走surface流程,消费方只有surfacetexture可选。surfacetexture又必须在gl线程中消费,没有拿裸rawbuffer的API.
- 或者生产方绘制到buffer上。buffer来源可以是 bitmap、hardwarebuffer、surface。消费方有 imageview、uithreadedrender、myGLThread、mediaRecord.
- 如果走surface,消费方一定拿不到buffer raw数据的。只能回读出来。通过glReadPixel 或者 FBO写到Hardwarebuffer上。
- HardwareBuffer是个好东西,既可以 作为消费buffer 又可以 作为生产buffer。被封装成EGLImage或者直接lock出数据指针。并且可以是rgba也可以是yuv
- imagerreader的出现,打破了拿不到surface消费方拿不到 rawbuffer的局限。
- 消费方是 同步模式(可背压) 、 同步+丢弃 、 异步。
- controlledByApp 消费方是ture。生产方也是true,触发了生产方走的丢弃模式。如果生产方不想走丢弃模式,则可以设置timeout。
- queue中至少2个buffer。
- 这是SurfaceFlinger,通过surfaceflinger出去的surface,ControlledByApp被永远设置为false,永远走背压模式。有UI、surfaceview。非surfaceflinger默认都是true 比如mediacodec。
sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
}4. surface的消费方。可以是 ImageReader、SurfaceTexture。 5. surface、HardwareBuffer、ANativeWindow、PhoneWindow 1.Graphicbuffer(HardwareBuffer) -》IGraphicBufferProducer-》Surface-》 ANativeWindow 6. Camera-》ImageReader-》并行 1. 包装为EGLImage 借助纹理上屏。void EGLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) { glEGLImageTargetTexture2DOES(texTarget,static_cast<GLeglImageOES>(mEglImage));} 2. 读取YUV走NN -》 获取NN结果变幻矩阵。 3. 综合绘制。下一帧的更新可以采用,消费优先的原则。生产触发还是消费触发。两种。消费触发就是,生产只打标,消费在glloop中判断标记,。image的close什么时候执行呢?需要GPU绘制结束后,要用eglsyncfence机制判断 4. 把surfacetextue的 updateImageTexture的过程 开放给 开发者控制。 5. 并image中的内容是可读取出来的。
mGraphicBuffer 转为 EglImage
void EGLConsumer::onAcquireBufferLocked(BufferItem* item, SurfaceTexture& st) {
// If item->mGraphicBuffer is not null, this buffer has not been acquired
// before, so any prior EglImage created is using a stale buffer. This
// replaces any old EglImage with a new one (using the new buffer).
int slot = item->mSlot;
if (item->mGraphicBuffer != nullptr || mEglSlots[slot].mEglImage.get() == nullptr) {
mEglSlots[slot].mEglImage = new EglImage(st.mSlots[slot].mGraphicBuffer);
}
}
网友评论