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

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

Issue 2517173004: Move VideoFrame and related declarations to webrtc/api/video. (Closed)
Patch Set: Make rotation check clearer. Created 3 years, 11 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
« no previous file with comments | « webrtc/common_video/video_frame.cc ('k') | webrtc/common_video/video_render_frames.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "webrtc/common_video/include/video_frame_buffer.h" 10 #include "webrtc/common_video/include/video_frame_buffer.h"
11 11
12 #include <string.h> 12 #include <string.h>
13 13
14 #include <algorithm> 14 #include <algorithm>
15 15
16 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
17 #include "webrtc/base/keep_ref_until_done.h" 17 #include "webrtc/base/keep_ref_until_done.h"
18 #include "libyuv/convert.h" 18 #include "libyuv/convert.h"
19 #include "libyuv/planar_functions.h" 19 #include "libyuv/planar_functions.h"
20 #include "libyuv/scale.h" 20 #include "libyuv/scale.h"
21 21
22 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
23 static const int kBufferAlignment = 64;
24
25 namespace webrtc { 22 namespace webrtc {
26 23
27 namespace {
28
29 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 }
32
33 } // namespace
34
35 VideoFrameBuffer::~VideoFrameBuffer() {}
36
37 I420Buffer::I420Buffer(int width, int height)
38 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) {
39 }
40
41 I420Buffer::I420Buffer(int width,
42 int height,
43 int stride_y,
44 int stride_u,
45 int stride_v)
46 : width_(width),
47 height_(height),
48 stride_y_(stride_y),
49 stride_u_(stride_u),
50 stride_v_(stride_v),
51 data_(static_cast<uint8_t*>(AlignedMalloc(
52 I420DataSize(height, stride_y, stride_u, stride_v),
53 kBufferAlignment))) {
54 RTC_DCHECK_GT(width, 0);
55 RTC_DCHECK_GT(height, 0);
56 RTC_DCHECK_GE(stride_y, width);
57 RTC_DCHECK_GE(stride_u, (width + 1) / 2);
58 RTC_DCHECK_GE(stride_v, (width + 1) / 2);
59 }
60
61 I420Buffer::~I420Buffer() {
62 }
63
64 // static
65 rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width, int height) {
66 return new rtc::RefCountedObject<I420Buffer>(width, height);
67 }
68
69 // static
70 rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width,
71 int height,
72 int stride_y,
73 int stride_u,
74 int stride_v) {
75 return new rtc::RefCountedObject<I420Buffer>(
76 width, height, stride_y, stride_u, stride_v);
77 }
78
79 // static
80 rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
81 const VideoFrameBuffer& source) {
82 return Copy(source.width(), source.height(),
83 source.DataY(), source.StrideY(),
84 source.DataU(), source.StrideU(),
85 source.DataV(), source.StrideV());
86 }
87
88 // static
89 rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
90 int width, int height,
91 const uint8_t* data_y, int stride_y,
92 const uint8_t* data_u, int stride_u,
93 const uint8_t* data_v, int stride_v) {
94 // Note: May use different strides than the input data.
95 rtc::scoped_refptr<I420Buffer> buffer = Create(width, height);
96 RTC_CHECK_EQ(0, libyuv::I420Copy(data_y, stride_y,
97 data_u, stride_u,
98 data_v, stride_v,
99 buffer->MutableDataY(), buffer->StrideY(),
100 buffer->MutableDataU(), buffer->StrideU(),
101 buffer->MutableDataV(), buffer->StrideV(),
102 width, height));
103 return buffer;
104 }
105
106 // static
107 rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::Rotate(
108 rtc::scoped_refptr<VideoFrameBuffer> src,
109 VideoRotation rotation) {
110 RTC_CHECK(src->DataY());
111 RTC_CHECK(src->DataU());
112 RTC_CHECK(src->DataV());
113
114 if (rotation == webrtc::kVideoRotation_0) {
115 return src;
116 }
117
118 int rotated_width = src->width();
119 int rotated_height = src->height();
120 if (rotation == webrtc::kVideoRotation_90 ||
121 rotation == webrtc::kVideoRotation_270) {
122 std::swap(rotated_width, rotated_height);
123 }
124
125 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
126 I420Buffer::Create(rotated_width, rotated_height);
127
128 RTC_CHECK_EQ(0, libyuv::I420Rotate(
129 src->DataY(), src->StrideY(),
130 src->DataU(), src->StrideU(),
131 src->DataV(), src->StrideV(),
132 buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(),
133 buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(),
134 src->width(), src->height(),
135 static_cast<libyuv::RotationMode>(rotation)));
136
137 return buffer;
138 }
139
140 void I420Buffer::InitializeData() {
141 memset(data_.get(), 0,
142 I420DataSize(height_, stride_y_, stride_u_, stride_v_));
143 }
144
145 int I420Buffer::width() const {
146 return width_;
147 }
148
149 int I420Buffer::height() const {
150 return height_;
151 }
152
153 const uint8_t* I420Buffer::DataY() const {
154 return data_.get();
155 }
156 const uint8_t* I420Buffer::DataU() const {
157 return data_.get() + stride_y_ * height_;
158 }
159 const uint8_t* I420Buffer::DataV() const {
160 return data_.get() + stride_y_ * height_ + stride_u_ * ((height_ + 1) / 2);
161 }
162
163 uint8_t* I420Buffer::MutableDataY() {
164 return const_cast<uint8_t*>(DataY());
165 }
166 uint8_t* I420Buffer::MutableDataU() {
167 return const_cast<uint8_t*>(DataU());
168 }
169 uint8_t* I420Buffer::MutableDataV() {
170 return const_cast<uint8_t*>(DataV());
171 }
172
173 int I420Buffer::StrideY() const {
174 return stride_y_;
175 }
176 int I420Buffer::StrideU() const {
177 return stride_u_;
178 }
179 int I420Buffer::StrideV() const {
180 return stride_v_;
181 }
182
183 void* I420Buffer::native_handle() const {
184 return nullptr;
185 }
186
187 rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() {
188 RTC_NOTREACHED();
189 return nullptr;
190 }
191
192 void I420Buffer::SetToBlack() {
193 RTC_CHECK(libyuv::I420Rect(MutableDataY(), StrideY(),
194 MutableDataU(), StrideU(),
195 MutableDataV(), StrideV(),
196 0, 0, width(), height(),
197 0, 128, 128) == 0);
198 }
199
200 void I420Buffer::CropAndScaleFrom(
201 const VideoFrameBuffer& src,
202 int offset_x,
203 int offset_y,
204 int crop_width,
205 int crop_height) {
206 RTC_CHECK_LE(crop_width, src.width());
207 RTC_CHECK_LE(crop_height, src.height());
208 RTC_CHECK_LE(crop_width + offset_x, src.width());
209 RTC_CHECK_LE(crop_height + offset_y, src.height());
210 RTC_CHECK_GE(offset_x, 0);
211 RTC_CHECK_GE(offset_y, 0);
212
213 // Make sure offset is even so that u/v plane becomes aligned.
214 const int uv_offset_x = offset_x / 2;
215 const int uv_offset_y = offset_y / 2;
216 offset_x = uv_offset_x * 2;
217 offset_y = uv_offset_y * 2;
218
219 const uint8_t* y_plane =
220 src.DataY() + src.StrideY() * offset_y + offset_x;
221 const uint8_t* u_plane =
222 src.DataU() + src.StrideU() * uv_offset_y + uv_offset_x;
223 const uint8_t* v_plane =
224 src.DataV() + src.StrideV() * uv_offset_y + uv_offset_x;
225 int res = libyuv::I420Scale(y_plane, src.StrideY(),
226 u_plane, src.StrideU(),
227 v_plane, src.StrideV(),
228 crop_width, crop_height,
229 MutableDataY(), StrideY(),
230 MutableDataU(), StrideU(),
231 MutableDataV(), StrideV(),
232 width(), height(), libyuv::kFilterBox);
233
234 RTC_DCHECK_EQ(res, 0);
235 }
236
237 void I420Buffer::CropAndScaleFrom(
238 const VideoFrameBuffer& src) {
239 const int crop_width =
240 std::min(src.width(), width() * src.height() / height());
241 const int crop_height =
242 std::min(src.height(), height() * src.width() / width());
243
244 CropAndScaleFrom(
245 src,
246 (src.width() - crop_width) / 2, (src.height() - crop_height) / 2,
247 crop_width, crop_height);
248 }
249
250 void I420Buffer::ScaleFrom(const VideoFrameBuffer& src) {
251 CropAndScaleFrom(src, 0, 0, src.width(), src.height());
252 }
253
254 NativeHandleBuffer::NativeHandleBuffer(void* native_handle, 24 NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
255 int width, 25 int width,
256 int height) 26 int height)
257 : native_handle_(native_handle), width_(width), height_(height) { 27 : native_handle_(native_handle), width_(width), height_(height) {
258 RTC_DCHECK(native_handle != nullptr); 28 RTC_DCHECK(native_handle != nullptr);
259 RTC_DCHECK_GT(width, 0); 29 RTC_DCHECK_GT(width, 0);
260 RTC_DCHECK_GT(height, 0); 30 RTC_DCHECK_GT(height, 0);
261 } 31 }
262 32
263 int NativeHandleBuffer::width() const { 33 int NativeHandleBuffer::width() const {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 void* WrappedI420Buffer::native_handle() const { 123 void* WrappedI420Buffer::native_handle() const {
354 return nullptr; 124 return nullptr;
355 } 125 }
356 126
357 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { 127 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() {
358 RTC_NOTREACHED(); 128 RTC_NOTREACHED();
359 return nullptr; 129 return nullptr;
360 } 130 }
361 131
362 } // namespace webrtc 132 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/video_frame.cc ('k') | webrtc/common_video/video_render_frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698