Hi all,
As Andres mentioned, I’m currently working on making Pepper use the VideoDecoder (VD) interface over Mojo instead of the legacy VDA interface.
We need some feedback, but first let me give you some background about what happens today and what we're planning to do.
PepperVideoDecoderHost seems to be an intermediary between the Pepper plugin and the video decoder in the gpu process. Today, for hardware accelerated video decoding, it uses media::GpuVideoDecodeAcceleratorHost as the media::VideoDecodeAccelerator implementation [1]. In order to make decoding requests, the PepperVideoDecoderHost calls media::GpuVideoDecodeAcceleratorHost::Decode() [2]. Those requests are received in the gpu process by media::GpuVideoDecodeAccelerator that owns a media::VideoDecodeAccelerator. This media::VideoDecodeAccelerator is implemented by a platform-specific class. For instance, for VA-API on ChromeOS, we have media::VaapiVideoDecodeAccelerator. When media::VaapiVideoDecodeAccelerator receives a decoding request, it asks the client for buffers to decode onto by calling the client function ProvidePictureBuffers() [3]. The client (the Pepper code in this case) creates texture/mailbox pairs and sends the texture IDs to the video decoder. At least on ChromeOS, the ideal path in the GPU process is to then bind those textures to the native buffers used by the hardware decoder. That way, the hardware decoder decodes onto buffers used by Pepper without copies.
PepperVideoDecoderHost uses media::VideoDecoderShim [4] for fallback to software video decoding. media::VideoDecoderShim serves as an adapter between the VDA interface (old) and the VD interface (new) so our plan is to use it for hardware video decoding too.
In the new interface, the video decoder does not ask the client for buffers using ProvidePictureBuffers() as I mentioned above. Instead, the video decoder in the gpu process manages its own buffers. The VideoDecoderShim asks the Pepper code to create textures so that when it gets a decoded YUV frame, it converts from YUV to RGB onto those textures [5]. This doesn't seem too bad for software decoding.
However, for hardware video decoding, this buffer management framework complicates things a bit. For context (at least on ChromeOS), the hardware decoder sends us Mailbox-backed NV12 frames. These NV12 frames are actually backed by a single Mailbox because on ChromeOS, we can sample from NV12 buffers as if they were RGBA textures. We have a couple of alternatives:
1. We can continue asking the Pepper code to create RGBA textures. Then, we do a copy from the NV12 frame mailboxes to the Pepper RGBA textures using RasterInterface::CopySubTexture()[6].
2. Don’t request textures from the Pepper code. Instead, when we receive an NV12 Mailbox frame from the decoder, we can get a texture from it and give it to the Pepper code. For that we need to use RasterInterface::CreateAndConsumeForGpuRaster() [7] which is only implemented by RasterImplementationGLES [8].
Option #1 is the easiest (in theory) but it represents a regression from what we do today: instead of sampling from the NV12 buffers directly (and doing the RGB conversion implicitly at that point), we are doing a copy-conversion from NV12 to RGBA which may be a problem in terms of bandwidth and memory usage.
We believe option #2 is the best option, but it’s a bit more complicated to implement. Before proceeding, we would like to make sure you don’t see any fundamental issues with this option. For instance, we would need to make sure that RasterImplementationGLES::CreateAndConsumeForGpuRaster [8] is not part of the GL code you are trying to remove.
In principle, since Pepper is on its way out, we could first try option #1, and if we don't see a significant regression with respect to tip-of-tree, we could just stick with it. We don't know if that would work for all platforms though.
Please, let us know what you think. Thanks!
[1]
https://source.chromium.org/chromium/chromium/src/+/main:content/renderer/pepper/pepper_video_decoder_host.cc;l=164;drc=0c0b242b9475066635cf3e5e8a9ea074199d261d[2]
https://source.chromium.org/chromium/chromium/src/+/main:content/renderer/pepper/pepper_video_decoder_host.cc;l=262;drc=0c0b242b9475066635cf3e5e8a9ea074199d261d[3]
https://source.chromium.org/chromium/chromium/src/+/main:media/gpu/vaapi/vaapi_video_decode_accelerator.cc;l=650;drc=0b1b357a2fe097c9d23e453a0a5c5680c712b287[4]
https://source.chromium.org/chromium/chromium/src/+/main:content/renderer/pepper/video_decoder_shim.h;l=34-38;drc=3bfd3ba3af617152dfee61d03e93a773ddd3443b[5]
https://source.chromium.org/chromium/chromium/src/+/main:content/renderer/pepper/video_decoder_shim.cc;l=519-520;drc=a8afec221e6eac25a83c8a0db5909e88402b3d1c[6]
https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/client/raster_interface.h;l=51;drc=75425ebb5303c7bb416b2261e9b27114ec903d3f[7]
https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/client/raster_interface.h;l=171;drc=75425ebb5303c7bb416b2261e9b27114ec903d3f[8]
https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/client/raster_implementation_gles.cc;l=396;drc=75425ebb5303c7bb416b2261e9b27114ec903d3fPilar