SurfaceView 容器中的 onDraw 会导致视频无效吗?

Posted

技术标签:

【中文标题】SurfaceView 容器中的 onDraw 会导致视频无效吗?【英文标题】:does onDraw in a surfaceview container causes video to be invalidated? 【发布时间】:2014-04-17 12:55:51 【问题描述】:

我有一个视频观看。这个视图包含在一个名为VideoStructure 的自定义FrameLayout 中,我还可以在其中放置频道徽标或类似内容。 在正常情况下,视频是硬件加速的,所以视图(我想)真的是一个透明的“黑洞”,而视频是由相关硬件解码和渲染的。

我的问题是,如果我在视频视图的容器中覆盖 draw()(图像中的 VideoStructure 扩展了 FrameLayout)以绘制一些东西(即图像中的圆圈)OVER强> 视频-我正在覆盖draw(),而不是onDraw()-这会破坏硬件加速吗?我可以期待这样做会带来很大的性能损失吗?

【问题讨论】:

【参考方案1】:

它应该对性能没有影响。

SurfaceViews 有两个部分,“视图”部分和“表面”部分。 “视图”部分是与其他视图相吻合的透明孔,“表面”部分是完全独立的层,由系统与视图层合成。视频正在发送到“表面”部分。

如果您覆盖 SurfaceView 的“视图”渲染器,您将获得通常完全透明的视图的硬件加速 Canvas(因此,如果您删除它,您最好使用零 alpha 和正确的传输模式)。

如果您尝试在“表面”部分进行渲染,通过从lockCanvas() 获取 Canvas,您将失败(因为视频有效地锁定了它),或者成功并阻止将视频写入其中。

无论“视图”层中出现什么,系统合成器都必须混合“视图”层和“表面”层,因此使更多像素不透明不会产生可衡量的影响。

更新:请参阅graphics architecture doc,了解有关表面和成分的更多详细信息。

【讨论】:

哦,多么准确的解释,正是我想知道的! @fadden - 我知道这是一个旧答案,但它在搜索中出现,并且作为 rupps 注释非常详细,所以快速跟进问题:我们如何解释 onDraw 方法 - 它是否被称为当您的答案中的“视图”部分或“表面”部分被绘制到(或两者)时?我猜可能是系统合成器必须将视图和视频与写入的每个视频帧混合,这就是为什么,如其他地方所讨论的,您可以通过查看视图的 onDraw 来计算视频帧率? View 失效时应用框架调用onDraw()。视频更新不调用它。请记住,视图 UI 和视频正在渲染到不同的图形缓冲区集,两者都被馈送到系统合成器(前者由应用程序提供,后者由媒体服务器进程中的视频编解码器提供)。您无法从 onDraw() 计算视频帧速率,除非您在软件中解码视频并对每一帧发出无效请求。 很好的解释,尤其是关于单独图形缓冲区的说明(我必须通过你上面链接的文档来工作......)。

以上是关于SurfaceView 容器中的 onDraw 会导致视频无效吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 上的 Camera 使用的 SurfaceView 上绘制叠加层?

Android中使用SurfaceView和Canvas来绘制动画

用surfaceView实现高性能动画

在使线性布局容器无效后未调用子视图的 ondraw()

安卓复习9

安卓复习9