Add support for I444 in VideoFrameBuffer
VideoFrameBuffer is currently hard coded to be either I420 or Native.
This CL makes VideoFrameBuffer more generic by moving the I420 specific
functions into their own class, and adds an enum tag that represents the
format and storage type of the buffer. Each buffer type is then
represented as a subclass. See webrtc/api/video/video_frame_buffer.h for
more info.
This CL also adds support for representing I444 in VideoFrameBuffer
using the new interface. Possible future buffer type candidates are
RGB and NV12.
BUG=webrtc:7632
TBR=stefan@webrtc.org
Review-Url: https://codereview.webrtc.org/2847383002
Cr-Commit-Position: refs/heads/master@{#18098}
diff --git a/webrtc/api/video/video_frame_buffer.h b/webrtc/api/video/video_frame_buffer.h
index c8c2e5d..6d0c991 100644
--- a/webrtc/api/video/video_frame_buffer.h
+++ b/webrtc/api/video/video_frame_buffer.h
@@ -18,38 +18,100 @@
namespace webrtc {
-// Interface of a simple frame buffer containing pixel data. This interface does
-// not contain any frame metadata such as rotation, timestamp, pixel_width, etc.
+class PlanarYuvBuffer;
+
+// Base class for frame buffers of different types of pixel format and storage.
+// The tag in type() indicates how the data is represented, and each type is
+// implemented as a subclass. To access the pixel data, call the appropriate
+// GetXXX() function, where XXX represents the type. There is also a function
+// ToI420() that returns a frame buffer in I420 format, converting from the
+// underlying representation if necessary. I420 is the most widely accepted
+// format and serves as a fallback for video sinks that can only handle I420,
+// e.g. the internal WebRTC software encoders. A special enum value 'kNative' is
+// provided for external clients to implement their own frame buffer
+// representations, e.g. as textures. The external client can produce such
+// native frame buffers from custom video sources, and then cast it back to the
+// correct subclass in custom video sinks. The purpose of this is to improve
+// performance by providing an optimized path without intermediate conversions.
+// Frame metadata such as rotation and timestamp are stored in
+// webrtc::VideoFrame, and not here.
class VideoFrameBuffer : public rtc::RefCountInterface {
public:
+ // New frame buffer types will be added conservatively when there is an
+ // opportunity to optimize the path between some pair of video source and
+ // video sink.
+ enum class Type {
+ kNative,
+ kI420,
+ kI444,
+ };
+
+ // This function specifies in what pixel format the data is stored in.
+ virtual Type type() const;
+
// The resolution of the frame in pixels. For formats where some planes are
// subsampled, this is the highest-resolution plane.
virtual int width() const = 0;
virtual int height() const = 0;
+ // Returns a memory-backed frame buffer in I420 format. If the pixel data is
+ // 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<PlanarYuvBuffer> ToI420();
+
+ // These functions should only be called if type() is of the correct type.
+ // Calling with a different type will result in a crash.
+ rtc::scoped_refptr<PlanarYuvBuffer> GetI420();
+ rtc::scoped_refptr<PlanarYuvBuffer> GetI444();
+
+ // 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 = 0;
- virtual const uint8_t* DataU() const = 0;
- virtual const uint8_t* DataV() const = 0;
-
+ 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 = 0;
- virtual int StrideU() const = 0;
- virtual int StrideV() const = 0;
+ 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 = 0;
+ virtual void* native_handle() const;
- // Returns a new memory-backed frame buffer converted from this buffer's
- // native handle.
- virtual rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() = 0;
+ // Deprecated - use ToI420() instead.
+ virtual rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer();
protected:
~VideoFrameBuffer() override {}
};
+// This interface represents Type::kI420 and Type::kI444.
+class PlanarYuvBuffer : public VideoFrameBuffer {
+ public:
+ int ChromaWidth() const;
+ int ChromaHeight() const;
+
+ // 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.
+ 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.
+ int StrideY() const override = 0;
+ int StrideU() const override = 0;
+ int StrideV() const override = 0;
+
+ rtc::scoped_refptr<PlanarYuvBuffer> ToI420() override;
+
+ protected:
+ ~PlanarYuvBuffer() override {}
+};
+
} // namespace webrtc
#endif // WEBRTC_API_VIDEO_VIDEO_FRAME_BUFFER_H_