OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/video_util.h" | 5 #include "media/base/video_util.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "media/base/video_frame.h" | 10 #include "media/base/video_frame.h" |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 uint8* dest_ptr = dest; | 263 uint8* dest_ptr = dest; |
264 for (int col = 0; col < num_cols; ++col) { | 264 for (int col = 0; col < num_cols; ++col) { |
265 *dest_ptr = *src_ptr++; | 265 *dest_ptr = *src_ptr++; |
266 dest_ptr += dest_col_step; | 266 dest_ptr += dest_col_step; |
267 } | 267 } |
268 src += src_stride; | 268 src += src_stride; |
269 dest += dest_row_step; | 269 dest += dest_row_step; |
270 } | 270 } |
271 } | 271 } |
272 | 272 |
| 273 // Common logic for the letterboxing and scale-within/scale-encompassing |
| 274 // functions. Scales |size| to either fit within or encompass |target|, |
| 275 // depending on whether |fit_within_target| is true. |
| 276 static gfx::Size ScaleSizeToTarget(const gfx::Size& size, |
| 277 const gfx::Size& target, |
| 278 bool fit_within_target) { |
| 279 if (size.IsEmpty()) |
| 280 return gfx::Size(); // Corner case: Aspect ratio is undefined. |
| 281 |
| 282 const int64 x = static_cast<int64>(size.width()) * target.height(); |
| 283 const int64 y = static_cast<int64>(size.height()) * target.width(); |
| 284 const bool use_target_width = fit_within_target ? (y < x) : (x < y); |
| 285 return use_target_width ? |
| 286 gfx::Size(target.width(), static_cast<int>(y / size.width())) : |
| 287 gfx::Size(static_cast<int>(x / size.height()), target.height()); |
| 288 } |
| 289 |
273 gfx::Rect ComputeLetterboxRegion(const gfx::Rect& bounds, | 290 gfx::Rect ComputeLetterboxRegion(const gfx::Rect& bounds, |
274 const gfx::Size& content) { | 291 const gfx::Size& content) { |
275 // If |content| has an undefined aspect ratio, let's not try to divide by | 292 // If |content| has an undefined aspect ratio, let's not try to divide by |
276 // zero. | 293 // zero. |
277 if (content.IsEmpty()) | 294 if (content.IsEmpty()) |
278 return gfx::Rect(); | 295 return gfx::Rect(); |
279 | 296 |
280 int64 x = static_cast<int64>(content.width()) * bounds.height(); | 297 gfx::Rect result = bounds; |
281 int64 y = static_cast<int64>(content.height()) * bounds.width(); | 298 result.ClampToCenteredSize(ScaleSizeToTarget(content, bounds.size(), true)); |
| 299 return result; |
| 300 } |
282 | 301 |
283 gfx::Size letterbox(bounds.width(), bounds.height()); | 302 gfx::Size ScaleSizeToFitWithinTarget(const gfx::Size& size, |
284 if (y < x) | 303 const gfx::Size& target) { |
285 letterbox.set_height(static_cast<int>(y / content.width())); | 304 return ScaleSizeToTarget(size, target, true); |
286 else | 305 } |
287 letterbox.set_width(static_cast<int>(x / content.height())); | 306 |
288 gfx::Rect result = bounds; | 307 gfx::Size ScaleSizeToEncompassTarget(const gfx::Size& size, |
289 result.ClampToCenteredSize(letterbox); | 308 const gfx::Size& target) { |
290 return result; | 309 return ScaleSizeToTarget(size, target, false); |
| 310 } |
| 311 |
| 312 gfx::Size PadToMatchAspectRatio(const gfx::Size& size, |
| 313 const gfx::Size& target) { |
| 314 if (target.IsEmpty()) |
| 315 return gfx::Size(); // Aspect ratio is undefined. |
| 316 |
| 317 const int64 x = static_cast<int64>(size.width()) * target.height(); |
| 318 const int64 y = static_cast<int64>(size.height()) * target.width(); |
| 319 if (x < y) |
| 320 return gfx::Size(static_cast<int>(y / target.height()), size.height()); |
| 321 return gfx::Size(size.width(), static_cast<int>(x / target.width())); |
291 } | 322 } |
292 | 323 |
293 void CopyRGBToVideoFrame(const uint8* source, | 324 void CopyRGBToVideoFrame(const uint8* source, |
294 int stride, | 325 int stride, |
295 const gfx::Rect& region_in_frame, | 326 const gfx::Rect& region_in_frame, |
296 VideoFrame* frame) { | 327 VideoFrame* frame) { |
297 const int kY = VideoFrame::kYPlane; | 328 const int kY = VideoFrame::kYPlane; |
298 const int kU = VideoFrame::kUPlane; | 329 const int kU = VideoFrame::kUPlane; |
299 const int kV = VideoFrame::kVPlane; | 330 const int kV = VideoFrame::kVPlane; |
300 CHECK_EQ(frame->stride(kU), frame->stride(kV)); | 331 CHECK_EQ(frame->stride(kU), frame->stride(kV)); |
(...skipping 13 matching lines...) Expand all Loading... |
314 frame->data(kU) + uv_offset, | 345 frame->data(kU) + uv_offset, |
315 frame->data(kV) + uv_offset, | 346 frame->data(kV) + uv_offset, |
316 region_in_frame.width(), | 347 region_in_frame.width(), |
317 region_in_frame.height(), | 348 region_in_frame.height(), |
318 stride, | 349 stride, |
319 frame->stride(kY), | 350 frame->stride(kY), |
320 uv_stride); | 351 uv_stride); |
321 } | 352 } |
322 | 353 |
323 } // namespace media | 354 } // namespace media |
OLD | NEW |