1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#include "webrtc/common_video/libyuv/include/scaler.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13266fc69742dbcff7e1f46e2960470feb1a98650candrew@webrtc.org// NOTE(ajm): Path provided by gyp.
14266fc69742dbcff7e1f46e2960470feb1a98650candrew@webrtc.org#include "libyuv.h"  // NOLINT
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgScaler::Scaler()
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : method_(kScaleBox),
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      src_width_(0),
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      src_height_(0),
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dst_width_(0),
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dst_height_(0),
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      set_(false) {}
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgScaler::~Scaler() {}
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint Scaler::Set(int src_width, int src_height,
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                int dst_width, int dst_height,
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                VideoType src_video_type, VideoType dst_video_type,
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                ScaleMethod method) {
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  set_ = false;
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (src_width < 1 || src_height < 1 || dst_width < 1 || dst_height < 1)
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!SupportedVideoType(src_video_type, dst_video_type))
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  src_width_ = src_width;
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  src_height_ = src_height;
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  dst_width_ = dst_width;
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  dst_height_ = dst_height;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  method_ = method;
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  set_ = true;
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
483bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgint Scaler::Scale(const I420VideoFrame& src_frame,
493bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                  I420VideoFrame* dst_frame) {
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(dst_frame);
513bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  if (src_frame.IsZeroSize())
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!set_)
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -2;
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Making sure that destination frame is of sufficient size.
573bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // Aligning stride values based on width.
583bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  dst_frame->CreateEmptyFrame(dst_width_, dst_height_,
593bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                              dst_width_, (dst_width_ + 1) / 2,
603bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                              (dst_width_ + 1) / 2);
613bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
623bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  return libyuv::I420Scale(src_frame.buffer(kYPlane),
633bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           src_frame.stride(kYPlane),
643bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           src_frame.buffer(kUPlane),
653bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           src_frame.stride(kUPlane),
663bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           src_frame.buffer(kVPlane),
673bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           src_frame.stride(kVPlane),
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           src_width_, src_height_,
693bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           dst_frame->buffer(kYPlane),
703bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           dst_frame->stride(kYPlane),
713bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           dst_frame->buffer(kUPlane),
723bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           dst_frame->stride(kUPlane),
733bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           dst_frame->buffer(kVPlane),
743bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                           dst_frame->stride(kVPlane),
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           dst_width_, dst_height_,
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           libyuv::FilterMode(method_));
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool Scaler::SupportedVideoType(VideoType src_video_type,
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                VideoType dst_video_type) {
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (src_video_type != dst_video_type)
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if ((src_video_type == kI420) || (src_video_type == kIYUV) ||
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      (src_video_type == kYV12))
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return false;
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
92