#ifndef MEDIA_RENDERERS_VIDEO_RESOURCE_UPDATER_H_
#define MEDIA_RENDERERS_VIDEO_RESOURCE_UPDATER_H_
#include <stddef.h>
#include <stdint.h>
#include <array>
#include <memory>
#include <optional>
#include <vector>
#include "base/containers/heap_array.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/unguessable_token.h"
#include "components/viz/common/resources/release_callback.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "media/base/media_export.h"
#include "media/base/video_frame.h"
#include "ui/gfx/geometry/size.h"
namespace gfx {
class Rect;
class Transform;
class MaskFilterInfo;
}
namespace viz {
class ClientResourceProvider;
class RasterContextProvider;
class CompositorRenderPass;
}
namespace gpu {
class SharedImageInterface;
}
namespace media {
class PaintCanvasVideoRenderer;
enum class VideoFrameResourceType {
NONE,
RGB,
RGBA_PREMULTIPLIED,
VIDEO_HOLE,
};
class MEDIA_EXPORT VideoFrameExternalResource {
public:
VideoFrameResourceType type = VideoFrameResourceType::NONE;
viz::TransferableResource resource;
viz::ReleaseCallback release_callback;
VideoFrameExternalResource();
VideoFrameExternalResource(VideoFrameExternalResource&& other);
VideoFrameExternalResource& operator=(VideoFrameExternalResource&& other);
~VideoFrameExternalResource();
};
class MEDIA_EXPORT VideoResourceUpdater
: public base::trace_event::MemoryDumpProvider {
public:
VideoResourceUpdater(
viz::RasterContextProvider* context_provider,
viz::ClientResourceProvider* resource_provider,
scoped_refptr<gpu::SharedImageInterface> shared_image_interface,
bool use_gpu_memory_buffer_resources,
int max_resource_size);
VideoResourceUpdater(const VideoResourceUpdater&) = delete;
VideoResourceUpdater& operator=(const VideoResourceUpdater&) = delete;
~VideoResourceUpdater() override;
void ObtainFrameResource(scoped_refptr<VideoFrame> video_frame);
void ReleaseFrameResource();
void AppendQuad(viz::CompositorRenderPass* render_pass,
scoped_refptr<VideoFrame> frame,
gfx::Transform transform,
gfx::Rect quad_rect,
gfx::Rect visible_quad_rect,
const gfx::MaskFilterInfo& mask_filter_info,
std::optional<gfx::Rect> clip_rect,
bool context_opaque,
float draw_opacity,
int sorting_context_id);
void ClearFrameResources();
VideoFrameExternalResource CreateExternalResourceFromVideoFrame(
scoped_refptr<VideoFrame> video_frame);
viz::SharedImageFormat YuvSharedImageFormat(int bits_per_channel);
gpu::SharedImageInterface* shared_image_interface() const;
viz::ResourceId GetFrameResourceIdForTesting() const;
private:
class FrameResource;
bool software_compositor() const { return context_provider_ == nullptr; }
bool ReallocateUploadPixels(size_t needed_size, size_t plane);
FrameResource* RecycleOrAllocateResource(const gfx::Size& resource_size,
viz::SharedImageFormat si_format,
const gfx::ColorSpace& color_space,
SkAlphaType alpha_type,
VideoFrame::ID unique_id);
FrameResource* AllocateResource(const gfx::Size& size,
viz::SharedImageFormat format,
const gfx::ColorSpace& color_space,
SkAlphaType alpha_type);
VideoFrameExternalResource CopyHardwareResource(VideoFrame* video_frame);
VideoFrameExternalResource CreateForHardwareFrame(
scoped_refptr<VideoFrame> video_frame);
viz::SharedImageFormat GetSoftwareOutputFormat(
VideoPixelFormat input_frame_format,
int bits_per_channel);
void TransferRGBPixelsToPaintCanvas(scoped_refptr<VideoFrame> video_frame,
FrameResource* frame_resource);
bool WriteRGBPixelsToTexture(scoped_refptr<VideoFrame> video_frame,
FrameResource* frame_resource);
bool WriteYUVPixelsForAllPlanesToTexture(
scoped_refptr<VideoFrame> video_frame,
FrameResource* resource,
size_t bits_per_channel);
VideoFrameExternalResource CreateForSoftwareFrame(
scoped_refptr<VideoFrame> video_frame);
gpu::raster::RasterInterface* RasterInterface();
void RecycleResource(uint32_t resource_id,
const gpu::SyncToken& sync_token,
bool lost_resource);
void ReturnTexture(scoped_refptr<VideoFrame> video_frame,
const gpu::SyncToken& original_release_token,
const gpu::SyncToken& new_release_token,
bool lost_resource);
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
const raw_ptr<viz::RasterContextProvider> context_provider_;
scoped_refptr<gpu::SharedImageInterface> shared_image_interface_;
const raw_ptr<viz::ClientResourceProvider, DanglingUntriaged>
resource_provider_;
const bool use_gpu_memory_buffer_resources_;
const int max_resource_size_;
const int tracing_id_;
std::unique_ptr<PaintCanvasVideoRenderer> video_renderer_;
uint32_t next_plane_resource_id_ = 1;
using PlaneData = base::HeapArray<uint8_t, base::UncheckedFreeDeleter>;
std::array<PlaneData, SkYUVAInfo::kMaxPlanes> upload_pixels_ = {};
VideoFrameResourceType frame_resource_type_;
viz::ResourceId frame_resource_id_;
base::UnguessableToken overlay_plane_id_;
std::vector<std::unique_ptr<FrameResource>> all_resources_;
base::WeakPtrFactory<VideoResourceUpdater> weak_ptr_factory_{this};
};
}
#endif