Decoded video frames should own their planar YUV data and color space
directly. Keeping that storage behind ImmutableBitmap gave a
still-image abstraction media-specific behavior and made calls like
bitmap() potentially allocate and convert a whole video frame.
Move YUV ownership into Media::VideoFrame, where the lifetime naturally
follows media playback, and remove the YUV-backed mode from
ImmutableBitmap. This commit intentionally keeps the visible Web paint
path on ExternalContentSource by converting the current frame back to
an ImmutableBitmap where Web still expects one.
Callers that need pixels now ask the frame to convert explicitly. That
preserves behavior for canvas and bitmap consumers while making the
expensive YUV-to-pixel path visible at the call site instead of
hiding it behind ImmutableBitmap::bitmap().
This is a small prerequisite for moving decoded YUV frames from
ImmutableBitmap into Media::VideoFrame. Once the frame owns the planes
directly, CPU consumers and the Skia upload path will share the same
YUVData object.
Those consumers need different representations. Skia expects high bit
depth YUVA pixmaps to be full-range 16-bit samples, while CPU conversion
paths must see the decoder-native samples and the original bit depth.
Keep YUVData in decoder-native form, and make the Skia expansion a
temporary copy owned by SkYUVAPixmaps. Add a regression test that checks
10-bit pixmaps are expanded for Skia without mutating the source planes
or changing YUVData::to_bitmap() output.
Using the Rust yuv crate, eagerly convert from YUV to RGBA on the CPU
when a GPU context is unavailable.
Time spent converting an 8-bit YUV frame with this crate is better than
libyuv on ARM by about 20%, and on x86 with AVX2, it achieves similar
numbers to libyuv.
Storing these was pointless, since they're only used briefly to provide
the info needed to upload the buffers to the GPU.
For BT.2020 coefficients, we can just say that the bit depth is 16 bits
since we're always bit replicating to that for Skia's shaders.
This saves us from having our own color conversion code, which was
taking up a fair amount of time in VideoDataProvider. With this change,
we should be able to play high resolution videos without interruptions
on machines where the CPU can keep up with decoding.
In order to make this change, ImmutableBitmap is now able to be
constructed with YUV data instead of an RBG bitmap. It holds onto a
YUVData instance that stores the buffers of image data, since Skia
itself doesn't take ownership of them.
In order to support greater than 8 bits of color depth, we normalize
the 10- or 12-bit color values into a 16-bit range.