910e62b5创建于 1月15日历史提交
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_GPU_CHROMEOS_NATIVE_PIXMAP_FRAME_RESOURCE_H_
#define MEDIA_GPU_CHROMEOS_NATIVE_PIXMAP_FRAME_RESOURCE_H_

#include <optional>

#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/types/pass_key.h"
#include "media/base/video_frame_layout.h"
#include "media/base/video_frame_metadata.h"
#include "media/gpu/chromeos/frame_resource.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/linux/native_pixmap_dmabuf.h"

namespace media {

// Implements a FrameResource that is backed by a gfx::NativePixmapDmaBuf. The
// frame's pixel content is only accessible by mapping the frame using a
// GenericDmaBufVideoFrameMapper. IsMappable() returns false and all data
// accessors return nullptr.
class NativePixmapFrameResource : public FrameResource {
 public:
  // The underlying NativePixmap is constructed from `handle`.
  NativePixmapFrameResource(base::PassKey<NativePixmapFrameResource>,
                            const media::VideoFrameLayout& layout,
                            const gfx::Rect& visible_rect,
                            const gfx::Size& natural_size,
                            base::TimeDelta timestamp,
                            viz::SharedImageFormat si_format,
                            const base::UnguessableToken& token,
                            std::optional<gfx::BufferUsage> buffer_usage,
                            gfx::NativePixmapHandle handle);
  NativePixmapFrameResource(
      base::PassKey<NativePixmapFrameResource>,
      const media::VideoFrameLayout& layout,
      const gfx::Rect& visible_rect,
      const gfx::Size& natural_size,
      base::TimeDelta timestamp,
      const base::UnguessableToken& token,
      std::optional<gfx::BufferUsage> buffer_usage,
      scoped_refptr<const gfx::NativePixmapDmaBuf> pixmap);
  NativePixmapFrameResource() = delete;
  NativePixmapFrameResource(const NativePixmapFrameResource&) = delete;
  NativePixmapFrameResource& operator=(const NativePixmapFrameResource&) =
      delete;

  // Creates a NativePixmapFrameResource that assumes ownership of |dmabuf_fds|.
  static scoped_refptr<NativePixmapFrameResource> Create(
      const media::VideoFrameLayout& layout,
      const gfx::Rect& visible_rect,
      const gfx::Size& natural_size,
      std::vector<base::ScopedFD> dmabuf_fds,
      base::TimeDelta timestamp);

  // Uses MiniGBM to allocate a NativePixmapFrameResource.
  static scoped_refptr<NativePixmapFrameResource> Create(
      media::VideoPixelFormat pixel_format,
      const gfx::Size& coded_size,
      const gfx::Rect& visible_rect,
      const gfx::Size& natural_size,
      base::TimeDelta timestamp,
      gfx::BufferUsage buffer_usage);

  // Creates a NativePixmapFrameResource from a NativePixmapDmaBuf.
  static scoped_refptr<NativePixmapFrameResource> Create(
      const gfx::Rect& visible_rect,
      const gfx::Size& natural_size,
      base::TimeDelta timestamp,
      gfx::BufferUsage buffer_usage,
      scoped_refptr<const gfx::NativePixmapDmaBuf> pixmap);

  // FrameResource implementation.
  const NativePixmapFrameResource* AsNativePixmapFrameResource() const override;

