Chromium Code Reviews

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

Issue 2020593002: Refactor scaling. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Trivial rebase. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « webrtc/common_video/video_frame.cc ('k') | webrtc/media/base/videoframe.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 10
11 #include <algorithm>
12
11 #include "webrtc/common_video/include/video_frame_buffer.h" 13 #include "webrtc/common_video/include/video_frame_buffer.h"
12 14
13 #include "webrtc/base/checks.h" 15 #include "webrtc/base/checks.h"
14 #include "webrtc/base/keep_ref_until_done.h" 16 #include "webrtc/base/keep_ref_until_done.h"
15 #include "libyuv/convert.h" 17 #include "libyuv/convert.h"
18 #include "libyuv/scale.h"
16 19
17 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. 20 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
18 static const int kBufferAlignment = 64; 21 static const int kBufferAlignment = 64;
19 22
20 namespace webrtc { 23 namespace webrtc {
21 24
22 namespace { 25 namespace {
23 26
24 int I420DataSize(int height, int stride_y, int stride_u, int stride_v) { 27 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); 28 return stride_y * height + (stride_u + stride_v) * ((height + 1) / 2);
(...skipping 175 matching lines...)
201 } 204 }
202 205
203 void I420Buffer::SetToBlack() { 206 void I420Buffer::SetToBlack() {
204 RTC_CHECK(libyuv::I420Rect(MutableDataY(), StrideY(), 207 RTC_CHECK(libyuv::I420Rect(MutableDataY(), StrideY(),
205 MutableDataU(), StrideU(), 208 MutableDataU(), StrideU(),
206 MutableDataV(), StrideV(), 209 MutableDataV(), StrideV(),
207 0, 0, width(), height(), 210 0, 0, width(), height(),
208 0, 128, 128) == 0); 211 0, 128, 128) == 0);
209 } 212 }
210 213
214 void I420Buffer::CropAndScaleFrom(
215 const rtc::scoped_refptr<VideoFrameBuffer>& src,
216 int offset_x,
217 int offset_y,
218 int crop_width,
219 int crop_height) {
220 RTC_CHECK_LE(crop_width, src->width());
221 RTC_CHECK_LE(crop_height, src->height());
222 RTC_CHECK_LE(crop_width + offset_x, src->width());
223 RTC_CHECK_LE(crop_height + offset_y, src->height());
224 RTC_CHECK_GE(offset_x, 0);
225 RTC_CHECK_GE(offset_y, 0);
226
227 // Make sure offset is even so that u/v plane becomes aligned.
228 const int uv_offset_x = offset_x / 2;
229 const int uv_offset_y = offset_y / 2;
230 offset_x = uv_offset_x * 2;
231 offset_y = uv_offset_y * 2;
232
233 const uint8_t* y_plane =
234 src->DataY() + src->StrideY() * offset_y + offset_x;
235 const uint8_t* u_plane =
236 src->DataU() + src->StrideU() * uv_offset_y + uv_offset_x;
237 const uint8_t* v_plane =
238 src->DataV() + src->StrideV() * uv_offset_y + uv_offset_x;
239 int res = libyuv::I420Scale(y_plane, src->StrideY(),
240 u_plane, src->StrideU(),
241 v_plane, src->StrideV(),
242 crop_width, crop_height,
243 MutableDataY(), StrideY(),
244 MutableDataU(), StrideU(),
245 MutableDataV(), StrideV(),
246 width(), height(), libyuv::kFilterBox);
247
248 RTC_DCHECK_EQ(res, 0);
249 }
250
251 void I420Buffer::CropAndScaleFrom(
252 const rtc::scoped_refptr<VideoFrameBuffer>& src) {
253 const int crop_width =
254 std::min(src->width(), width() * src->height() / height());
255 const int crop_height =
256 std::min(src->height(), height() * src->width() / width());
257
258 CropAndScaleFrom(
259 src,
260 (src->width() - crop_width) / 2, (src->height() - crop_height) / 2,
261 crop_width, crop_height);
262 }
263
264 void I420Buffer::ScaleFrom(const rtc::scoped_refptr<VideoFrameBuffer>& src) {
265 CropAndScaleFrom(src, 0, 0, src->width(), src->height());
266 }
267
211 NativeHandleBuffer::NativeHandleBuffer(void* native_handle, 268 NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
212 int width, 269 int width,
213 int height) 270 int height)
214 : native_handle_(native_handle), width_(width), height_(height) { 271 : native_handle_(native_handle), width_(width), height_(height) {
215 RTC_DCHECK(native_handle != nullptr); 272 RTC_DCHECK(native_handle != nullptr);
216 RTC_DCHECK_GT(width, 0); 273 RTC_DCHECK_GT(width, 0);
217 RTC_DCHECK_GT(height, 0); 274 RTC_DCHECK_GT(height, 0);
218 } 275 }
219 276
220 int NativeHandleBuffer::width() const { 277 int NativeHandleBuffer::width() const {
(...skipping 88 matching lines...)
309 366
310 void* WrappedI420Buffer::native_handle() const { 367 void* WrappedI420Buffer::native_handle() const {
311 return nullptr; 368 return nullptr;
312 } 369 }
313 370
314 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() { 371 rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() {
315 RTC_NOTREACHED(); 372 RTC_NOTREACHED();
316 return nullptr; 373 return nullptr;
317 } 374 }
318 375
319 rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop(
320 const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
321 int cropped_width,
322 int cropped_height) {
323 RTC_CHECK(buffer->native_handle() == nullptr);
324 RTC_CHECK_LE(cropped_width, buffer->width());
325 RTC_CHECK_LE(cropped_height, buffer->height());
326 if (buffer->width() == cropped_width && buffer->height() == cropped_height)
327 return buffer;
328
329 // Center crop to |cropped_width| x |cropped_height|.
330 // Make sure offset is even so that u/v plane becomes aligned.
331 const int uv_offset_x = (buffer->width() - cropped_width) / 4;
332 const int uv_offset_y = (buffer->height() - cropped_height) / 4;
333 const int offset_x = uv_offset_x * 2;
334 const int offset_y = uv_offset_y * 2;
335
336 const uint8_t* y_plane = buffer->DataY() +
337 buffer->StrideY() * offset_y + offset_x;
338 const uint8_t* u_plane = buffer->DataU() +
339 buffer->StrideU() * uv_offset_y + uv_offset_x;
340 const uint8_t* v_plane = buffer->DataV() +
341 buffer->StrideV() * uv_offset_y + uv_offset_x;
342 return new rtc::RefCountedObject<WrappedI420Buffer>(
343 cropped_width, cropped_height,
344 y_plane, buffer->StrideY(),
345 u_plane, buffer->StrideU(),
346 v_plane, buffer->StrideV(),
347 rtc::KeepRefUntilDone(buffer));
348 }
349
350 } // namespace webrtc 376 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/video_frame.cc ('k') | webrtc/media/base/videoframe.h » ('j') | no next file with comments »

Powered by Google App Engine