blob: 287624e59ec5076f72ad0d87a856a6fe8e0ba8b0 [file] [log] [blame]
kjellander6f8ce062015-11-16 13:52:24 -08001/*
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
kwibergc891eb42016-03-02 03:41:34 -080014#include <stdint.h>
15
16#include <memory>
17
kjellander6f8ce062015-11-16 13:52:24 -080018#include "webrtc/base/callback.h"
19#include "webrtc/base/refcount.h"
kjellander6f8ce062015-11-16 13:52:24 -080020#include "webrtc/base/scoped_ref_ptr.h"
nissed5074722016-08-30 08:45:44 -070021#include "webrtc/common_video/rotation.h"
kjellander6f8ce062015-11-16 13:52:24 -080022#include "webrtc/system_wrappers/include/aligned_malloc.h"
23
24namespace webrtc {
25
kjellander6f8ce062015-11-16 13:52:24 -080026// Interface of a simple frame buffer containing pixel data. This interface does
27// not contain any frame metadata such as rotation, timestamp, pixel_width, etc.
28class VideoFrameBuffer : public rtc::RefCountInterface {
29 public:
kjellander6f8ce062015-11-16 13:52:24 -080030 // The resolution of the frame in pixels. For formats where some planes are
31 // subsampled, this is the highest-resolution plane.
32 virtual int width() const = 0;
33 virtual int height() const = 0;
34
35 // Returns pointer to the pixel data for a given plane. The memory is owned by
36 // the VideoFrameBuffer object and must not be freed by the caller.
nisse1e6bbe42016-06-21 03:59:23 -070037 virtual const uint8_t* DataY() const = 0;
38 virtual const uint8_t* DataU() const = 0;
39 virtual const uint8_t* DataV() const = 0;
kjellander6f8ce062015-11-16 13:52:24 -080040
kjellander6f8ce062015-11-16 13:52:24 -080041 // Returns the number of bytes between successive rows for a given plane.
nisse1e6bbe42016-06-21 03:59:23 -070042 virtual int StrideY() const = 0;
43 virtual int StrideU() const = 0;
44 virtual int StrideV() const = 0;
kjellander6f8ce062015-11-16 13:52:24 -080045
46 // Return the handle of the underlying video frame. This is used when the
47 // frame is backed by a texture.
48 virtual void* native_handle() const = 0;
49
50 // Returns a new memory-backed frame buffer converted from this buffer's
51 // native handle.
52 virtual rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() = 0;
53
54 protected:
55 virtual ~VideoFrameBuffer();
56};
57
58// Plain I420 buffer in standard memory.
59class I420Buffer : public VideoFrameBuffer {
60 public:
61 I420Buffer(int width, int height);
62 I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
nisseefec5902016-06-09 00:31:39 -070063
nisseac62bd42016-06-20 03:38:52 -070064 static rtc::scoped_refptr<I420Buffer> Create(int width, int height);
65 static rtc::scoped_refptr<I420Buffer> Create(int width,
66 int height,
67 int stride_y,
68 int stride_u,
69 int stride_v);
70
nisseefec5902016-06-09 00:31:39 -070071 // Sets all three planes to all zeros. Used to work around for
72 // quirks in memory checkers
73 // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
74 // ffmpeg (http://crbug.com/390941).
75 // TODO(nisse): Should be deleted if/when those issues are resolved
76 // in a better way.
hbos900f9752016-02-05 08:08:34 -080077 void InitializeData();
kjellander6f8ce062015-11-16 13:52:24 -080078
nisseefec5902016-06-09 00:31:39 -070079 // Sets the frame buffer to all black.
80 void SetToBlack();
81
kjellander6f8ce062015-11-16 13:52:24 -080082 int width() const override;
83 int height() const override;
nisse06176e42016-04-18 05:34:40 -070084 const uint8_t* DataY() const override;
85 const uint8_t* DataU() const override;
86 const uint8_t* DataV() const override;
nissed591e3f2016-05-26 06:49:55 -070087
nisse64ec8f82016-09-27 00:17:25 -070088 uint8_t* MutableDataY();
89 uint8_t* MutableDataU();
90 uint8_t* MutableDataV();
nisse06176e42016-04-18 05:34:40 -070091 int StrideY() const override;
92 int StrideU() const override;
93 int StrideV() const override;
94
kjellander6f8ce062015-11-16 13:52:24 -080095 void* native_handle() const override;
96 rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
97
nisse7cc9cc02016-03-29 23:44:19 -070098 // Create a new buffer and copy the pixel data.
nissee3fe4a72016-11-10 08:44:38 -080099 static rtc::scoped_refptr<I420Buffer> Copy(const VideoFrameBuffer& buffer);
nisse7cc9cc02016-03-29 23:44:19 -0700100
Niels Möller718a7632016-06-13 13:06:01 +0200101 // Scale the cropped area of |src| to the size of |this| buffer, and
102 // write the result into |this|.
nissee3fe4a72016-11-10 08:44:38 -0800103 void CropAndScaleFrom(const VideoFrameBuffer& src,
Niels Möller718a7632016-06-13 13:06:01 +0200104 int offset_x,
105 int offset_y,
106 int crop_width,
107 int crop_height);
108
109 // The common case of a center crop, when needed to adjust the
110 // aspect ratio without distorting the image.
nissee3fe4a72016-11-10 08:44:38 -0800111 void CropAndScaleFrom(const VideoFrameBuffer& src);
Niels Möller718a7632016-06-13 13:06:01 +0200112
113 // Scale all of |src| to the size of |this| buffer, with no cropping.
nissee3fe4a72016-11-10 08:44:38 -0800114 void ScaleFrom(const VideoFrameBuffer& src);
115
116 // Deprecated methods, using smart pointer references.
117 // TODO(nisse): Delete once downstream applications are updated.
118 static rtc::scoped_refptr<I420Buffer> Copy(
119 const rtc::scoped_refptr<VideoFrameBuffer>& buffer) {
120 return Copy(*buffer);
121 }
122 void CropAndScaleFrom(const rtc::scoped_refptr<VideoFrameBuffer>& src,
123 int offset_x,
124 int offset_y,
125 int crop_width,
126 int crop_height) {
127 CropAndScaleFrom(*src, offset_x, offset_y, crop_width, crop_height);
128 }
129 void CropAndScaleFrom(const rtc::scoped_refptr<VideoFrameBuffer>& src) {
130 CropAndScaleFrom(*src);
131 }
132 void ScaleFrom(const rtc::scoped_refptr<VideoFrameBuffer>& src) {
133 ScaleFrom(*src);
134 }
Niels Möller718a7632016-06-13 13:06:01 +0200135
nissed5074722016-08-30 08:45:44 -0700136 // Returns a rotated versions of |src|. Native buffers are not
137 // supported. The reason this function doesn't return an I420Buffer,
138 // is that it returns |src| unchanged in case |rotation| is zero.
139 static rtc::scoped_refptr<VideoFrameBuffer> Rotate(
nissee3fe4a72016-11-10 08:44:38 -0800140 rtc::scoped_refptr<VideoFrameBuffer> src,
nissed5074722016-08-30 08:45:44 -0700141 VideoRotation rotation);
142
kjellander6f8ce062015-11-16 13:52:24 -0800143 protected:
144 ~I420Buffer() override;
145
146 private:
147 const int width_;
148 const int height_;
149 const int stride_y_;
150 const int stride_u_;
151 const int stride_v_;
kwibergc891eb42016-03-02 03:41:34 -0800152 const std::unique_ptr<uint8_t, AlignedFreeDeleter> data_;
kjellander6f8ce062015-11-16 13:52:24 -0800153};
154
155// Base class for native-handle buffer is a wrapper around a |native_handle|.
156// This is used for convenience as most native-handle implementations can share
157// many VideoFrame implementations, but need to implement a few others (such
158// as their own destructors or conversion methods back to software I420).
159class NativeHandleBuffer : public VideoFrameBuffer {
160 public:
161 NativeHandleBuffer(void* native_handle, int width, int height);
162
163 int width() const override;
164 int height() const override;
nisse06176e42016-04-18 05:34:40 -0700165 const uint8_t* DataY() const override;
166 const uint8_t* DataU() const override;
167 const uint8_t* DataV() const override;
168 int StrideY() const override;
169 int StrideU() const override;
170 int StrideV() const override;
171
kjellander6f8ce062015-11-16 13:52:24 -0800172 void* native_handle() const override;
173
174 protected:
175 void* native_handle_;
176 const int width_;
177 const int height_;
178};
179
180class WrappedI420Buffer : public webrtc::VideoFrameBuffer {
181 public:
182 WrappedI420Buffer(int width,
183 int height,
184 const uint8_t* y_plane,
185 int y_stride,
186 const uint8_t* u_plane,
187 int u_stride,
188 const uint8_t* v_plane,
189 int v_stride,
190 const rtc::Callback0<void>& no_longer_used);
191 int width() const override;
192 int height() const override;
193
nisse06176e42016-04-18 05:34:40 -0700194 const uint8_t* DataY() const override;
195 const uint8_t* DataU() const override;
196 const uint8_t* DataV() const override;
197 int StrideY() const override;
198 int StrideU() const override;
199 int StrideV() const override;
kjellander6f8ce062015-11-16 13:52:24 -0800200
kjellander6f8ce062015-11-16 13:52:24 -0800201 void* native_handle() const override;
202
203 rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
204
205 private:
206 friend class rtc::RefCountedObject<WrappedI420Buffer>;
207 ~WrappedI420Buffer() override;
208
209 const int width_;
210 const int height_;
211 const uint8_t* const y_plane_;
212 const uint8_t* const u_plane_;
213 const uint8_t* const v_plane_;
214 const int y_stride_;
215 const int u_stride_;
216 const int v_stride_;
217 rtc::Callback0<void> no_longer_used_cb_;
218};
219
kjellander6f8ce062015-11-16 13:52:24 -0800220} // namespace webrtc
221
222#endif // WEBRTC_COMMON_VIDEO_INCLUDE_VIDEO_FRAME_BUFFER_H_