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 | 10 |
11 #include "webrtc/common_video/interface/video_frame_buffer.h" | 11 #include "webrtc/common_video/interface/video_frame_buffer.h" |
12 | 12 |
13 #include "webrtc/base/bind.h" | 13 #include "webrtc/base/bind.h" |
14 #include "webrtc/base/checks.h" | 14 #include "webrtc/base/checks.h" |
15 | 15 |
16 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. | 16 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. |
17 static const int kBufferAlignment = 64; | 17 static const int kBufferAlignment = 64; |
18 | 18 |
19 namespace webrtc { | 19 namespace webrtc { |
| 20 namespace { |
| 21 |
| 22 // Used in rtc::Bind to keep a buffer alive until destructor is called. |
| 23 static void NoLongerUsedCallback(rtc::scoped_refptr<VideoFrameBuffer> dummy) {} |
| 24 |
| 25 } // anonymous namespace |
20 | 26 |
21 VideoFrameBuffer::~VideoFrameBuffer() {} | 27 VideoFrameBuffer::~VideoFrameBuffer() {} |
22 | 28 |
23 I420Buffer::I420Buffer(int width, int height) | 29 I420Buffer::I420Buffer(int width, int height) |
24 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) { | 30 : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) { |
25 } | 31 } |
26 | 32 |
27 I420Buffer::I420Buffer(int width, | 33 I420Buffer::I420Buffer(int width, |
28 int height, | 34 int height, |
29 int stride_y, | 35 int stride_y, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 | 134 |
129 int NativeHandleBuffer::stride(PlaneType type) const { | 135 int NativeHandleBuffer::stride(PlaneType type) const { |
130 RTC_NOTREACHED(); // Should not be called. | 136 RTC_NOTREACHED(); // Should not be called. |
131 return 0; | 137 return 0; |
132 } | 138 } |
133 | 139 |
134 void* NativeHandleBuffer::native_handle() const { | 140 void* NativeHandleBuffer::native_handle() const { |
135 return native_handle_; | 141 return native_handle_; |
136 } | 142 } |
137 | 143 |
138 WrappedI420Buffer::WrappedI420Buffer(int desired_width, | 144 WrappedI420Buffer::WrappedI420Buffer(int width, |
139 int desired_height, | |
140 int width, | |
141 int height, | 145 int height, |
142 const uint8_t* y_plane, | 146 const uint8_t* y_plane, |
143 int y_stride, | 147 int y_stride, |
144 const uint8_t* u_plane, | 148 const uint8_t* u_plane, |
145 int u_stride, | 149 int u_stride, |
146 const uint8_t* v_plane, | 150 const uint8_t* v_plane, |
147 int v_stride, | 151 int v_stride, |
148 const rtc::Callback0<void>& no_longer_used) | 152 const rtc::Callback0<void>& no_longer_used) |
149 : width_(desired_width), | 153 : width_(width), |
150 height_(desired_height), | 154 height_(height), |
151 y_plane_(y_plane), | 155 y_plane_(y_plane), |
152 u_plane_(u_plane), | 156 u_plane_(u_plane), |
153 v_plane_(v_plane), | 157 v_plane_(v_plane), |
154 y_stride_(y_stride), | 158 y_stride_(y_stride), |
155 u_stride_(u_stride), | 159 u_stride_(u_stride), |
156 v_stride_(v_stride), | 160 v_stride_(v_stride), |
157 no_longer_used_cb_(no_longer_used) { | 161 no_longer_used_cb_(no_longer_used) { |
158 CHECK(width >= desired_width && height >= desired_height); | |
159 | |
160 // Center crop to |desired_width| x |desired_height|. | |
161 // Make sure offset is even so that u/v plane becomes aligned. | |
162 const int offset_x = ((width - desired_width) / 2) & ~1; | |
163 const int offset_y = ((height - desired_height) / 2) & ~1; | |
164 y_plane_ += y_stride_ * offset_y + offset_x; | |
165 u_plane_ += u_stride_ * (offset_y / 2) + (offset_x / 2); | |
166 v_plane_ += v_stride_ * (offset_y / 2) + (offset_x / 2); | |
167 } | 162 } |
168 | 163 |
169 WrappedI420Buffer::~WrappedI420Buffer() { | 164 WrappedI420Buffer::~WrappedI420Buffer() { |
170 no_longer_used_cb_(); | 165 no_longer_used_cb_(); |
171 } | 166 } |
172 | 167 |
173 | |
174 int WrappedI420Buffer::width() const { | 168 int WrappedI420Buffer::width() const { |
175 return width_; | 169 return width_; |
176 } | 170 } |
177 | 171 |
178 int WrappedI420Buffer::height() const { | 172 int WrappedI420Buffer::height() const { |
179 return height_; | 173 return height_; |
180 } | 174 } |
181 | 175 |
182 const uint8_t* WrappedI420Buffer::data(PlaneType type) const { | 176 const uint8_t* WrappedI420Buffer::data(PlaneType type) const { |
183 switch (type) { | 177 switch (type) { |
(...skipping 30 matching lines...) Expand all Loading... |
214 | 208 |
215 void* WrappedI420Buffer::native_handle() const { | 209 void* WrappedI420Buffer::native_handle() const { |
216 return nullptr; | 210 return nullptr; |
217 } | 211 } |
218 | 212 |
219 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { | 213 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { |
220 RTC_NOTREACHED(); | 214 RTC_NOTREACHED(); |
221 return nullptr; | 215 return nullptr; |
222 } | 216 } |
223 | 217 |
| 218 rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( |
| 219 const rtc::scoped_refptr<VideoFrameBuffer>& buffer, |
| 220 int cropped_width, |
| 221 int cropped_height) { |
| 222 CHECK(buffer->native_handle() == nullptr); |
| 223 CHECK_LE(cropped_width, buffer->width()); |
| 224 CHECK_LE(cropped_height, buffer->height()); |
| 225 if (buffer->width() == cropped_width && buffer->height() == cropped_height) |
| 226 return buffer; |
| 227 |
| 228 // Center crop to |cropped_width| x |cropped_height|. |
| 229 // Make sure offset is even so that u/v plane becomes aligned. |
| 230 const int uv_offset_x = (buffer->width() - cropped_width) / 4; |
| 231 const int uv_offset_y = (buffer->height() - cropped_height) / 4; |
| 232 const int offset_x = uv_offset_x * 2; |
| 233 const int offset_y = uv_offset_y * 2; |
| 234 |
| 235 // Const cast to call the correct const-version of data(). |
| 236 const VideoFrameBuffer* const_buffer(buffer.get()); |
| 237 const uint8_t* y_plane = const_buffer->data(kYPlane) + |
| 238 buffer->stride(kYPlane) * offset_y + offset_x; |
| 239 const uint8_t* u_plane = const_buffer->data(kUPlane) + |
| 240 buffer->stride(kUPlane) * uv_offset_y + uv_offset_x; |
| 241 const uint8_t* v_plane = const_buffer->data(kVPlane) + |
| 242 buffer->stride(kVPlane) * uv_offset_y + uv_offset_x; |
| 243 return new rtc::RefCountedObject<WrappedI420Buffer>( |
| 244 cropped_width, cropped_height, |
| 245 y_plane, buffer->stride(kYPlane), |
| 246 u_plane, buffer->stride(kUPlane), |
| 247 v_plane, buffer->stride(kVPlane), |
| 248 rtc::Bind(&NoLongerUsedCallback, buffer)); |
| 249 } |
| 250 |
224 } // namespace webrtc | 251 } // namespace webrtc |
OLD | NEW |