OLD | NEW |
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 #include "webrtc/common_video/include/video_frame_buffer.h" | 10 #include "webrtc/api/video/i420_buffer.h" |
11 | 11 |
12 #include <string.h> | 12 #include <string.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
| 15 #include <utility> |
15 | 16 |
16 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/keep_ref_until_done.h" | 18 #include "webrtc/base/keep_ref_until_done.h" |
18 #include "libyuv/convert.h" | 19 #include "libyuv/convert.h" |
19 #include "libyuv/planar_functions.h" | 20 #include "libyuv/planar_functions.h" |
20 #include "libyuv/scale.h" | 21 #include "libyuv/scale.h" |
21 | 22 |
22 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. | 23 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. |
23 static const int kBufferAlignment = 64; | 24 static const int kBufferAlignment = 64; |
24 | 25 |
25 namespace webrtc { | 26 namespace webrtc { |
26 | 27 |
27 namespace { | 28 namespace { |
28 | 29 |
29 int I420DataSize(int height, int stride_y, int stride_u, int stride_v) { | 30 int I420DataSize(int height, int stride_y, int stride_u, int stride_v) { |
30 return stride_y * height + (stride_u + stride_v) * ((height + 1) / 2); | 31 return stride_y * height + (stride_u + stride_v) * ((height + 1) / 2); |
31 } | 32 } |
32 | 33 |
33 } // namespace | 34 } // namespace |
34 | 35 |
35 VideoFrameBuffer::~VideoFrameBuffer() {} | |
36 | |
37 I420Buffer::I420Buffer(int width, int height) | 36 I420Buffer::I420Buffer(int width, int height) |
38 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) { | 37 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) { |
39 } | 38 } |
40 | 39 |
41 I420Buffer::I420Buffer(int width, | 40 I420Buffer::I420Buffer(int width, |
42 int height, | 41 int height, |
43 int stride_y, | 42 int stride_y, |
44 int stride_u, | 43 int stride_u, |
45 int stride_v) | 44 int stride_v) |
46 : width_(width), | 45 : width_(width), |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 data_u, stride_u, | 96 data_u, stride_u, |
98 data_v, stride_v, | 97 data_v, stride_v, |
99 buffer->MutableDataY(), buffer->StrideY(), | 98 buffer->MutableDataY(), buffer->StrideY(), |
100 buffer->MutableDataU(), buffer->StrideU(), | 99 buffer->MutableDataU(), buffer->StrideU(), |
101 buffer->MutableDataV(), buffer->StrideV(), | 100 buffer->MutableDataV(), buffer->StrideV(), |
102 width, height)); | 101 width, height)); |
103 return buffer; | 102 return buffer; |
104 } | 103 } |
105 | 104 |
106 // static | 105 // static |
107 rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::Rotate( | 106 rtc::scoped_refptr<I420Buffer> I420Buffer::Rotate( |
108 rtc::scoped_refptr<VideoFrameBuffer> src, | 107 const VideoFrameBuffer& src, VideoRotation rotation) { |
109 VideoRotation rotation) { | 108 RTC_CHECK(src.DataY()); |
110 RTC_CHECK(src->DataY()); | 109 RTC_CHECK(src.DataU()); |
111 RTC_CHECK(src->DataU()); | 110 RTC_CHECK(src.DataV()); |
112 RTC_CHECK(src->DataV()); | |
113 | 111 |
114 if (rotation == webrtc::kVideoRotation_0) { | 112 int rotated_width = src.width(); |
115 return src; | 113 int rotated_height = src.height(); |
116 } | |
117 | |
118 int rotated_width = src->width(); | |
119 int rotated_height = src->height(); | |
120 if (rotation == webrtc::kVideoRotation_90 || | 114 if (rotation == webrtc::kVideoRotation_90 || |
121 rotation == webrtc::kVideoRotation_270) { | 115 rotation == webrtc::kVideoRotation_270) { |
122 std::swap(rotated_width, rotated_height); | 116 std::swap(rotated_width, rotated_height); |
123 } | 117 } |
124 | 118 |
125 rtc::scoped_refptr<webrtc::I420Buffer> buffer = | 119 rtc::scoped_refptr<webrtc::I420Buffer> buffer = |
126 I420Buffer::Create(rotated_width, rotated_height); | 120 I420Buffer::Create(rotated_width, rotated_height); |
127 | 121 |
128 RTC_CHECK_EQ(0, libyuv::I420Rotate( | 122 RTC_CHECK_EQ(0, libyuv::I420Rotate( |
129 src->DataY(), src->StrideY(), | 123 src.DataY(), src.StrideY(), |
130 src->DataU(), src->StrideU(), | 124 src.DataU(), src.StrideU(), |
131 src->DataV(), src->StrideV(), | 125 src.DataV(), src.StrideV(), |
132 buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(), | 126 buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(), |
133 buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(), | 127 buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(), |
134 src->width(), src->height(), | 128 src.width(), src.height(), |
135 static_cast<libyuv::RotationMode>(rotation))); | 129 static_cast<libyuv::RotationMode>(rotation))); |
136 | 130 |
137 return buffer; | 131 return buffer; |
138 } | 132 } |
139 | 133 |
| 134 // static |
| 135 rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::Rotate( |
| 136 rtc::scoped_refptr<VideoFrameBuffer> src, |
| 137 VideoRotation rotation) { |
| 138 if (rotation == webrtc::kVideoRotation_0) { |
| 139 return src; |
| 140 } else { |
| 141 return Rotate(*src, rotation); |
| 142 } |
| 143 } |
| 144 |
140 void I420Buffer::InitializeData() { | 145 void I420Buffer::InitializeData() { |
141 memset(data_.get(), 0, | 146 memset(data_.get(), 0, |
142 I420DataSize(height_, stride_y_, stride_u_, stride_v_)); | 147 I420DataSize(height_, stride_y_, stride_u_, stride_v_)); |
143 } | 148 } |
144 | 149 |
145 int I420Buffer::width() const { | 150 int I420Buffer::width() const { |
146 return width_; | 151 return width_; |
147 } | 152 } |
148 | 153 |
149 int I420Buffer::height() const { | 154 int I420Buffer::height() const { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 CropAndScaleFrom( | 249 CropAndScaleFrom( |
245 src, | 250 src, |
246 (src.width() - crop_width) / 2, (src.height() - crop_height) / 2, | 251 (src.width() - crop_width) / 2, (src.height() - crop_height) / 2, |
247 crop_width, crop_height); | 252 crop_width, crop_height); |
248 } | 253 } |
249 | 254 |
250 void I420Buffer::ScaleFrom(const VideoFrameBuffer& src) { | 255 void I420Buffer::ScaleFrom(const VideoFrameBuffer& src) { |
251 CropAndScaleFrom(src, 0, 0, src.width(), src.height()); | 256 CropAndScaleFrom(src, 0, 0, src.width(), src.height()); |
252 } | 257 } |
253 | 258 |
254 NativeHandleBuffer::NativeHandleBuffer(void* native_handle, | |
255 int width, | |
256 int height) | |
257 : native_handle_(native_handle), width_(width), height_(height) { | |
258 RTC_DCHECK(native_handle != nullptr); | |
259 RTC_DCHECK_GT(width, 0); | |
260 RTC_DCHECK_GT(height, 0); | |
261 } | |
262 | |
263 int NativeHandleBuffer::width() const { | |
264 return width_; | |
265 } | |
266 | |
267 int NativeHandleBuffer::height() const { | |
268 return height_; | |
269 } | |
270 | |
271 const uint8_t* NativeHandleBuffer::DataY() const { | |
272 RTC_NOTREACHED(); // Should not be called. | |
273 return nullptr; | |
274 } | |
275 const uint8_t* NativeHandleBuffer::DataU() const { | |
276 RTC_NOTREACHED(); // Should not be called. | |
277 return nullptr; | |
278 } | |
279 const uint8_t* NativeHandleBuffer::DataV() const { | |
280 RTC_NOTREACHED(); // Should not be called. | |
281 return nullptr; | |
282 } | |
283 | |
284 int NativeHandleBuffer::StrideY() const { | |
285 RTC_NOTREACHED(); // Should not be called. | |
286 return 0; | |
287 } | |
288 int NativeHandleBuffer::StrideU() const { | |
289 RTC_NOTREACHED(); // Should not be called. | |
290 return 0; | |
291 } | |
292 int NativeHandleBuffer::StrideV() const { | |
293 RTC_NOTREACHED(); // Should not be called. | |
294 return 0; | |
295 } | |
296 | |
297 void* NativeHandleBuffer::native_handle() const { | |
298 return native_handle_; | |
299 } | |
300 | |
301 WrappedI420Buffer::WrappedI420Buffer(int width, | |
302 int height, | |
303 const uint8_t* y_plane, | |
304 int y_stride, | |
305 const uint8_t* u_plane, | |
306 int u_stride, | |
307 const uint8_t* v_plane, | |
308 int v_stride, | |
309 const rtc::Callback0<void>& no_longer_used) | |
310 : width_(width), | |
311 height_(height), | |
312 y_plane_(y_plane), | |
313 u_plane_(u_plane), | |
314 v_plane_(v_plane), | |
315 y_stride_(y_stride), | |
316 u_stride_(u_stride), | |
317 v_stride_(v_stride), | |
318 no_longer_used_cb_(no_longer_used) { | |
319 } | |
320 | |
321 WrappedI420Buffer::~WrappedI420Buffer() { | |
322 no_longer_used_cb_(); | |
323 } | |
324 | |
325 int WrappedI420Buffer::width() const { | |
326 return width_; | |
327 } | |
328 | |
329 int WrappedI420Buffer::height() const { | |
330 return height_; | |
331 } | |
332 | |
333 const uint8_t* WrappedI420Buffer::DataY() const { | |
334 return y_plane_; | |
335 } | |
336 const uint8_t* WrappedI420Buffer::DataU() const { | |
337 return u_plane_; | |
338 } | |
339 const uint8_t* WrappedI420Buffer::DataV() const { | |
340 return v_plane_; | |
341 } | |
342 | |
343 int WrappedI420Buffer::StrideY() const { | |
344 return y_stride_; | |
345 } | |
346 int WrappedI420Buffer::StrideU() const { | |
347 return u_stride_; | |
348 } | |
349 int WrappedI420Buffer::StrideV() const { | |
350 return v_stride_; | |
351 } | |
352 | |
353 void* WrappedI420Buffer::native_handle() const { | |
354 return nullptr; | |
355 } | |
356 | |
357 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { | |
358 RTC_NOTREACHED(); | |
359 return nullptr; | |
360 } | |
361 | |
362 } // namespace webrtc | 259 } // namespace webrtc |
OLD | NEW |