1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/common_video/libyuv/include/scaler.h"
12
13// NOTE(ajm): Path provided by gyp.
14#include "libyuv.h"  // NOLINT
15
16namespace webrtc {
17
18Scaler::Scaler()
19    : method_(kScaleBox),
20      src_width_(0),
21      src_height_(0),
22      dst_width_(0),
23      dst_height_(0),
24      set_(false) {}
25
26Scaler::~Scaler() {}
27
28int Scaler::Set(int src_width, int src_height,
29                int dst_width, int dst_height,
30                VideoType src_video_type, VideoType dst_video_type,
31                ScaleMethod method) {
32  set_ = false;
33  if (src_width < 1 || src_height < 1 || dst_width < 1 || dst_height < 1)
34    return -1;
35
36  if (!SupportedVideoType(src_video_type, dst_video_type))
37    return -1;
38
39  src_width_ = src_width;
40  src_height_ = src_height;
41  dst_width_ = dst_width;
42  dst_height_ = dst_height;
43  method_ = method;
44  set_ = true;
45  return 0;
46}
47
48int Scaler::Scale(const I420VideoFrame& src_frame,
49                  I420VideoFrame* dst_frame) {
50  assert(dst_frame);
51  if (src_frame.IsZeroSize())
52    return -1;
53  if (!set_)
54    return -2;
55
56  // Making sure that destination frame is of sufficient size.
57  // Aligning stride values based on width.
58  dst_frame->CreateEmptyFrame(dst_width_, dst_height_,
59                              dst_width_, (dst_width_ + 1) / 2,
60                              (dst_width_ + 1) / 2);
61
62  return libyuv::I420Scale(src_frame.buffer(kYPlane),
63                           src_frame.stride(kYPlane),
64                           src_frame.buffer(kUPlane),
65                           src_frame.stride(kUPlane),
66                           src_frame.buffer(kVPlane),
67                           src_frame.stride(kVPlane),
68                           src_width_, src_height_,
69                           dst_frame->buffer(kYPlane),
70                           dst_frame->stride(kYPlane),
71                           dst_frame->buffer(kUPlane),
72                           dst_frame->stride(kUPlane),
73                           dst_frame->buffer(kVPlane),
74                           dst_frame->stride(kVPlane),
75                           dst_width_, dst_height_,
76                           libyuv::FilterMode(method_));
77}
78
79bool Scaler::SupportedVideoType(VideoType src_video_type,
80                                VideoType dst_video_type) {
81  if (src_video_type != dst_video_type)
82    return false;
83
84  if ((src_video_type == kI420) || (src_video_type == kIYUV) ||
85      (src_video_type == kYV12))
86    return true;
87
88  return false;
89}
90
91}  // namespace webrtc
92