0

gpu_arc_vd: Fix ARCVM video frame pool.

This CL is similar to the changes in crrev.com/c/3256071 and fixes
the allocation of video frames in the GpuArcVideoFramePool, which is
used by the new ARCVM video decoder backend. The associated video
frame pool seems to have been broken by the introduction of linear
buffer support in crrev.com/c/3221735.

Bug: b:189278506, b:203240043
Test: arc.VideoDecodeAccel.h264_vm

Change-Id: Ib8fcbd5e17cbc76f70d612cdc6f449371b82b52e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3313765
Reviewed-by: Andres Calderon Jaramillo <andrescj@chromium.org>
Commit-Queue: David Staessens <dstaessens@chromium.org>
Cr-Commit-Position: refs/heads/main@{#952834}
This commit is contained in:
David Staessens
2021-12-20 03:53:48 +00:00
committed by Chromium LUCI CQ
parent 67d3ac890f
commit e202a2f65a
2 changed files with 36 additions and 19 deletions
ash/components/arc/video_accelerator

@@ -11,9 +11,12 @@
#include "base/bind.h"
#include "base/posix/eintr_wrapper.h"
#include "build/build_config.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include "media/base/decode_status.h"
#include "media/base/format_utils.h"
#include "media/base/video_types.h"
#include "media/gpu/macros.h"
#include "ui/gfx/buffer_format_util.h"
#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
#include "media/gpu/chromeos/platform_video_frame_utils.h"
@@ -178,8 +181,9 @@ void GpuArcVideoFramePool::AddVideoFrame(mojom::VideoFramePtr video_frame,
return;
}
DmabufId dmabuf_id = media::DmabufVideoFramePool::GetDmabufId(*origin_frame);
auto it = dmabuf_to_video_frame_id_.emplace(dmabuf_id, video_frame->id);
const gfx::GpuMemoryBufferId buffer_id =
origin_frame->GetGpuMemoryBuffer()->GetId();
auto it = buffer_id_to_video_frame_id_.emplace(buffer_id, video_frame->id);
DCHECK(it.second);
// Wrap the video frame and attach a destruction observer so we're notified
@@ -227,9 +231,9 @@ void GpuArcVideoFramePool::RequestFrames(
absl::optional<int32_t> GpuArcVideoFramePool::GetVideoFrameId(
const media::VideoFrame* video_frame) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = dmabuf_to_video_frame_id_.find(
media::DmabufVideoFramePool::GetDmabufId(*video_frame));
return it != dmabuf_to_video_frame_id_.end()
auto it = buffer_id_to_video_frame_id_.find(
video_frame->GetGpuMemoryBuffer()->GetId());
return it != buffer_id_to_video_frame_id_.end()
? absl::optional<int32_t>(it->second)
: absl::nullopt;
}
@@ -239,10 +243,10 @@ void GpuArcVideoFramePool::OnFrameReleased(
DVLOGF(4);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = dmabuf_to_video_frame_id_.find(
media::DmabufVideoFramePool::GetDmabufId(*origin_frame));
DCHECK(it != dmabuf_to_video_frame_id_.end());
dmabuf_to_video_frame_id_.erase(it);
auto it = buffer_id_to_video_frame_id_.find(
origin_frame->GetGpuMemoryBuffer()->GetId());
DCHECK(it != buffer_id_to_video_frame_id_.end());
buffer_id_to_video_frame_id_.erase(it);
}
gfx::GpuMemoryBufferHandle GpuArcVideoFramePool::CreateGpuMemoryHandle(
@@ -282,19 +286,34 @@ gfx::GpuMemoryBufferHandle GpuArcVideoFramePool::CreateGpuMemoryHandle(
}
gmb_handle = std::move(handle).value();
}
gmb_handle.id = media::GetNextGpuMemoryBufferId();
return gmb_handle;
}
scoped_refptr<media::VideoFrame> GpuArcVideoFramePool::CreateVideoFrame(
gfx::GpuMemoryBufferHandle gmb_handle,
media::VideoPixelFormat pixel_format) const {
std::vector<base::ScopedFD> fds;
for (auto& plane : gmb_handle.native_pixmap_handle.planes) {
fds.push_back(std::move(plane.fd));
auto buffer_format = media::VideoPixelFormatToGfxBufferFormat(pixel_format);
CHECK(buffer_format);
// Usage is SCANOUT_VDA_WRITE because we are just wrapping the dmabuf in a
// GpuMemoryBuffer. This buffer is just for decoding purposes, so having
// the dmabufs mmapped is not necessary.
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
gpu::GpuMemoryBufferSupport().CreateGpuMemoryBufferImplFromHandle(
std::move(gmb_handle), coded_size_, *buffer_format,
gfx::BufferUsage::SCANOUT_VDA_WRITE, base::NullCallback());
if (!gpu_memory_buffer) {
VLOGF(1) << "Failed to create GpuMemoryBuffer. format: "
<< gfx::BufferFormatToString(*buffer_format)
<< ", coded_size: " << coded_size_.ToString();
return nullptr;
}
return media::VideoFrame::WrapExternalDmabufs(
*video_frame_layout_, gfx::Rect(coded_size_), coded_size_, std::move(fds),
base::TimeDelta());
const gpu::MailboxHolder mailbox_holder[media::VideoFrame::kMaxPlanes] = {};
return media::VideoFrame::WrapExternalGpuMemoryBuffer(
gfx::Rect(coded_size_), coded_size_, std::move(gpu_memory_buffer),
mailbox_holder, base::NullCallback(), base::TimeDelta());
}
} // namespace arc

@@ -76,8 +76,6 @@ class GpuArcVideoFramePool : public mojom::VideoFramePool,
base::WeakPtr<GpuArcVideoFramePool> WeakThis() { return weak_this_; }
private:
using DmabufId = media::DmabufVideoFramePool::DmabufId;
// Create a GPU memory handle from the specified |fd|.
gfx::GpuMemoryBufferHandle CreateGpuMemoryHandle(
base::ScopedFD fd,
@@ -111,8 +109,8 @@ class GpuArcVideoFramePool : public mojom::VideoFramePool,
// The current video frame layout.
absl::optional<media::VideoFrameLayout> video_frame_layout_;
// Map of video frame DmabufIds to the associated video frame ids.
std::map<DmabufId, int32_t> dmabuf_to_video_frame_id_;
// Map of video frame buffer ids to the associated video frame ids.
std::map<gfx::GpuMemoryBufferId, int32_t> buffer_id_to_video_frame_id_;
// The protected buffer manager, used when decoding an encrypted video.
scoped_refptr<ProtectedBufferManager> protected_buffer_manager_;