如何将动态位图流渲染到画布上?

4

我已经编写了一个OpenGL游戏,希望能通过canvas元素允许远程游戏。输入很简单,但视频很难。

目前我正在使用node.js启动游戏,在渲染循环中发送一个base64编码的位图数据流,表示当前帧。通过websocket将base64帧发送到客户端页面,并逐像素地呈现(非常缓慢)。显然这样做是不可行的。

我一直在考虑尝试生成一个视频流,然后可以通过标记(如http://mrdoob.github.com/three.js/examples/materials_video.html)轻松地将其呈现在画布上。

我对这个想法的问题是我不知道足够有关编解码器/流媒体的知识,以高层次确定是否可能实现?我不确定甚至编解码器是否是我需要担心内容动态更改并可能提前几帧呈现的部分。

我其他的想法:

  • 尝试从base64帧创建HTMLImageElement
  • 尝试优化压缩/重绘区域,以使像素带宽更低(似乎无法实现我需要达到20+fps的性能水平)。

然后总是有选择使用Flash的选项...但我真的很想避免它。我正在寻找一些关于要追求的技术和想法的意见?

2个回答

2
尝试在YCbCr色彩空间中转换RGB,并将像素值流式传输为:
Y1 Y2 Y3 Y4 Y5 .... Cb1 Cb2 Cb3 Cb4 Cb5 .... Cr1 Cr2 Cr3 Cr4 Cr5 ...

由于存在许多重复模式,因此任何压缩算法都会比RGBRGBRBG序列更好地压缩它。

http://zh.wikipedia.org/wiki/YCbCr


1
另外,请查看 https://github.com/pkrumins/node-video。这个库似乎可以处理所有与视频编码有关的繁琐工作。 - Gleb M Borisov
它真的比RRRRRGGGGGBBBBB压缩得更好吗? - Nakilon
1
刚刚测试了一下1920x1080的真实照片。压缩后RGB大小为392kb,YCbCr大小为309kb。压缩后RR..GG..BB大小为409kb,YY..CbCb..CrCr大小为218kb。效果真的很好 :) 另外,您可以尝试将图像分割成N个M像素边长的正方形,并为每个正方形线性编写YY..CbCb..CrCr序列,我认为这样会更好地压缩,稍后会进行检查。但不要忘记,在YCbCr中可能会丢失一些颜色信息-请查看维基百科获取详细信息。对于回复晚了,非常抱歉 ;) - Gleb M Borisov

1
  1. 为什么要将数据进行base64编码?我认为可以通过WebSocket直接传输原始字节

  2. 如果你有一个正确格式的RGBA值的线性数组,你可以将其直接倒入一个ImageData对象中,然后使用单个ctx.putImageData()调用进行后续处理。


  1. 在谷歌上搜索似乎表明情况并非如此,但我从未尝试过(因为在尝试之前我已经在谷歌上搜索了)。
  2. 现在我想了想...你是对的,结合重绘区域/压缩可能足够快。我会进行实验。
- amirpc
是的,经过进一步的思考,WebSocket 可能可以接收原始字符串,但您仍然需要将其解包到本地数组中才能将其与 putImageData() 一起使用。 - Alnitak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接