Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: webrtc/common_video/video_frame_buffer.cc

Issue 1878623002: Added new VideoFrameBuffer methods Data[YUV]() etc. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/common_video/include/video_frame_buffer.h" 11 #include "webrtc/common_video/include/video_frame_buffer.h"
12 12
13 #include "webrtc/base/checks.h" 13 #include "webrtc/base/checks.h"
14 #include "webrtc/base/keep_ref_until_done.h" 14 #include "webrtc/base/keep_ref_until_done.h"
15 #include "libyuv/convert.h" 15 #include "libyuv/convert.h"
16 16
17 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. 17 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
18 static const int kBufferAlignment = 64; 18 static const int kBufferAlignment = 64;
19 19
20 namespace webrtc { 20 namespace webrtc {
21 21
22 namespace { 22 namespace {
23 23
24 int I420DataSize(int height, int stride_y, int stride_u, int stride_v) { 24 int I420DataSize(int height, int stride_y, int stride_u, int stride_v) {
25 return stride_y * height + (stride_u + stride_v) * ((height + 1) / 2); 25 return stride_y * height + (stride_u + stride_v) * ((height + 1) / 2);
26 } 26 }
27 27
28 } // namespace 28 } // namespace
29 29
30 uint8_t* VideoFrameBuffer::MutableData(PlaneType type) { 30 const uint8_t* VideoFrameBuffer::data(PlaneType type) const {
31 switch (type) {
32 case kYPlane:
33 return DataY();
34 case kUPlane:
35 return DataU();
36 case kVPlane:
37 return DataV();
38 default:
39 RTC_NOTREACHED();
40 return nullptr;
41 }
42 }
43
44 const uint8_t* VideoFrameBuffer::DataY() const {
45 return data(kYPlane);
46 }
47 const uint8_t* VideoFrameBuffer::DataU() const {
48 return data(kUPlane);
49 }
50 const uint8_t* VideoFrameBuffer::DataV() const {
51 return data(kVPlane);
52 }
53
54 int VideoFrameBuffer::stride(PlaneType type) const {
55 switch (type) {
56 case kYPlane:
57 return StrideY();
58 case kUPlane:
59 return StrideU();
60 case kVPlane:
61 return StrideV();
62 default:
63 RTC_NOTREACHED();
64 return 0;
65 }
66 }
67
68 int VideoFrameBuffer::StrideY() const {
69 return stride(kYPlane);
70 }
71 int VideoFrameBuffer::StrideU() const {
72 return stride(kUPlane);
73 }
74 int VideoFrameBuffer::StrideV() const {
75 return stride(kVPlane);
76 }
77
78 uint8_t* VideoFrameBuffer::MutableDataY() {
31 RTC_NOTREACHED(); 79 RTC_NOTREACHED();
32 return nullptr; 80 return nullptr;
33 } 81 }
82 uint8_t* VideoFrameBuffer::MutableDataU() {
83 RTC_NOTREACHED();
84 return nullptr;
85 }
86 uint8_t* VideoFrameBuffer::MutableDataV() {
87 RTC_NOTREACHED();
88 return nullptr;
89 }
90
91 uint8_t* VideoFrameBuffer::MutableData(PlaneType type) {
92 switch (type) {
93 case kYPlane:
94 return MutableDataY();
95 case kUPlane:
96 return MutableDataU();
97 case kVPlane:
98 return MutableDataV();
99 default:
100 RTC_NOTREACHED();
101 return nullptr;
102 }
103 }
34 104
35 VideoFrameBuffer::~VideoFrameBuffer() {} 105 VideoFrameBuffer::~VideoFrameBuffer() {}
36 106
37 I420Buffer::I420Buffer(int width, int height) 107 I420Buffer::I420Buffer(int width, int height)
38 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) { 108 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) {
39 } 109 }
40 110
41 I420Buffer::I420Buffer(int width, 111 I420Buffer::I420Buffer(int width,
42 int height, 112 int height,
43 int stride_y, 113 int stride_y,
(...skipping 23 matching lines...) Expand all
67 } 137 }
68 138
69 int I420Buffer::width() const { 139 int I420Buffer::width() const {
70 return width_; 140 return width_;
71 } 141 }
72 142
73 int I420Buffer::height() const { 143 int I420Buffer::height() const {
74 return height_; 144 return height_;
75 } 145 }
76 146
77 const uint8_t* I420Buffer::data(PlaneType type) const { 147 const uint8_t* I420Buffer::DataY() const {
78 switch (type) { 148 return data_.get();
79 case kYPlane: 149 }
80 return data_.get(); 150 const uint8_t* I420Buffer::DataU() const {
81 case kUPlane: 151 return data_.get() + stride_y_ * height_;
82 return data_.get() + stride_y_ * height_; 152 }
83 case kVPlane: 153 const uint8_t* I420Buffer::DataV() const {
84 return data_.get() + stride_y_ * height_ + 154 return data_.get() + stride_y_ * height_ + stride_u_ * ((height_ + 1) / 2);
85 stride_u_ * ((height_ + 1) / 2);
86 default:
87 RTC_NOTREACHED();
88 return nullptr;
89 }
90 } 155 }
91 156
92 bool I420Buffer::IsMutable() { 157 bool I420Buffer::IsMutable() {
93 return HasOneRef(); 158 return HasOneRef();
94 } 159 }
95 160
96 uint8_t* I420Buffer::MutableData(PlaneType type) { 161 uint8_t* I420Buffer::MutableDataY() {
97 RTC_DCHECK(IsMutable()); 162 RTC_DCHECK(IsMutable());
98 return const_cast<uint8_t*>( 163 return const_cast<uint8_t*>(DataY());
99 static_cast<const VideoFrameBuffer*>(this)->data(type)); 164 }
165 uint8_t* I420Buffer::MutableDataU() {
166 RTC_DCHECK(IsMutable());
167 return const_cast<uint8_t*>(DataU());
168 }
169 uint8_t* I420Buffer::MutableDataV() {
170 RTC_DCHECK(IsMutable());
171 return const_cast<uint8_t*>(DataV());
100 } 172 }
101 173
102 int I420Buffer::stride(PlaneType type) const { 174 int I420Buffer::StrideY() const {
103 switch (type) { 175 return stride_y_;
104 case kYPlane: 176 }
105 return stride_y_; 177 int I420Buffer::StrideU() const {
106 case kUPlane: 178 return stride_u_;
107 return stride_u_; 179 }
108 case kVPlane: 180 int I420Buffer::StrideV() const {
109 return stride_v_; 181 return stride_v_;
110 default:
111 RTC_NOTREACHED();
112 return 0;
113 }
114 } 182 }
115 183
116 void* I420Buffer::native_handle() const { 184 void* I420Buffer::native_handle() const {
117 return nullptr; 185 return nullptr;
118 } 186 }
119 187
120 rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() { 188 rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() {
121 RTC_NOTREACHED(); 189 RTC_NOTREACHED();
122 return nullptr; 190 return nullptr;
123 } 191 }
124 192
125 rtc::scoped_refptr<I420Buffer> I420Buffer::Copy( 193 rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
126 const rtc::scoped_refptr<VideoFrameBuffer>& buffer) { 194 const rtc::scoped_refptr<VideoFrameBuffer>& buffer) {
127 int width = buffer->width(); 195 int width = buffer->width();
128 int height = buffer->height(); 196 int height = buffer->height();
129 rtc::scoped_refptr<I420Buffer> copy = 197 rtc::scoped_refptr<I420Buffer> copy =
130 new rtc::RefCountedObject<I420Buffer>(width, height); 198 new rtc::RefCountedObject<I420Buffer>(width, height);
131 RTC_CHECK(libyuv::I420Copy(buffer->data(kYPlane), buffer->stride(kYPlane), 199 RTC_CHECK(libyuv::I420Copy(buffer->DataY(), buffer->StrideY(),
132 buffer->data(kUPlane), buffer->stride(kUPlane), 200 buffer->DataU(), buffer->StrideU(),
133 buffer->data(kVPlane), buffer->stride(kVPlane), 201 buffer->DataV(), buffer->StrideV(),
134 copy->MutableData(kYPlane), copy->stride(kYPlane), 202 copy->MutableDataY(), copy->StrideY(),
135 copy->MutableData(kUPlane), copy->stride(kUPlane), 203 copy->MutableDataU(), copy->StrideU(),
136 copy->MutableData(kVPlane), copy->stride(kVPlane), 204 copy->MutableDataV(), copy->StrideV(),
137 width, height) == 0); 205 width, height) == 0);
138 206
139 return copy; 207 return copy;
140 } 208 }
141 209
142 NativeHandleBuffer::NativeHandleBuffer(void* native_handle, 210 NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
143 int width, 211 int width,
144 int height) 212 int height)
145 : native_handle_(native_handle), width_(width), height_(height) { 213 : native_handle_(native_handle), width_(width), height_(height) {
146 RTC_DCHECK(native_handle != nullptr); 214 RTC_DCHECK(native_handle != nullptr);
147 RTC_DCHECK_GT(width, 0); 215 RTC_DCHECK_GT(width, 0);
148 RTC_DCHECK_GT(height, 0); 216 RTC_DCHECK_GT(height, 0);
149 } 217 }
150 218
151 bool NativeHandleBuffer::IsMutable() { 219 bool NativeHandleBuffer::IsMutable() {
152 return false; 220 return false;
153 } 221 }
154 222
155 int NativeHandleBuffer::width() const { 223 int NativeHandleBuffer::width() const {
156 return width_; 224 return width_;
157 } 225 }
158 226
159 int NativeHandleBuffer::height() const { 227 int NativeHandleBuffer::height() const {
160 return height_; 228 return height_;
161 } 229 }
162 230
163 const uint8_t* NativeHandleBuffer::data(PlaneType type) const { 231 const uint8_t* NativeHandleBuffer::DataY() const {
232 RTC_NOTREACHED(); // Should not be called.
233 return nullptr;
234 }
235 const uint8_t* NativeHandleBuffer::DataU() const {
236 RTC_NOTREACHED(); // Should not be called.
237 return nullptr;
238 }
239 const uint8_t* NativeHandleBuffer::DataV() const {
164 RTC_NOTREACHED(); // Should not be called. 240 RTC_NOTREACHED(); // Should not be called.
165 return nullptr; 241 return nullptr;
166 } 242 }
167 243
168 int NativeHandleBuffer::stride(PlaneType type) const { 244 int NativeHandleBuffer::StrideY() const {
169 RTC_NOTREACHED(); // Should not be called. 245 RTC_NOTREACHED(); // Should not be called.
170 return 0; 246 return 0;
171 } 247 }
248 int NativeHandleBuffer::StrideU() const {
249 RTC_NOTREACHED(); // Should not be called.
250 return 0;
251 }
252 int NativeHandleBuffer::StrideV() const {
253 RTC_NOTREACHED(); // Should not be called.
254 return 0;
255 }
172 256
173 void* NativeHandleBuffer::native_handle() const { 257 void* NativeHandleBuffer::native_handle() const {
174 return native_handle_; 258 return native_handle_;
175 } 259 }
176 260
177 WrappedI420Buffer::WrappedI420Buffer(int width, 261 WrappedI420Buffer::WrappedI420Buffer(int width,
178 int height, 262 int height,
179 const uint8_t* y_plane, 263 const uint8_t* y_plane,
180 int y_stride, 264 int y_stride,
181 const uint8_t* u_plane, 265 const uint8_t* u_plane,
(...skipping 22 matching lines...) Expand all
204 } 288 }
205 289
206 int WrappedI420Buffer::width() const { 290 int WrappedI420Buffer::width() const {
207 return width_; 291 return width_;
208 } 292 }
209 293
210 int WrappedI420Buffer::height() const { 294 int WrappedI420Buffer::height() const {
211 return height_; 295 return height_;
212 } 296 }
213 297
214 const uint8_t* WrappedI420Buffer::data(PlaneType type) const { 298 const uint8_t* WrappedI420Buffer::DataY() const {
215 switch (type) { 299 return y_plane_;
216 case kYPlane: 300 }
217 return y_plane_; 301 const uint8_t* WrappedI420Buffer::DataU() const {
218 case kUPlane: 302 return u_plane_;
219 return u_plane_; 303 }
220 case kVPlane: 304 const uint8_t* WrappedI420Buffer::DataV() const {
221 return v_plane_; 305 return v_plane_;
222 default:
223 RTC_NOTREACHED();
224 return nullptr;
225 }
226 } 306 }
227 307
228 int WrappedI420Buffer::stride(PlaneType type) const { 308 int WrappedI420Buffer::StrideY() const {
229 switch (type) { 309 return y_stride_;
230 case kYPlane: 310 }
231 return y_stride_; 311 int WrappedI420Buffer::StrideU() const {
232 case kUPlane: 312 return u_stride_;
233 return u_stride_; 313 }
234 case kVPlane: 314 int WrappedI420Buffer::StrideV() const {
235 return v_stride_; 315 return v_stride_;
236 default:
237 RTC_NOTREACHED();
238 return 0;
239 }
240 } 316 }
241 317
242 void* WrappedI420Buffer::native_handle() const { 318 void* WrappedI420Buffer::native_handle() const {
243 return nullptr; 319 return nullptr;
244 } 320 }
245 321
246 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { 322 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() {
247 RTC_NOTREACHED(); 323 RTC_NOTREACHED();
248 return nullptr; 324 return nullptr;
249 } 325 }
250 326
251 rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( 327 rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop(
252 const rtc::scoped_refptr<VideoFrameBuffer>& buffer, 328 const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
253 int cropped_width, 329 int cropped_width,
254 int cropped_height) { 330 int cropped_height) {
255 RTC_CHECK(buffer->native_handle() == nullptr); 331 RTC_CHECK(buffer->native_handle() == nullptr);
256 RTC_CHECK_LE(cropped_width, buffer->width()); 332 RTC_CHECK_LE(cropped_width, buffer->width());
257 RTC_CHECK_LE(cropped_height, buffer->height()); 333 RTC_CHECK_LE(cropped_height, buffer->height());
258 if (buffer->width() == cropped_width && buffer->height() == cropped_height) 334 if (buffer->width() == cropped_width && buffer->height() == cropped_height)
259 return buffer; 335 return buffer;
260 336
261 // Center crop to |cropped_width| x |cropped_height|. 337 // Center crop to |cropped_width| x |cropped_height|.
262 // Make sure offset is even so that u/v plane becomes aligned. 338 // Make sure offset is even so that u/v plane becomes aligned.
263 const int uv_offset_x = (buffer->width() - cropped_width) / 4; 339 const int uv_offset_x = (buffer->width() - cropped_width) / 4;
264 const int uv_offset_y = (buffer->height() - cropped_height) / 4; 340 const int uv_offset_y = (buffer->height() - cropped_height) / 4;
265 const int offset_x = uv_offset_x * 2; 341 const int offset_x = uv_offset_x * 2;
266 const int offset_y = uv_offset_y * 2; 342 const int offset_y = uv_offset_y * 2;
267 343
268 const uint8_t* y_plane = buffer->data(kYPlane) + 344 const uint8_t* y_plane = buffer->DataY() +
269 buffer->stride(kYPlane) * offset_y + offset_x; 345 buffer->StrideY() * offset_y + offset_x;
270 const uint8_t* u_plane = buffer->data(kUPlane) + 346 const uint8_t* u_plane = buffer->DataU() +
271 buffer->stride(kUPlane) * uv_offset_y + uv_offset_x; 347 buffer->StrideU() * uv_offset_y + uv_offset_x;
272 const uint8_t* v_plane = buffer->data(kVPlane) + 348 const uint8_t* v_plane = buffer->DataV() +
273 buffer->stride(kVPlane) * uv_offset_y + uv_offset_x; 349 buffer->StrideV() * uv_offset_y + uv_offset_x;
274 return new rtc::RefCountedObject<WrappedI420Buffer>( 350 return new rtc::RefCountedObject<WrappedI420Buffer>(
275 cropped_width, cropped_height, 351 cropped_width, cropped_height,
276 y_plane, buffer->stride(kYPlane), 352 y_plane, buffer->StrideY(),
277 u_plane, buffer->stride(kUPlane), 353 u_plane, buffer->StrideU(),
278 v_plane, buffer->stride(kVPlane), 354 v_plane, buffer->StrideV(),
279 rtc::KeepRefUntilDone(buffer)); 355 rtc::KeepRefUntilDone(buffer));
280 } 356 }
281 357
282 } // namespace webrtc 358 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/include/video_frame_buffer.h ('k') | webrtc/media/engine/webrtcvideoframe.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698