1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_RENDERERS_VIDEO_FRAME_YUV_MAILBOXES_HOLDER_H_
6 #define MEDIA_RENDERERS_VIDEO_FRAME_YUV_MAILBOXES_HOLDER_H_
8 #include "media/base/media_export.h"
9 #include "media/base/video_frame.h"
10 #include "third_party/skia/include/core/SkRefCnt.h"
11 #include "third_party/skia/include/core/SkYUVAInfo.h"
12 #include "third_party/skia/include/gpu/GrYUVABackendTextures.h"
13 #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
20 class RasterContextProvider;
25 class MEDIA_EXPORT VideoFrameYUVMailboxesHolder {
27 VideoFrameYUVMailboxesHolder();
28 ~VideoFrameYUVMailboxesHolder();
30 void ReleaseCachedData();
31 void ReleaseTextures();
33 // Extracts shared image information if |video_frame| is texture backed or
34 // creates new shared images and uploads YUV data to GPU if |video_frame| is
35 // mappable. This function can be called repeatedly to re-use shared images in
36 // the case of CPU backed VideoFrames. The planes are returned in |mailboxes|.
37 void VideoFrameToMailboxes(
38 const VideoFrame* video_frame,
39 viz::RasterContextProvider* raster_context_provider,
40 gpu::Mailbox mailboxes[SkYUVAInfo::kMaxPlanes],
41 bool allow_multiplanar_for_upload);
43 // Returns a YUV SkImage for the specified video frame. If
44 // `reinterpret_color_space` is non-nullptr, then the SkImage will be
45 // reinterpreted to be in the specified value. Otherwise, it will be
46 // in `video_frame`'s color space.
47 sk_sp<SkImage> VideoFrameToSkImage(
48 const VideoFrame* video_frame,
49 viz::RasterContextProvider* raster_context_provider,
50 sk_sp<SkColorSpace> reinterpret_color_space);
52 // Creates SkSurfaces for each plane for the specified video frame. Returns
53 // true only if surfaces for all planes were created.
54 bool VideoFrameToPlaneSkSurfaces(
55 const VideoFrame* video_frame,
56 viz::RasterContextProvider* raster_context_provider,
57 sk_sp<SkSurface> surfaces[SkYUVAInfo::kMaxPlanes]);
59 const SkYUVAInfo& yuva_info() const { return yuva_info_; }
61 // Utility to convert a media pixel format to SkYUVAInfo.
62 static std::tuple<SkYUVAInfo::PlaneConfig, SkYUVAInfo::Subsampling>
63 VideoPixelFormatToSkiaValues(VideoPixelFormat video_format);
65 // Utility to populate a SkYUVAInfo from a video frame.
66 static SkYUVAInfo VideoFrameGetSkYUVAInfo(const VideoFrame* video_frame);
69 static constexpr size_t kMaxPlanes =
70 static_cast<size_t>(SkYUVAInfo::kMaxPlanes);
72 // Like VideoFrameToMailboxes but imports the textures from the mailboxes and
73 // returns the planes as a set of YUVA GrBackendTextures. If |for_surface| is
74 // true, then select color types and pixel formats that are renderable as
76 GrYUVABackendTextures VideoFrameToSkiaTextures(
77 const VideoFrame* video_frame,
78 viz::RasterContextProvider* raster_context_provider,
81 void ImportTextures(bool for_surface);
83 scoped_refptr<viz::RasterContextProvider> provider_;
84 bool imported_textures_ = false;
85 bool created_shared_images_ = false;
86 gfx::Size cached_video_size_;
87 gfx::ColorSpace cached_video_color_space_;
89 // The properties of the most recently received video frame.
90 size_t num_planes_ = 0;
91 SkYUVAInfo yuva_info_;
92 SkISize plane_sizes_[SkYUVAInfo::kMaxPlanes];
94 // Populated by VideoFrameToMailboxes.
95 std::array<gpu::MailboxHolder, kMaxPlanes> holders_;
97 // Populated by ImportTextures.
98 struct YUVPlaneTextureInfo {
99 GrGLTextureInfo texture = {0, 0};
100 bool is_shared_image = false;
102 std::array<YUVPlaneTextureInfo, kMaxPlanes> textures_;
107 #endif // MEDIA_RENDERERS_VIDEO_FRAME_YUV_MAILBOXES_HOLDER_H_