Our project is a secondary development based on chromium(107 version), and I am responsible for the media work.
Currently, I encountered a strange scenario, using webgl to obtain video content from the video element and then rendering it to canvas. Demo link is:
https://alphahans.github.io/index_ori_duration_100.htmlOn some Huawei mobile phones (Mate30pro\Mate40\Nova6...), you will find that the picture rendered by the video tag is stuck or rolled back. It seems that webgl copies the old texture and re-renders it on the video tag.
So I try to find the cause of the problem.
First of all, I found the unreasonable timing of wegbl calls. I replaced the following calls from
```
// calls gl.drawArrays or gl.drawElements
webglUtils.drawBufferInfo(gl, bufferInfo);
// Tell WebGL we want to affect texture unit 0
gl.activeTexture(gl.TEXTURE0);
// Bind the texture to texture unit 0
gl.bindTexture(gl.TEXTURE_2D, texture);
// Tell the shader we bound the texture to texture unit 0
gl.uniform1i( gl.getUniformLocation(meshProgramInfo.program, "uSampler"), 0);
if( copyVideo ){
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
}else{
// Fill the texture with a 1x1 blue pixel.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
}
```
to
```
if( copyVideo ){
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
}else{
// Fill the texture with a 1x1 blue pixel.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
}
// Tell WebGL we want to affect texture unit 0
gl.activeTexture(gl.TEXTURE0);
// Bind the texture to texture unit 0
gl.bindTexture(gl.TEXTURE_2D, texture);
// Tell the shader we bound the texture to texture unit 0
gl.uniform1i( gl.getUniformLocation(meshProgramInfo.program, "uSampler"), 0);
// calls gl.drawArrays or gl.drawElements
webglUtils.drawBufferInfo(gl, bufferInfo);
```
and found that the problem has been solved.
It is obvious here that webgl should render immediately after copying the texture, instead of waiting until the next cycle to render, otherwise the rendered picture will be old. Therefore, my guess as to why I faced the abnormal phenomenon above is that the video page draws old frames, causing <video> to roll back or freeze.
But I don't know why this problem can be solved here.
Previously, I was an audio and video developer(not in chromium),so I try to understand the code of media.
My Question:
1. Is the data decoded by MediaCodec converted into SharedImage a deep copy?
Why do I have this question?
Combing through the code, I found that webgl gets the latest videoframe through VideoFrameCompositor::GetCurrentFrameOnAnyThread. code like:
```
scoped_refptr<media::VideoFrame>
VideoFrameCompositor::GetCurrentFrameOnAnyThread() {
base::AutoLock lock(current_frame_lock_);
return first_video_frame_ ? first_video_frame_ : current_frame_;
}
```
I modified this to always return the first frame of the video after decoding. I expected that the canvas would always render the first frame of the video, but I found that the behavior was not what I expected.
2. Is there any documentation that I can learn more about VideoImageReaderImageBacking and VideoSurfaceTextureImageBacking?
Why do I have this question?
I found that if I don't adjust the code of webgl, I still keep the original way of calling it. Then I changed the default implementation of AndroidVideoImageBacking from VideoImageReaderImageBacking to VideoSurfaceTextureImageBacking and found that the problem of video tag playback lag or rollback was also solved.
3. Is there more documentation that can help me get familiar with Chromium's gpu-related mechanisms on Android?
Articles I have read:
https://docs.google.com/document/d/12qYPeN819JkdNGbPcKBA0rfPXSOIE3aIaQVrAZ4I1lM/edit?pli=1#heading=h.h8qur11p2eifhttps://chromium.googlesource.com/chromium/src.git/+/master/docs/design/gpu_synchronization.mdThank you for your help and I hope you work well.