2017-05-31 70 views
2

我有一串YUV数据(来自视频文件),我想实时流到屏幕。 (基本上,我想写一个能够实时播放视频的程序。)便携式YUV绘图环境

因此,我正在寻找一种将YUV数据发送到屏幕的便携方式。我最好喜欢使用可移植的东西,所以我不必为每个主要平台重新实现它。

我发现了一些选项,但他们都似乎有重大问题。它们是:

  1. 直接使用OpenGL,将YUV数据转换为RGB。 (并且使用单个四合一技术实现全屏幕技巧)

这显然不会工作,因为在CPU上将RGB转换为YUV对于实时显示图像来说太慢了。

  1. 使用OpenGL,但使用着色器将YUV流转换为RGB。

该选项稍微好一点。 Although the problem here is that (afaict), this will involve making two streams and splicing them together. It might work, but may have issues with larger resolutions.

  1. 改为使用SDL,它可以直接创建YUV上下文。

问题是我已经在为我的程序的其他方面(如播放控件)使用跨平台小部件库。据我所知,SDL只在其(possibly borderless)窗口中打开。我会理想地喜欢我的控件和绘图上下文在同一个窗口中。我可以用opengl做什么,但不能用SDL。

  1. 使用SDL,并在屏幕上使用类似Qt的小部件,使用消息传递协议在两个库之间进行通信。 Have the (borderless) SDL window constantly move itself on top of the opengl window.

虽然这种方法很聪明,但似乎这两个窗口很容易脱落,使用户体验不够理想。

  1. 忘记一个跨平台库,请认为操作系统具体,使用硬件加速,如果存在。

这是一个很好的解决方案,虽然它不是跨平台。

因此,有没有YUV数据绘制到一个屏幕,理想情况下没有什么好的办法:

  1. 便携式(至少在主要平台)。
  2. 快到足以实时。
  3. 允许其他窗口小部件在同一窗口中。
+0

使用#2:使用1或3(取决于YUV数据的平面度)纹理,并在渲染纹理四边形的同时在片段着色器中执行YUV→RGB转换。 SDL_Renderer在[幕后]执行此操作(https://hg.libsdl.org/SDL/file/1f2cb42aa5d3/src/render/opengl/SDL_shaders_gl.c#l128)。 – genpfault

+0

此外,请注意:CPU端颜色转换:['libswscale'](https://www.ffmpeg.org/libswscale.html),请参阅['ffplay']中的用法(https://ffmpeg.org/ffplay的.html)。 – genpfault

+0

Facepalm,谢谢你们俩。特别是@genpfault,现在我觉得有点笨,因为我已经在应用程序中使用ffmpeg了... –

回答

1

使用选项编号2.在着色器中执行YUV到RGB转换没有问题。没有这样的其他“便携”方式。

想一想:无论视频是多大或多小,片段着色器(转换完成的地方)都会在显示时执行每个像素,因此您可以将一个小视频全屏或大屏幕,计算(对于着色器)是相同的,因为它们显示相同数量的像素。

在正常情况下,任何显卡都可以运行这种着色器,没有任何问题。