1/* 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#ifndef WEBRTC_COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_H_ 12#define WEBRTC_COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_H_ 13 14#include "webrtc/base/callback.h" 15#include "webrtc/base/refcount.h" 16#include "webrtc/base/scoped_ptr.h" 17#include "webrtc/base/scoped_ref_ptr.h" 18#include "webrtc/system_wrappers/include/aligned_malloc.h" 19 20namespace webrtc { 21 22enum PlaneType { 23 kYPlane = 0, 24 kUPlane = 1, 25 kVPlane = 2, 26 kNumOfPlanes = 3, 27}; 28 29// Interface of a simple frame buffer containing pixel data. This interface does 30// not contain any frame metadata such as rotation, timestamp, pixel_width, etc. 31class VideoFrameBuffer : public rtc::RefCountInterface { 32 public: 33 // Returns true if this buffer has a single exclusive owner. 34 virtual bool HasOneRef() const = 0; 35 36 // The resolution of the frame in pixels. For formats where some planes are 37 // subsampled, this is the highest-resolution plane. 38 virtual int width() const = 0; 39 virtual int height() const = 0; 40 41 // Returns pointer to the pixel data for a given plane. The memory is owned by 42 // the VideoFrameBuffer object and must not be freed by the caller. 43 virtual const uint8_t* data(PlaneType type) const = 0; 44 45 // Non-const data access is disallowed by default. You need to make sure you 46 // have exclusive access and a writable buffer before calling this function. 47 virtual uint8_t* MutableData(PlaneType type); 48 49 // Returns the number of bytes between successive rows for a given plane. 50 virtual int stride(PlaneType type) const = 0; 51 52 // Return the handle of the underlying video frame. This is used when the 53 // frame is backed by a texture. 54 virtual void* native_handle() const = 0; 55 56 // Returns a new memory-backed frame buffer converted from this buffer's 57 // native handle. 58 virtual rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() = 0; 59 60 protected: 61 virtual ~VideoFrameBuffer(); 62}; 63 64// Plain I420 buffer in standard memory. 65class I420Buffer : public VideoFrameBuffer { 66 public: 67 I420Buffer(int width, int height); 68 I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v); 69 70 int width() const override; 71 int height() const override; 72 const uint8_t* data(PlaneType type) const override; 73 // Non-const data access is only allowed if HasOneRef() is true to protect 74 // against unexpected overwrites. 75 uint8_t* MutableData(PlaneType type) override; 76 int stride(PlaneType type) const override; 77 void* native_handle() const override; 78 rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override; 79 80 protected: 81 ~I420Buffer() override; 82 83 private: 84 const int width_; 85 const int height_; 86 const int stride_y_; 87 const int stride_u_; 88 const int stride_v_; 89 const rtc::scoped_ptr<uint8_t, AlignedFreeDeleter> data_; 90}; 91 92// Base class for native-handle buffer is a wrapper around a |native_handle|. 93// This is used for convenience as most native-handle implementations can share 94// many VideoFrame implementations, but need to implement a few others (such 95// as their own destructors or conversion methods back to software I420). 96class NativeHandleBuffer : public VideoFrameBuffer { 97 public: 98 NativeHandleBuffer(void* native_handle, int width, int height); 99 100 int width() const override; 101 int height() const override; 102 const uint8_t* data(PlaneType type) const override; 103 int stride(PlaneType type) const override; 104 void* native_handle() const override; 105 106 protected: 107 void* native_handle_; 108 const int width_; 109 const int height_; 110}; 111 112class WrappedI420Buffer : public webrtc::VideoFrameBuffer { 113 public: 114 WrappedI420Buffer(int width, 115 int height, 116 const uint8_t* y_plane, 117 int y_stride, 118 const uint8_t* u_plane, 119 int u_stride, 120 const uint8_t* v_plane, 121 int v_stride, 122 const rtc::Callback0<void>& no_longer_used); 123 int width() const override; 124 int height() const override; 125 126 const uint8_t* data(PlaneType type) const override; 127 128 int stride(PlaneType type) const override; 129 void* native_handle() const override; 130 131 rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override; 132 133 private: 134 friend class rtc::RefCountedObject<WrappedI420Buffer>; 135 ~WrappedI420Buffer() override; 136 137 const int width_; 138 const int height_; 139 const uint8_t* const y_plane_; 140 const uint8_t* const u_plane_; 141 const uint8_t* const v_plane_; 142 const int y_stride_; 143 const int u_stride_; 144 const int v_stride_; 145 rtc::Callback0<void> no_longer_used_cb_; 146}; 147 148// Helper function to crop |buffer| without making a deep copy. May only be used 149// for non-native frames. 150rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( 151 const rtc::scoped_refptr<VideoFrameBuffer>& buffer, 152 int cropped_width, 153 int cropped_height); 154 155} // namespace webrtc 156 157#endif // WEBRTC_COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_H_ 158