I see the disconnect. My comments have been referring to the native OES_EGL_image_external OpenGL ES extension. The API added by that extension only supports binding an EGLImage to a texture. An EGLImage is a single image.
You are referring to the underlying external texture object. Yes an external texture as defined by OES_EGL_image_external can be the consumer endpoint for either an EGLImage or an EGLStream or indeed Android’s SurfaceTexture. But different API functions are used to hook up EGLStreams or SufaceTextures.
An external texture maps only a single image. It is really important to be clear about this. SurfaceTexture is a stream, almost certainly implemented, in most cases, using EGLStream. It says
is called, the contents of the texture object specified
when the SurfaceTexture was created are updated to contain the most recent image from the image
stream. This may cause some frames of the stream to be skipped.
updateTexImage() is to be called by the app every frame.
Your WebGL version of OES_EGL_image_external modifies EGLImageTargetTexture2DOES to accept an HTMLVideoElement instead of an EGLImage. Thus you are, confusingly, changing a call that in the native extension took a single image, into one that takes a stream of images. You are stepping into the world of EGLStream but avoiding its API.
The example code shows EGLImageTargetTexture2DOES being called just once at the start of the program. This is equivalent to calling SurfaceTexture.attachToGLContext. There is no step to latch a video frame when drawing a WebGL frame, no equivalent to updateTexImage. It just does WebGL rendering every frame.
So you are relying on unspecified magic to ensure that the mapped frame is never being updated while the WebGL application is sampling it. You are also concealing from the app which video frame it will be sampling.
I maintain that you need to stop relying on magic and hiding what’s happening. Internally here has to be a buffered stream to ensure there is always a complete frame when the WebGL app is sampling thus avoiding tearing. (The alternative is locking on a single image buffer which is likely to stall both the video decoder and the graphics pipeline causing horrendous performance.) The buffering should be exposed and put under the control of the application.
The extension needs updateTexImage-like functionality. Once you have that then your new WebGLVideoFrameInfo can return information about the currently mapped frame.
If you are trying to mimic SurfaceTexture then you may also need to handle cases where the video size or orientation can change between frames. This is handled in SurfaceTexture by requiring the app to query the texture transform to be used with the texture. I don’t know if such changes can occur in HTMLVideoElements.