Я занимаюсь разработкой приложения WebGL, которое получает поток текстур из видео HTML5 с использованием HLS.js. Он отлично работает на настольных ПК и работает с видео 1920 * 1080 на мобильном Android, но не для 3840 * 2160.
Я протестировал приложение на нескольких высокопроизводительных устройствах (Xperia X Performance, Samsung Galaxy S8), оба из которых не работают для видео 4K.
Я знаю, что видео можно воспроизводить на этих устройствах, потому что у меня также есть режим отладки, когда элемент видео подключен к DOM, и видео воспроизводится идеально.
Я также использовал http://webglreport.com/ на этих устройствах, и на этой странице показано, что я смогу использовать 4096 * 4096 текстур.
Я также вручную сгенерировал 3840 * 2160, используя Javascript ArrayBuffer, и эта текстура была правильно обработана.
Вот как я копирую видео
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.videoElement);
При выполнении этого звонка для видео размером 3840 * 2160 на Chrome Android я получаю следующую распечатку журнала
SurfaceUtils: настроить nativeWindow 0xc9ef2008 для 3840x2160, цвет 0x7fa30c04, вращение 0, использование 0x20002900
хром: [INFO: КОНСОЛЬ (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 и отобразить ее
- Я могу декодировать и воспроизводить видео размером 3840 * 2160, используя тег
<video>
- Я НЕ могу загрузить кадры из видео 3840 * 2160 в WebGL
- С меньшим разрешением работает просто отлично
Спасибо!