2DCanvas的webgl context提供了一組接口 texImage2D()用于将不同類型的源作為材質渲染到指定texture上。這些不同類型的源包括:
ArrayBufferView, ImageData,
HTMLImageElement,HTMLCanvasElement, HTMLVideoElement
這篇部落格分析HTMLVideoElement作為源渲染到指定texture的實作過程。
也就是下面這個接口的具體實作,
WebGLRenderingContextBase::texImage2D(...,HTMLVideoElement,textureid,...)。
整個過程可以分成3個步驟:
步驟1.承載video内容的texture建立的過程;
步驟2:包含video内容的texture與video視訊流關聯的過程;
步驟3:包含video内容的texture被繪制到指定texture的過程;
下面分别看這三個步驟:
步驟1.承載video内容的texture建立的過程;
這個過程主要做三件事情:
1).建立承載video内容的texture,圖中路徑1标示的過程;
2).建立SurfaceTexture封裝1)中的texture,圖中路徑2标示的過程,SurfaceTexture會在步驟2中關聯到android mediaplayer上,這樣mediaplayer的輸出目标就變成了SurfaceTexture封裝的texture;
3).将1)中建立的承載video内容的texture封裝進mailbox.在另一個gl線程繪制video texture到指定texture時,會通過mailbox取得video texture,圖中路徑3标示的過程.
步驟2:包含video内容的texture與video視訊流關聯的過程
參照http://blog.csdn.net/jaylinzhou/article/details/51722363中關于surfacetexture類的說明,使用SurfaceTexture類就是為了改變MediaPlayer的輸出目的地。封裝了video texture的SurfaceTextrue與MediaPlayer綁定的過程如下圖:
步驟3:包含video内容的texture被消費的過程
這個過程分三個小步驟完成:
1)在繪制線程根據命名的mailbox取出video texture;
2)更新video texture的内容為最新;
3)video texture繪制到指定的目标texture;
video texture繪制到指定目标texture的過程是通過如下三個gl指令完成的:
3.1)目标texture作為framebuffer的後端存儲attach到framebuffer上;
glFramebufferTexture2DEXT();
3.2)綁定video texture;
glBindTexture(source_target, source_id);
3.3)繪制video texture到framebuffer上,由于framebuffer綁定了目标texture,這樣,video texture就繪制到了目标textrure上;
glDrawArrays(GL_TRIANGLE_FAN,0, 4);