Chromium Code Reviews| Index: media/base/video_frame.cc |
| diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc |
| index c837159958739edb5d4d3708d1dab8af0bc45562..805080667c81e0defce98e4825d08ff2af32db32 100644 |
| --- a/media/base/video_frame.cc |
| +++ b/media/base/video_frame.cc |
| @@ -138,16 +138,13 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( |
| // ourselves), we can pad the requested |coded_size| if necessary if the |
| // request does not line up on sample boundaries. |
| const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); |
| - DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); |
| + DCHECK(IsValidConfig(format, TEXTURE_NONE, new_coded_size, visible_rect, |
| + natural_size)); |
| + gpu::MailboxHolder mailboxes[kMaxPlanes]; |
| scoped_refptr<VideoFrame> frame( |
| - new VideoFrame(format, |
| - new_coded_size, |
| - visible_rect, |
| - natural_size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - timestamp, |
| - false)); |
| + new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| + mailboxes, TEXTURE_NONE, timestamp, false)); |
| frame->AllocateYUV(); |
| return frame; |
| } |
| @@ -188,6 +185,7 @@ std::string VideoFrame::FormatToString(VideoFrame::Format format) { |
| // static |
| bool VideoFrame::IsValidConfig(VideoFrame::Format format, |
| + VideoFrame::TextureFormat texture_format, |
| const gfx::Size& coded_size, |
| const gfx::Rect& visible_rect, |
| const gfx::Size& natural_size) { |
| @@ -212,6 +210,7 @@ bool VideoFrame::IsValidConfig(VideoFrame::Format format, |
| // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are |
| // allowed to skip the below check. |
| case VideoFrame::NATIVE_TEXTURE: |
| + return texture_format != VideoFrame::TEXTURE_NONE; |
| #if defined(VIDEO_HOLE) |
| case VideoFrame::HOLE: |
| #endif // defined(VIDEO_HOLE) |
| @@ -243,23 +242,43 @@ bool VideoFrame::IsValidConfig(VideoFrame::Format format, |
| // static |
| scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( |
| - scoped_ptr<gpu::MailboxHolder> mailbox_holder, |
| + const gpu::MailboxHolder& mailbox_holder, |
| const ReleaseMailboxCB& mailbox_holder_release_cb, |
| const gfx::Size& coded_size, |
| const gfx::Rect& visible_rect, |
| const gfx::Size& natural_size, |
| base::TimeDelta timestamp, |
| bool allow_overlay) { |
| - scoped_refptr<VideoFrame> frame(new VideoFrame(NATIVE_TEXTURE, |
| - coded_size, |
| - visible_rect, |
| - natural_size, |
| - mailbox_holder.Pass(), |
| - timestamp, |
| - false)); |
| - frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb; |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| + mailbox_holders[0] = mailbox_holder; |
|
reveman
2015/05/03 16:13:27
s/0/kARGBPlan/
Daniele Castagna
2015/05/04 15:00:15
Done.
|
| + scoped_refptr<VideoFrame> frame( |
| + new VideoFrame(NATIVE_TEXTURE, coded_size, visible_rect, natural_size, |
| + mailbox_holders, TEXTURE_RGBA, timestamp, false)); |
| + frame->mailbox_holders_release_cb_ = mailbox_holder_release_cb; |
| frame->allow_overlay_ = allow_overlay; |
| + return frame; |
| +} |
| +// static |
| +scoped_refptr<VideoFrame> VideoFrame::WrapYUVNativeTextures( |
| + const gpu::MailboxHolder& y_mailbox_holder, |
| + const gpu::MailboxHolder& u_mailbox_holder, |
| + const gpu::MailboxHolder& v_mailbox_holder, |
| + const ReleaseMailboxCB& mailbox_holder_release_cb, |
| + const gfx::Size& coded_size, |
| + const gfx::Rect& visible_rect, |
| + const gfx::Size& natural_size, |
| + base::TimeDelta timestamp, |
| + bool allow_overlay) { |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| + mailbox_holders[kYPlane] = y_mailbox_holder; |
| + mailbox_holders[kUPlane] = u_mailbox_holder; |
| + mailbox_holders[kVPlane] = v_mailbox_holder; |
| + scoped_refptr<VideoFrame> frame( |
| + new VideoFrame(NATIVE_TEXTURE, coded_size, visible_rect, natural_size, |
| + mailbox_holders, TEXTURE_YUV_R8R8R8, timestamp, false)); |
| + frame->mailbox_holders_release_cb_ = mailbox_holder_release_cb; |
| + frame->allow_overlay_ = allow_overlay; |
| return frame; |
| } |
| @@ -277,21 +296,18 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory( |
| const base::Closure& no_longer_needed_cb) { |
| const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); |
| - if (!IsValidConfig(format, new_coded_size, visible_rect, natural_size)) |
| + if (!IsValidConfig(format, TEXTURE_NONE, new_coded_size, visible_rect, |
| + natural_size)) |
| return NULL; |
| if (data_size < AllocationSize(format, new_coded_size)) |
| return NULL; |
| switch (format) { |
| case VideoFrame::I420: { |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| scoped_refptr<VideoFrame> frame( |
| - new VideoFrame(format, |
| - new_coded_size, |
| - visible_rect, |
| - natural_size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - timestamp, |
| - false)); |
| + new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| + mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| frame->shared_memory_handle_ = handle; |
| frame->shared_memory_offset_ = data_offset; |
| frame->strides_[kYPlane] = new_coded_size.width(); |
| @@ -324,16 +340,13 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( |
| base::TimeDelta timestamp, |
| const base::Closure& no_longer_needed_cb) { |
| const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); |
| - CHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); |
| + CHECK(IsValidConfig(format, TEXTURE_NONE, new_coded_size, visible_rect, |
| + natural_size)); |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| scoped_refptr<VideoFrame> frame( |
| - new VideoFrame(format, |
| - new_coded_size, |
| - visible_rect, |
| - natural_size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - timestamp, |
| - false)); |
| + new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| + mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| frame->strides_[kYPlane] = y_stride; |
| frame->strides_[kUPlane] = u_stride; |
| frame->strides_[kVPlane] = v_stride; |
| @@ -354,7 +367,8 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( |
| const std::vector<int> dmabuf_fds, |
| base::TimeDelta timestamp, |
| const base::Closure& no_longer_needed_cb) { |
| - if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) |
| + if (!IsValidConfig(format, TEXTURE_NONE, coded_size, visible_rect, |
| + natural_size)) |
| return NULL; |
| // TODO(posciak): This is not exactly correct, it's possible for one |
| @@ -364,14 +378,10 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( |
| return NULL; |
| } |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| scoped_refptr<VideoFrame> frame( |
| - new VideoFrame(format, |
| - coded_size, |
| - visible_rect, |
| - natural_size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - timestamp, |
| - false)); |
| + new VideoFrame(format, coded_size, visible_rect, natural_size, |
| + mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| for (size_t i = 0; i < dmabuf_fds.size(); ++i) { |
| int duped_fd = HANDLE_EINTR(dup(dmabuf_fds[i])); |
| @@ -421,17 +431,14 @@ scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer( |
| const gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer)); |
| const gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer)); |
| - if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) |
| + if (!IsValidConfig(format, TEXTURE_NONE, coded_size, visible_rect, |
| + natural_size)) |
| return NULL; |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| scoped_refptr<VideoFrame> frame( |
| - new VideoFrame(format, |
| - coded_size, |
| - visible_rect, |
| - natural_size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - timestamp, |
| - false)); |
| + new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| + mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| frame->cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); |
| return frame; |
| @@ -449,14 +456,11 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( |
| CHECK_NE(frame->format(), NATIVE_TEXTURE); |
| DCHECK(frame->visible_rect().Contains(visible_rect)); |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| scoped_refptr<VideoFrame> wrapped_frame( |
| - new VideoFrame(frame->format(), |
| - frame->coded_size(), |
| - visible_rect, |
| - natural_size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - frame->timestamp(), |
| - frame->end_of_stream())); |
| + new VideoFrame(frame->format(), frame->coded_size(), visible_rect, |
| + natural_size, mailbox_holders, TEXTURE_NONE, |
| + frame->timestamp(), frame->end_of_stream())); |
| for (size_t i = 0; i < NumPlanes(frame->format()); ++i) { |
| wrapped_frame->strides_[i] = frame->stride(i); |
| @@ -469,13 +473,10 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( |
| // static |
| scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() { |
| - return new VideoFrame(VideoFrame::UNKNOWN, |
| - gfx::Size(), |
| - gfx::Rect(), |
| - gfx::Size(), |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - kNoTimestamp(), |
| - true); |
| + gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| + return new VideoFrame(VideoFrame::UNKNOWN, gfx::Size(), gfx::Rect(), |
| + gfx::Size(), mailbox_holders, TEXTURE_NONE, |
| + kNoTimestamp(), true); |
| } |
| // static |
| @@ -521,15 +522,12 @@ scoped_refptr<VideoFrame> VideoFrame::CreateTransparentFrame( |
| // static |
| scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( |
| const gfx::Size& size) { |
| - DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size)); |
| - scoped_refptr<VideoFrame> frame( |
| - new VideoFrame(VideoFrame::HOLE, |
| - size, |
| - gfx::Rect(size), |
| - size, |
| - scoped_ptr<gpu::MailboxHolder>(), |
| - base::TimeDelta(), |
| - false)); |
| + DCHECK(IsValidConfig(VideoFrame::HOLE, TEXTURE_NONE, size, gfx::Rect(size), |
| + size)); |
| + scoped_refptr<VideoFrame> frame(new VideoFrame(VideoFrame::HOLE, size, |
| + gfx::Rect(size), size, |
| + nullptr, // mailbox holders |
| + base::TimeDelta(), false)); |
| return frame; |
| } |
| #endif // defined(VIDEO_HOLE) |
| @@ -562,6 +560,21 @@ size_t VideoFrame::NumPlanes(Format format) { |
| return 0; |
| } |
| +// static |
| +size_t VideoFrame::NumTextures(TextureFormat texture_format) { |
| + switch (texture_format) { |
| + case TEXTURE_RGBA: |
| + return 1; |
| + case TEXTURE_YUV_R8R8R8: |
| + return 3; |
| + case TEXTURE_NONE: |
| + NOTREACHED(); |
| + return 0; |
| + } |
| + |
| + NOTREACHED(); |
| + return 0; |
| +} |
| // static |
| size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { |
| @@ -664,28 +677,30 @@ VideoFrame::VideoFrame(VideoFrame::Format format, |
| const gfx::Size& coded_size, |
| const gfx::Rect& visible_rect, |
| const gfx::Size& natural_size, |
| - scoped_ptr<gpu::MailboxHolder> mailbox_holder, |
| + const gpu::MailboxHolder mailbox_holders[kMaxPlanes], |
| + VideoFrame::TextureFormat texture_format, |
| base::TimeDelta timestamp, |
| bool end_of_stream) |
| : format_(format), |
| + texture_format_(texture_format), |
| coded_size_(coded_size), |
| visible_rect_(visible_rect), |
| natural_size_(natural_size), |
| - mailbox_holder_(mailbox_holder.Pass()), |
| shared_memory_handle_(base::SharedMemory::NULLHandle()), |
| shared_memory_offset_(0), |
| timestamp_(timestamp), |
| release_sync_point_(0), |
| end_of_stream_(end_of_stream), |
| allow_overlay_(false) { |
| - DCHECK(IsValidConfig(format_, coded_size_, visible_rect_, natural_size_)); |
| - |
| + DCHECK(IsValidConfig(format_, texture_format_, coded_size_, visible_rect_, |
| + natural_size_)); |
| + memcpy(&mailbox_holders_, mailbox_holders, sizeof(mailbox_holders_)); |
| memset(&strides_, 0, sizeof(strides_)); |
| memset(&data_, 0, sizeof(data_)); |
| } |
| VideoFrame::~VideoFrame() { |
| - if (!mailbox_holder_release_cb_.is_null()) { |
| + if (!mailbox_holders_release_cb_.is_null()) { |
| uint32 release_sync_point; |
| { |
| // To ensure that changes to |release_sync_point_| are visible on this |
| @@ -693,7 +708,7 @@ VideoFrame::~VideoFrame() { |
| base::AutoLock locker(release_sync_point_lock_); |
| release_sync_point = release_sync_point_; |
| } |
| - base::ResetAndReturn(&mailbox_holder_release_cb_).Run(release_sync_point); |
| + base::ResetAndReturn(&mailbox_holders_release_cb_).Run(release_sync_point); |
| } |
| if (!no_longer_needed_cb_.is_null()) |
| base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
| @@ -771,9 +786,10 @@ uint8* VideoFrame::visible_data(size_t plane) { |
| static_cast<const VideoFrame*>(this)->visible_data(plane)); |
| } |
| -const gpu::MailboxHolder* VideoFrame::mailbox_holder() const { |
| +const gpu::MailboxHolder& VideoFrame::mailbox_holder(size_t texture) const { |
| DCHECK_EQ(format_, NATIVE_TEXTURE); |
| - return mailbox_holder_.get(); |
| + DCHECK_LT(texture, NumTextures(texture_format_)); |
| + return mailbox_holders_[texture]; |
| } |
| base::SharedMemoryHandle VideoFrame::shared_memory_handle() const { |
| @@ -788,7 +804,7 @@ void VideoFrame::UpdateReleaseSyncPoint(SyncPointClient* client) { |
| DCHECK_EQ(format_, NATIVE_TEXTURE); |
| base::AutoLock locker(release_sync_point_lock_); |
| // Must wait on the previous sync point before inserting a new sync point so |
| - // that |mailbox_holder_release_cb_| guarantees the previous sync point |
| + // that |mailbox_holders_release_cb_| guarantees the previous sync point |
| // occurred when it waits on |release_sync_point_|. |
| if (release_sync_point_) |
| client->WaitSyncPoint(release_sync_point_); |