【问题标题】:WebGL video texture size limits on android - how to use 3840 * 2160?android上的WebGL视频纹理大小限制-如何使用3840 * 2160?
【发布时间】:2018-05-03 13:47:20
【问题描述】:

我正在开发一个 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:设置nativeWindow 0xc9ef2008为3840x2160,颜色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 浏览器
  • 我可以上传大小为 3840 * 2160 的自定义纹理并进行渲染
  • 我可以使用 &lt;video&gt; 标签解码和播放大小为 3840 * 2160 的视频
  • 我无法将 3840 * 2160 视频的帧上传到 WebGL
  • 较低的分辨率效果很好

谢谢!

【问题讨论】:

    标签: android google-chrome video webgl


    【解决方案1】:

    经过一周的努力了解问题后,现在很明显错误是在我们这边。

    视频确实创建为 3840 x 2160,但是是从分辨率为 3840 x 4320 的源视频创建的。将视频转换为 3840 x 2160 时,ffmpeg 将纵横比设置为 (3840/4320),导致 Android 将视频膨胀回该大小。膨胀尺寸的高度 > 4096,这就是无法创建纹理的原因。

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

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

    我学到了什么:

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

    【讨论】:

      猜你喜欢
      • 2013-03-17
      • 2012-04-14
      • 2014-03-30
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      相关资源
      最近更新 更多