From f1e34832b84798d7665d2aad9a5b3f33cbe5a274 Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Thu, 29 Jun 2017 13:39:20 +0000 Subject: [PATCH] Revert "VideoFrameBuffer: Remove deprecated functions" This reverts commit 428c9e218538278e6b0db42d1b734431bb432e1a. Reason for revert: Breaks Chromium WebRTC FYI on Mac Builder. http://build.chromium.org/p/chromium.webrtc.fyi/builders/Mac%20Builder/builds/25788 Original change's description: > VideoFrameBuffer: Remove deprecated functions > > Bug: webrtc:7632 > Change-Id: I06f97bacd51f94d1f90b5286cc39e06a1697bb9b > Reviewed-on: https://chromium-review.googlesource.com/535479 > Commit-Queue: Magnus Jedvert > Reviewed-by: Niels Moller > Cr-Commit-Position: refs/heads/master@{#18832} TBR=magjed@webrtc.org,nisse@webrtc.org Change-Id: I2e6617420746bba3e4637019d3bce03be12a4643 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:7632 Reviewed-on: https://chromium-review.googlesource.com/555550 Reviewed-by: Magnus Jedvert Commit-Queue: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#18834} --- webrtc/api/video/video_frame_buffer.cc | 83 ++++++++++++++++++- webrtc/api/video/video_frame_buffer.h | 36 ++++++-- .../common_video/include/video_frame_buffer.h | 26 ++++++ webrtc/common_video/video_frame_buffer.cc | 51 ++++++++++++ 4 files changed, 186 insertions(+), 10 deletions(-) diff --git a/webrtc/api/video/video_frame_buffer.cc b/webrtc/api/video/video_frame_buffer.cc index 057064d555..3fc442b217 100644 --- a/webrtc/api/video/video_frame_buffer.cc +++ b/webrtc/api/video/video_frame_buffer.cc @@ -16,15 +16,94 @@ namespace webrtc { +namespace { + +// TODO(magjed): Remove this class. It is only used for providing a default +// implementation of ToI420() until external clients are updated. ToI420() will +// then be made pure virtual. This adapter adapts a VideoFrameBuffer (which is +// expected to be in I420 format) to I420BufferInterface. The reason this is +// needed is because of the return type mismatch in NativeToI420Buffer (returns +// VideoFrameBuffer) vs ToI420 (returns I420BufferInterface). +class I420InterfaceAdapter : public I420BufferInterface { + public: + explicit I420InterfaceAdapter(const VideoFrameBuffer* buffer) + : buffer_(buffer) {} + + int width() const override { return buffer_->width(); } + int height() const override { return buffer_->height(); } + + const uint8_t* DataY() const override { return buffer_->DataY(); } + const uint8_t* DataU() const override { return buffer_->DataU(); } + const uint8_t* DataV() const override { return buffer_->DataV(); } + + int StrideY() const override { return buffer_->StrideY(); } + int StrideU() const override { return buffer_->StrideU(); } + int StrideV() const override { return buffer_->StrideV(); } + + private: + rtc::scoped_refptr buffer_; +}; + +} // namespace + +// TODO(magjed): The default implementations in VideoFrameBuffer are provided in +// order to support the deprecated interface until external clients are updated. +// Remove once done. +VideoFrameBuffer::Type VideoFrameBuffer::type() const { + return native_handle() ? Type::kNative : Type::kI420; +} + +const uint8_t* VideoFrameBuffer::DataY() const { + return GetI420()->DataY(); +} + +const uint8_t* VideoFrameBuffer::DataU() const { + return GetI420()->DataU(); +} + +const uint8_t* VideoFrameBuffer::DataV() const { + return GetI420()->DataV(); +} + +// Returns the number of bytes between successive rows for a given plane. +int VideoFrameBuffer::StrideY() const { + return GetI420()->StrideY(); +} + +int VideoFrameBuffer::StrideU() const { + return GetI420()->StrideU(); +} + +int VideoFrameBuffer::StrideV() const { + return GetI420()->StrideV(); +} + +void* VideoFrameBuffer::native_handle() const { + RTC_DCHECK(type() != Type::kNative); + return nullptr; +} + +rtc::scoped_refptr VideoFrameBuffer::NativeToI420Buffer() { + return ToI420(); +} + +rtc::scoped_refptr VideoFrameBuffer::ToI420() { + return new rtc::RefCountedObject(NativeToI420Buffer()); +} + rtc::scoped_refptr VideoFrameBuffer::GetI420() { RTC_CHECK(type() == Type::kI420); - return static_cast(this); + // TODO(magjed): static_cast to I420BufferInterface instead once external + // clients are updated. + return new rtc::RefCountedObject(this); } rtc::scoped_refptr VideoFrameBuffer::GetI420() const { RTC_CHECK(type() == Type::kI420); - return static_cast(this); + // TODO(magjed): static_cast to I420BufferInterface instead once external + // clients are updated. + return new rtc::RefCountedObject(this); } I444BufferInterface* VideoFrameBuffer::GetI444() { diff --git a/webrtc/api/video/video_frame_buffer.h b/webrtc/api/video/video_frame_buffer.h index d8f3e5a2c7..fa711d85e1 100644 --- a/webrtc/api/video/video_frame_buffer.h +++ b/webrtc/api/video/video_frame_buffer.h @@ -48,7 +48,7 @@ class VideoFrameBuffer : public rtc::RefCountInterface { }; // This function specifies in what pixel format the data is stored in. - virtual Type type() const = 0; + virtual Type type() const; // The resolution of the frame in pixels. For formats where some planes are // subsampled, this is the highest-resolution plane. @@ -59,7 +59,7 @@ class VideoFrameBuffer : public rtc::RefCountInterface { // in another format, a conversion will take place. All implementations must // provide a fallback to I420 for compatibility with e.g. the internal WebRTC // software encoders. - virtual rtc::scoped_refptr ToI420() = 0; + virtual rtc::scoped_refptr ToI420(); // These functions should only be called if type() is of the correct type. // Calling with a different type will result in a crash. @@ -70,6 +70,26 @@ class VideoFrameBuffer : public rtc::RefCountInterface { I444BufferInterface* GetI444(); const I444BufferInterface* GetI444() const; + // Deprecated - use ToI420() first instead. + // Returns pointer to the pixel data for a given plane. The memory is owned by + // the VideoFrameBuffer object and must not be freed by the caller. + virtual const uint8_t* DataY() const; + virtual const uint8_t* DataU() const; + virtual const uint8_t* DataV() const; + // Returns the number of bytes between successive rows for a given plane. + virtual int StrideY() const; + virtual int StrideU() const; + virtual int StrideV() const; + + // Deprecated - use type() to determine if the stored data is kNative, and + // then cast into the appropriate type. + // Return the handle of the underlying video frame. This is used when the + // frame is backed by a texture. + virtual void* native_handle() const; + + // Deprecated - use ToI420() instead. + virtual rtc::scoped_refptr NativeToI420Buffer(); + protected: ~VideoFrameBuffer() override {} }; @@ -82,14 +102,14 @@ class PlanarYuvBuffer : public VideoFrameBuffer { // Returns pointer to the pixel data for a given plane. The memory is owned by // the VideoFrameBuffer object and must not be freed by the caller. - virtual const uint8_t* DataY() const = 0; - virtual const uint8_t* DataU() const = 0; - virtual const uint8_t* DataV() const = 0; + const uint8_t* DataY() const override = 0; + const uint8_t* DataU() const override = 0; + const uint8_t* DataV() const override = 0; // Returns the number of bytes between successive rows for a given plane. - virtual int StrideY() const = 0; - virtual int StrideU() const = 0; - virtual int StrideV() const = 0; + int StrideY() const override = 0; + int StrideU() const override = 0; + int StrideV() const override = 0; protected: ~PlanarYuvBuffer() override {} diff --git a/webrtc/common_video/include/video_frame_buffer.h b/webrtc/common_video/include/video_frame_buffer.h index 8016c65521..e3835d3dbf 100644 --- a/webrtc/common_video/include/video_frame_buffer.h +++ b/webrtc/common_video/include/video_frame_buffer.h @@ -19,6 +19,32 @@ namespace webrtc { +// Base class for native-handle buffer is a wrapper around a |native_handle|. +// This is used for convenience as most native-handle implementations can share +// many VideoFrame implementations, but need to implement a few others (such +// as their own destructors or conversion methods back to software I420). +class NativeHandleBuffer : public VideoFrameBuffer { + public: + NativeHandleBuffer(void* native_handle, int width, int height); + + Type type() const override; + int width() const override; + int height() const override; + const uint8_t* DataY() const override; + const uint8_t* DataU() const override; + const uint8_t* DataV() const override; + int StrideY() const override; + int StrideU() const override; + int StrideV() const override; + + void* native_handle() const override; + + protected: + void* native_handle_; + const int width_; + const int height_; +}; + // Deprecated. Please use WrapI420Buffer(...) instead. class WrappedI420Buffer : public I420BufferInterface { public: diff --git a/webrtc/common_video/video_frame_buffer.cc b/webrtc/common_video/video_frame_buffer.cc index 3c4d2a0a9f..7ebff44507 100644 --- a/webrtc/common_video/video_frame_buffer.cc +++ b/webrtc/common_video/video_frame_buffer.cc @@ -21,6 +21,57 @@ namespace webrtc { +NativeHandleBuffer::NativeHandleBuffer(void* native_handle, + int width, + int height) + : native_handle_(native_handle), width_(width), height_(height) { + RTC_DCHECK(native_handle != nullptr); + RTC_DCHECK_GT(width, 0); + RTC_DCHECK_GT(height, 0); +} + +VideoFrameBuffer::Type NativeHandleBuffer::type() const { + return Type::kNative; +} + +int NativeHandleBuffer::width() const { + return width_; +} + +int NativeHandleBuffer::height() const { + return height_; +} + +const uint8_t* NativeHandleBuffer::DataY() const { + RTC_NOTREACHED(); // Should not be called. + return nullptr; +} +const uint8_t* NativeHandleBuffer::DataU() const { + RTC_NOTREACHED(); // Should not be called. + return nullptr; +} +const uint8_t* NativeHandleBuffer::DataV() const { + RTC_NOTREACHED(); // Should not be called. + return nullptr; +} + +int NativeHandleBuffer::StrideY() const { + RTC_NOTREACHED(); // Should not be called. + return 0; +} +int NativeHandleBuffer::StrideU() const { + RTC_NOTREACHED(); // Should not be called. + return 0; +} +int NativeHandleBuffer::StrideV() const { + RTC_NOTREACHED(); // Should not be called. + return 0; +} + +void* NativeHandleBuffer::native_handle() const { + return native_handle_; +} + WrappedI420Buffer::WrappedI420Buffer(int width, int height, const uint8_t* y_plane,