  // IsMappable() returns false. There is no direct data access to the buffers
  // without use of a GenericVideoFrameMapper.
  bool IsMappable() const override;
  const uint8_t* data(size_t plane) const override;
  uint8_t* writable_data(size_t plane) override;
  const uint8_t* visible_data(size_t plane) const override;
  uint8_t* GetWritableVisibleData(size_t plane) override;
  size_t NumDmabufFds() const override;
  int GetDmabufFd(size_t i) const override;
  scoped_refptr<const gfx::NativePixmapDmaBuf> GetNativePixmapDmaBuf()
      const override;
  // CreateGpuMemoryBufferHandle() will duplicate file descriptors to make a
  // gfx::GpuMemoryBufferHandle.
  gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferHandle() const override;
  // Always returns nullptr.
  std::unique_ptr<VideoFrame::ScopedMapping> MapGMBOrSharedImage()
      const override;
  const VideoFrameLayout& layout() const override;
  VideoPixelFormat format() const override;
  int stride(size_t plane) const override;
  VideoFrame::StorageType storage_type() const override;
  int row_bytes(size_t plane) const override;
  const gfx::Size& coded_size() const override;
  const gfx::Rect& visible_rect() const override;
  const gfx::Size& natural_size() const override;
  const VideoFrameMetadata& metadata() const override;
  VideoFrameMetadata& metadata() override;
  void set_metadata(const VideoFrameMetadata& metadata) override;
  const base::UnguessableToken& tracking_token() const override;
  gfx::ColorSpace ColorSpace() const override;
  void set_color_space(const gfx::ColorSpace& color_space) override;
  const std::optional<gfx::HDRMetadata>& hdr_metadata() const override;
  void set_hdr_metadata(
      const std::optional<gfx::HDRMetadata>& hdr_metadata) override;
  base::TimeDelta timestamp() const override;
  void set_timestamp(base::TimeDelta timestamp) override;
  void AddDestructionObserver(base::OnceClosure callback) override;
  scoped_refptr<FrameResource> CreateWrappingFrame(
      const gfx::Rect& visible_rect,
      const gfx::Size& natural_size) override;
  std::string AsHumanReadableString() const override;
  // Always returns empty handle.
  gfx::GpuMemoryBufferHandle GetGpuMemoryBufferHandleForTesting()
      const override;

  // CreateDmabufVideoFrame() is used to create a VideoFrame from the underlying
  // NativePixmap. The DMABuf FDs are duplicated and a VideoFrame with storage
  // type STORAGE_DMABUFS is created.
  scoped_refptr<VideoFrame> CreateDmabufVideoFrame() const;

  // CreateMappableVideoFrame() is used to create a VideoFrame from the
  // underlying NativePixmap. The DMABuf FDs are duplicated and a VideoFrame
  // with storage type STORAGE_GPU_MEMORY_BUFFER is created.
  scoped_refptr<VideoFrame> CreateMappableVideoFrame(
      gpu::SharedImageInterface* sii) const;

 private:
  ~NativePixmapFrameResource() override;

  // |pixmap_| is the underlying NativePixmap. It is is set by the constructors.
  const scoped_refptr<const gfx::NativePixmapDmaBuf> pixmap_;

  // |buffer_usage_| affects how a buffer can be used. It is only set if it was
  // provided by the caller of Create(), or if the NativePixmap was allocated by
  // MiniGBM. If this not set, then a CreateVideoFrame() should not be used to
  // create a STORAGE_GPU_MEMORY_BUFFER VideoFrame.
  const std::optional<gfx::BufferUsage> buffer_usage_;

  // VideoFrameLayout (includes format, coded_size, and strides). Per-plane
  // metadata is redundant with NativePixmapDmabuf::planes. Factory functions
  // ensure consistency between |layout_| and |pixmap_|.
  const media::VideoFrameLayout layout_;

  // Width, height, and offsets of the visible portion of the video frame. Must
  // be a subrect of |coded_size_|. Can be odd with respect to the sample
  // boundaries, e.g. for formats with subsampled chroma.
  const gfx::Rect visible_rect_;

  // Width and height of the visible portion of the video frame
  // (|visible_rect_.size()|) with aspect ratio taken into account.
  const gfx::Size natural_size_;

  media::VideoFrameMetadata metadata_;

  base::TimeDelta timestamp_;

  gfx::ColorSpace color_space_;
  std::optional<gfx::HDRMetadata> hdr_metadata_;

  // Callbacks are added by AddDestructionObserver(). It is unclear whether
  // guarding |done_callbacks_| is necessary. VideoFrame has a similar lock,
  // which is why |done_callbacks_lock_| was added to NativePixmapFrameResource.
  // VideoFrame's lock may not be necessary for the workflows where
  // NativePixmapFrameResource is used.
  // TODO(nhebert): Add a UMA to log concurrent access to
  // AddDestructionObserver().
  base::Lock done_callbacks_lock_;
  std::vector<base::OnceClosure> done_callbacks_
      GUARDED_BY(done_callbacks_lock_);
};

}  // namespace media
#endif  // MEDIA_GPU_CHROMEOS_NATIVE_PIXMAP_FRAME_RESOURCE_H_