Commit 779cda84 authored by Ricky Liang's avatar Ricky Liang Committed by Commit Bot

media: Allow wrapping VideoFrame backed by texture and GpuMemoryBuffer

This CL allows us to soft-apply cropping and scaling on opaque buffer
handles.  The wrapping frame retains no resource regarding the opaque
buffer handles and acts simply as a decorator to expose different
visible rectangle and natural size.  Any operation involving the opaque
buffer handles are relayed to the wrapped frame.

Bug: 982201
Change-Id: If51308c92adeb33d60627386545cadfe1f17edcd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1830243
Commit-Queue: Ricky Liang <jcliang@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#701490}
parent a4b38bf0
......@@ -621,9 +621,6 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame(
VideoPixelFormat format,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size) {
// Frames with textures need mailbox info propagated, and there's no support
// for that here yet, see http://crbug/362521.
CHECK(!frame->HasTextures());
DCHECK(frame->visible_rect().Contains(visible_rect));
// The following storage type should not be wrapped as the shared region
......@@ -910,16 +907,19 @@ bool VideoFrame::IsMappable() const {
}
bool VideoFrame::HasTextures() const {
return !mailbox_holders_[0].mailbox.IsZero();
return wrapped_frame_ ? wrapped_frame_->HasTextures()
: !mailbox_holders_[0].mailbox.IsZero();
}
size_t VideoFrame::NumTextures() const {
if (!HasTextures())
return 0;
const auto& mailbox_holders =
wrapped_frame_ ? wrapped_frame_->mailbox_holders_ : mailbox_holders_;
size_t i = 0;
for (; i < NumPlanes(format()); ++i) {
if (mailbox_holders_[i].mailbox.IsZero()) {
if (mailbox_holders[i].mailbox.IsZero()) {
return i;
}
}
......@@ -927,11 +927,13 @@ size_t VideoFrame::NumTextures() const {
}
bool VideoFrame::HasGpuMemoryBuffer() const {
return !!gpu_memory_buffer_;
return wrapped_frame_ ? wrapped_frame_->HasGpuMemoryBuffer()
: !!gpu_memory_buffer_;
}
gfx::GpuMemoryBuffer* VideoFrame::GetGpuMemoryBuffer() const {
return gpu_memory_buffer_.get();
return wrapped_frame_ ? wrapped_frame_->GetGpuMemoryBuffer()
: gpu_memory_buffer_.get();
}
gfx::ColorSpace VideoFrame::ColorSpace() const {
......@@ -974,7 +976,8 @@ const gpu::MailboxHolder&
VideoFrame::mailbox_holder(size_t texture_index) const {
DCHECK(HasTextures());
DCHECK(IsValidPlane(texture_index, format()));
return mailbox_holders_[texture_index];
return wrapped_frame_ ? wrapped_frame_->mailbox_holders_[texture_index]
: mailbox_holders_[texture_index];
}
#if defined(OS_LINUX)
......@@ -1004,11 +1007,16 @@ CVPixelBufferRef VideoFrame::CvPixelBuffer() const {
void VideoFrame::SetReleaseMailboxCB(ReleaseMailboxCB release_mailbox_cb) {
DCHECK(release_mailbox_cb);
DCHECK(!mailbox_holders_release_cb_);
// We don't relay SetReleaseMailboxCB to |wrapped_frame_| because the method
// is not thread safe. This method should only be called by the owner of
// |wrapped_frame_| directly.
DCHECK(!wrapped_frame_);
mailbox_holders_release_cb_ = std::move(release_mailbox_cb);
}
bool VideoFrame::HasReleaseMailboxCB() const {
return !!mailbox_holders_release_cb_;
return wrapped_frame_ ? wrapped_frame_->HasReleaseMailboxCB()
: !!mailbox_holders_release_cb_;
}
void VideoFrame::AddDestructionObserver(base::OnceClosure callback) {
......@@ -1018,6 +1026,9 @@ void VideoFrame::AddDestructionObserver(base::OnceClosure callback) {
gpu::SyncToken VideoFrame::UpdateReleaseSyncToken(SyncTokenClient* client) {
DCHECK(HasTextures());
if (wrapped_frame_) {
return wrapped_frame_->UpdateReleaseSyncToken(client);
}
base::AutoLock locker(release_sync_token_lock_);
// Must wait on the previous sync point before inserting a new sync point so
// that |mailbox_holders_release_cb_| guarantees the previous sync point
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment