| 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 |