WebGL视频纹理大小限制在android上 - 如何使用3840 * 2160?

时间:2018-05-03 13:47:21

标签: android google-chrome video webgl

我正在开发一个WebGL应用程序,它使用HLS.js从HTML5视频中获取纹理流。它在桌面上运行良好,它适用于移动Android上的1920 * 1080视频,但不适用于3840 * 2160.

我已经在几款高端设备(Xperia X Performance,三星Galaxy S8)上测试了这款应用程序,这两款产品均无法用于4k视频。

我知道视频可以在这些设备上播放,因为我还有一个调试模式,其中视频元素连接到DOM,视频渲染完美。

我还在这些设备上使用了http://webglreport.com/,该页面显示我应该可以使用4096 * 4096纹理。

我还使用Javascript ArrayBuffer手动生成了一个3840 * 2160,并且该纹理已正确渲染。

这是我复制视频的方式

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.videoElement);

在Chrome Android上执行此尺寸为3840 * 2160的视频通话时,我会收到以下日志

  

SurfaceUtils:为3840x2160设置nativeWindow 0xc9ef2008,颜色为0x7fa30c04,旋转0,用法0x20002900

     

chromium:[INFO:CONSOLE(11818)]“WebGL:INVALID_VALUE:texImage2D:   宽度或高度超出范围“

gl.getError()映射到此错误代码:

  

GL_INVALID_VALUE,0x0501

这些是我用于背景纹理的参数

const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

以下是我生成和上传测试纹理的方法

const width = 3840;
const height = 2160;

const generateTex = (w: number, h: number): number[] => {
    const res = [];
    for (let i = 0; i < w * h; i++) {
        res.push(0, 255, 0);
    }
    return res;
};

const image = new Uint8Array(generateTex(width, height));
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, image);

texImage2D的文档说

  

HTMLVideoElement类型的来源

     

纹理的宽度和高度   设置为视频上传帧的宽度和高度   像素。

问题是:是否有某个规格可以解释为什么我的3840 * 2160纹理无法渲染?

TL; DR

  • 高端设备(Xperia X Performance,Galaxy S8)
  • Android Chrome
  • 我可以上传尺寸为3840 * 2160的自定义纹理并将其渲染
  • 我可以解码&amp;使用<video>标记
  • 播放尺寸为3840 * 2160的视频
  • 我无法将3840 * 2160视频中的帧上传到WebGL
  • 分辨率较低

谢谢!

1 个答案:

答案 0 :(得分:0)

经过一周的努力来理解这个问题后,现在很清楚错误就在我们的最后。

该视频确实创建为3840 x 2160,但是是从分辨率为3840 x 4320的源视频创建的。当将视频转换为3840 x 2160时,ffmpeg将宽高比设置为(3840/4320),领先的Android将视频扩展回那个尺寸。膨胀尺寸的高度> 4096,这就是无法创建纹理的原因。

我们在其他平台(本机应用)上没有看到此问题,因此可能是Android媒体播放器的一些怪癖。

我们已经通过手动将(3840/2160)的“正确”宽高比设置为ffmpeg参数来解决问题。

我学到了什么:

不要认为VLC或QuickTime等应用程序报告的分辨率将正确反映每个其他平台上会发生的情况。在实现检查HTML视频元素分辨率所需的代码之后,很明显Android上与其他平台相比发生了不同的事情。