66 working group</a > (public_webgl 'at' khronos.org) </contact >
77
88 <contributors >
9- <contributor >Byungseon Shin (sun.shin 'at' lge.com)</contributor >
10- <contributor >Andrey Volykhin (andrey.volykhin 'at' lge.com)</contributor >
9+ <contributor >Byungseon Shin, LG Electronics</contributor >
10+
11+ <contributor >Andrei Volykhin, LG Electronics</contributor >
12+
13+ <contributor >Mark Callow, Edgewise Consulting</contributor >
14+
1115 <contributor >Members of the WebGL working group</contributor >
1216 </contributors >
1317
1822 </depends >
1923
2024 <overview >
21- <mirrors href = " https://www.khronos.org/registry/gles/extensions/OES/OES_EGL_image_external.txt "
22- name = " OES_EGL_image_external " >
23- < addendum >Defines a new texture target < code >TEXTURE_VIDEO_IMAGE</ code >.</ addendum >
24- < addendum >Provides a mechanism for binding <code >HTMLVideoElement </code > stream to video texture targets.</ addendum >
25- < addendum >Provides time of frame, texture width and height of < code >HTMLVideoElement</ code >'s texture binding.</ addendum >
26- </ mirrors >
25+ <p >This extension defines a new object, the < code >HTMLVideoTexture</ code >,
26+ that can be used to efficiently transfer a sequence of image frames from
27+ a producer which is outside the control of WebGL into a WebGL texture.
28+ This is done via a new texture target, <code >TEXTURE_VIDEO_WEBGL </code >
29+ which can only be specified as being the consumer of an image stream from a
30+ producer element.</ p >
2731
28- <features >
29- <feature >Add support for <code >WEBGL_video_texture</code >
30- binding of HTMLVideoElement.</feature >
32+ <p >There is no support for most of the functions that manipulate other
33+ texture targets (e.g. you cannot use <code >*[Tt]ex*Image*()</code >
34+ functions with <code >TEXTURE_VIDEO_WEBGL</code >). Also,
35+ <code >TEXTURE_VIDEO_WEBGL</code > targets never have more than a single
36+ level of detail. Because of these restrictions, it is possible to
37+ allow sources which have internal formats not otherwise supported by WebGL,
38+ such as planar or interleaved YUV data to be WebGL texture target siblings.</p >
39+
40+ <p >The extension extends GLSL ES with a new <code >samplerVideoWebGL</code > type
41+ and matching sampling functions that provide a place for an implementation
42+ to inject code for sampling non-RGB data when necessary without degrading performance
43+ for other texture targets. Sampling a <code >TEXTURE_VIDEO_WEBGL</code > via a sampler of
44+ type <code >samplerVideoWebGL</code > always returns RGBA data.</p >
45+
46+ <p >Sampling a WebGL texture which is not associated with any
47+ <code >HTMLVideoTexture</code > object will return a sample value of (0,0,0,1).</p >
48+
49+ <p >Each <code >TEXTURE_VIDEO_WEBGL</code > texture object may require up
50+ to 3 texture image units for each texture unit to which it is bound.
51+ The number of texture image units required by a bound texture object
52+ can be queried using <code >getTexParameter</code > with target set
53+ to the texture target in question, value set to
54+ <code >REQUIRED_TEXTURE_VIDEO_IMAGE_UNITS_WEBGL</code >, and <code >activeTexture</code >
55+ set to the texture unit to which the texture object is bound.</p >
56+
57+ <p ><code >HTMLVideoTexture</code > provides a commands for <em >latching</em > an
58+ image frame into the consuming texture as its contents and retrieving additional
59+ information as a timestamp or a transformation matrix.</p >
3160
61+ <features >
3262 <glsl extname =" WEBGL_video_texture" >
63+ <stage type =" vertex" />
3364 <stage type =" fragment" />
65+
3466 <type name =" samplerVideoWEBGL" />
3567
3668 <function name =" texture2D" type =" vec4" >
3971 <param name =" coord" type =" vec2" />
4072 </function >
4173
74+ <function name =" texture2DProj" type =" vec4" >
75+ <param name =" sampler" type =" samplerVideoWEBGL" />
76+
77+ <param name =" coord" type =" vec3" />
78+ </function >
79+
80+ <function name =" texture2DProj" type =" vec4" >
81+ <param name =" sampler" type =" samplerVideoWEBGL" />
82+
83+ <param name =" coord" type =" vec4" />
84+ </function >
4285 </glsl >
4386 </features >
4487 </overview >
4588
4689 <idl xml : space =" preserve" >
4790[NoInterfaceObject]
48- interface WebGLVideoFrameInfo {
49- readonly attribute double currentTime;
50- readonly attribute unsigned long textureWidth;
51- readonly attribute unsigned long textureHeight;
91+ interface HTMLVideoTexture : EventTarget {
92+ void updateTexImage();
93+
94+ double getTimestamp();
95+ void getTransformMatrix(Float32Array matrix);
96+
97+ double getLastAvailableTimestamp();
98+
99+ attribute EventHandler onframeavailable;
100+ attribute EventHandler onerror;
52101};
53102
54103[NoInterfaceObject]
55104interface WEBGL_video_texture {
56- const GLenum TEXTURE_VIDEO_IMAGE = 0x851D;
57- const GLenum SAMPLER_VIDEO_IMAGE = 0x8B61;
105+ const GLenum TEXTURE_VIDEO_WEBGL = 0x9248;
106+ const GLenum SAMPLER_VIDEO_WEBGL = 0x9249;
107+ const GLenum TEXTURE_BINDING_VIDEO_WEBGL = 0x924A;
108+ const GLenum REQUIRED_TEXTURE_VIDEO_IMAGE_UNITS_WEBGL = 0x924B;
58109
59- [RaisesException] WebGLVideoFrameInfo VideoElementTargetVideoTexture(
60- GLenum target, HTMLVideoElement video);
110+ [RaisesException] HTMLVideoTexture? createVideoTexture(WebGLTexture? texture, HTMLVideoElement video);
61111};
62112 </idl >
63113
64- <samplecode xml : space =" preserve" >
114+ <!-- new functions -->
115+
116+ <newfun >
117+ <p >On <code >HTMLVideoTexture</code >:</p >
118+
119+ <function name =" updateTexImage" type =" void" >
120+ Release the previously-held frame, if any, and update the texture image
121+ to the most recent frame from the image stream.
122+ This may cause some frames of the stream to be skipped.
123+ Sampling the WebGL texture, that is the <code >HTMLVideoTexture</code >'s
124+ <em >consumer</em >, will return values from the latched image.
125+ The image data is guaranteed not to change as long as the image is latched.
126+ It will implicitly binds associated WebGL texture to the active texture unit's
127+ <code >TEXTURE_VIDEO_WEBGL</code > texture target.
128+ </function >
129+
130+ <function name =" getTimestamp" type =" double" >
131+ Retrieve the timestamp associated with the texture image set by the most
132+ recent call to <code >updateTexImage</code >. This timestamp represent
133+ the time of frame relative to start of the producer timeline, the time
134+ when the frame was produced (the Media Stream Counter in OpenML),
135+ not the time when frame was received by application.
136+ This timestamp is in seconds, and is normally monotonically increasing.
137+ It is equivalent of <code >HTMLMediaElement</code >'s <em >currentTime</em > property.
138+ </function >
139+
140+ <function name =" getTransformMatrix" type =" void" >
141+ <param name =" matrix" type =" Float32Array" />
142+ Retrieve the 4x4 texture coordinate transform matrix associated with
143+ the texture image set by the most recent call to <code >updateTexImage</code >.
144+ This transform matrix maps 2D homogeneous texture coordinates
145+ of the form (s, t, 0, 1) with s and t in the inclusive range [0, 1]
146+ to the texture coordinate that should be used to sample that location
147+ from the texture. Sampling the texture outside of the range
148+ of this transform is undefined.
149+ The matrix is stored in column-major order.
150+ </function >
151+
152+ <function name =" getLastAvailableTimestamp" type =" double" >
153+ Retrieve the timestamp associated with the most recent texture image
154+ which could be provided by a producer.
155+ </function >
156+ </newfun >
157+
158+ <dl class =" methods" >
159+ <dt ><code class =" attribute-name" >onframeavailable</code > of type
160+ <code >EventHandler</code ></dt >
161+
162+ <dd >The <code >onframeavailable</code > handler is executed when a new frame
163+ could be latched from image stream.</dd >
164+
165+ <dt ><code class =" attribute-name" >onerror</code > of type
166+ <code >EventHandler</code ></dt >
167+
168+ <dd >The <code >onerror</code > handler is executed when this object
169+ will be in "incomplete" state in case if a image stream's consumer or
170+ producer will be deleted or due internal errors.</dd >
171+ </dl >
65172
66- <p > This a fragment shader that samples a video texture.</p >
173+ <!-- new tokens -->
174+
175+ <newtok >
176+ <p >On <code >WEBGL_video_texture</code >:</p >
177+
178+ <p >The meaning and use of these tokens is similar as described in <a
179+ href =" https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt" >OES_EGL_image_external</a >.</p >
180+
181+ <function name =" bindTexture" type =" void" >
182+ <param name =" target" type =" GLenum" />
183+ <param name =" texture" type =" WebGLTexture?" />
184+ <code >TEXTURE_VIDEO_WEBGL</code > is accepted as a target by the
185+ <code >target</code > parameter of <code >bindTexture</code >
186+ </function >
187+
188+ <function name =" getActiveUniform" type =" WebGLActiveInfo?" >
189+ <param name =" program" type =" WebGLProgram?" />
190+ <param name =" index" type =" GLuint" />
191+ <code >SAMPLER_VIDEO_WEBGL</code > can be returned in the
192+ <code >type</code > field of the <code >WebGLActiveInfo</code > returned by
193+ <code >getActiveUniform</code >
194+ </function >
195+
196+ <function name =" getParameter" type =" any" >
197+ <param name =" pname" type =" GLenum" />
198+ <code >TEXTURE_BINDING_VIDEO_WEBGL</code > is accepted by
199+ the <code >pname</code > parameter of <code >getParameter</code >
200+ </function >
201+
202+ <function name =" getTexParameter*" type =" any" >
203+ <param name =" target" type =" GLenum" />
204+ <param name =" pname" type =" GLenum" />
205+ <code >REQUIRED_TEXTURE_VIDEO_IMAGE_UNITS_WEBGL</code > is accepted
206+ as the <code >pname</code > parameter of <code >getTexParameter*</code >
207+ </function >
208+ </newtok >
209+
210+ <newfun >
211+ <p >New <code >HTMLVideoTexture</code > object creation</p >
212+
213+ <function name =" createVideoTexture" type =" HTMLVideoTexture?" >
214+ <param name =" texture" type =" WebGLTexture?" />
215+ <param name =" video" type =" HTMLVideoElement" />
216+ Create a new <code >HTMLVideoTexture></code > object that can be used to
217+ transfer a sequence of image frames from a <code >HTMLVideoElement</code >
218+ into a WebGL texture.
219+ WebGL texture must be defined as a texture with <code >TEXTURE_VIDEO_WEBGL</code >
220+ target before passing it as <code >texture</code > parameter
221+ (Note: to create a <code >TEXTURE_VIDEO_WEBGL</code > texture and bind it,
222+ call <code >bindTexture</code > with <code >target</code > set to
223+ <code >TEXTURE_VIDEO_WEBGL</code > and <code >texture</code >
224+ set to the name of the new created texture).
225+ If this function is called with <code >HTMLVideoElement</code >
226+ which origin differs from the origin of the containing Document,
227+ a <code >SECURITY_ERR</code > exception must be thrown.
228+ If the WebGL texture is later deleted, connected to a different
229+ <code >HTMLVideoTexture</code >, then this <code >HTMLVideoTexture</code >
230+ will be in "incomplete" state and release any associated resources.
231+ If the <code >HTMLVideoElement</code > or <code >HTMLVideoTexture</code >
232+ is later destroyed then the consuming texture will be "incomplete" and
233+ sampling from it will return a sample value of (0,0,0,1).
234+ </function >
235+ </newfun >
236+
237+ <errors >
238+ <error >
239+ The error <code >INVALID_OPERATION</code > is generated by calling
240+ <code >createVideoTexture</code > with a <code >texture</code > parameter
241+ that does not identify a <code >VIDEO_WEBGL</code > texture.
242+ </error >
243+ </errors >
244+
245+ <samplecode xml : space =" preserve" >
246+ <p >This a fragment shader that samples a video texture.</p >
67247 <pre >
248+ #version 100 es
68249 #extension GL_WEBGL_video_texture : require
250+
69251 precision mediump float;
70- varying vec2 v_texCoord;
71252
72253 uniform samplerVideoWEBGL uSampler;
254+ varying vec2 v_texCoord;
73255
74256 void main(void) {
75257 gl_FragColor = texture2D(uSampler, v_texCoord);
76258 }
77259 </pre >
78260
79- <p > This shows application that renders video using proposed extension. </p >
261+ <p >This shows application that renders an HTMLVideoElement using proposed extension.</p >
80262 <pre >
81- var videoElement = document.getElementById("video" );
82- var videoTexture = gl.createTexture( );
263+ var gl = document.createElement('canvas').getContext('webgl' );
264+ var video = document.getElementById("video" );
83265
84- function update() {
85- var ext = gl.getExtension('WEBGL_video_texture');
86- if(ext !=== null){
87- gl.bindTexture(ext.TEXTURE_VIDEO_IMAGE, videoTexture);
88- ext.VideoElementTargetVideoTexture(ext.TEXTURE_VIDEO_IMAGE, videoElement);
89- gl.bindTexture(ext.TEXTURE_VIDEO_IMAGE, null);
90- }
91- }
92-
93- function render() {
94- gl.clearColor(0.0, 0.0, 1.0, 1.0);
95- gl.clear(gl.COLOR_BUFFER_BIT);
266+ var ext = gl.getExtension('WEBGL_video_texture');
96267
97- gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer );
98- gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
268+ var texture = gl.createTexture( );
269+ gl.bindTexture(ext.TEXTURE_VIDEO_WEBGL, texture); // explicit texture binding
99270
100- gl.activeTexture(gl.TEXTURE0 );
101- gl.bindTexture(ext.TEXTURE_VIDEO_IMAGE, videoTexture) ;
102- gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0) ;
271+ var videoTexture = ext.createVideoTexture(texture, video );
272+ videoTexture.onframeavailable = function() { ... } ;
273+ videoTexture.onerror = function() { ... } ;
103274
104- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
275+ function update() {
276+ videoTexture.updateTexImage(); // implicit texture binding
105277 }
106- </pre >
107278
108- <p > Application renders each video frames into WebGL canvas based on game-loop pattern. </p >
109- <pre >
279+ function render() {
280+ // ... do something
281+ gl.drawArrays(...);
282+ }
110283
111284 while (true) {
112- update();
113- processInput();
114- render();
285+ update();
286+ processInput();
287+ render();
115288 }
116289 </pre >
117-
118290 </samplecode >
119291
120292 <tests />
121293
122- <issues />
294+ <issues >
295+ <ol >
296+ <li >
297+ <p >In which colorspace should be the RGB value returned by sampler?</p >
298+
299+ <p >A. In linear RGB colorspace.</p >
300+
301+ <p >B. In extended sRGB (scRGB-non-linear) colorspace <a
302+ href =" https://developer.apple.com/documentation/coregraphics/kcgcolorspaceextendedsrgb?language=objc" >kCGColorSpaceExtendedSRGB</a ></p >
303+
304+ <p >C. It will be allowed to choose by passed parameter at a
305+ <code >HTMLVideoTexture</code > object creation time.</p >
306+
307+ <p >UNRESOLVED.</p >
308+ </li >
309+ </ol >
310+ </issues >
123311
124312 <history >
125313 <revision date =" 2016/11/05" >
@@ -135,5 +323,8 @@ interface WEBGL_video_texture {
135323 <change >Define new sampler and texture type, TEXTURE_VIDEO_IMAGE and SAMPLER_VIDEO_IMAGE.</change >
136324 <change >Change EGLImageTargetTexture2DOES to VideoElementTargetVideoTexture.</change >
137325 </revision >
326+ <revision date =" 2017/09/21" >
327+ <change >Add new HTMLVideoTexture object and new tokens.</change >
328+ </revision >
138329 </history >
139330</proposal >
0 commit comments