/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "api/video/video_frame.h"

#include <math.h>
#include <string.h>

#include "api/video/i010_buffer.h"
#include "api/video/i420_buffer.h"
#include "api/video/nv12_buffer.h"
#include "rtc_base/time_utils.h"
#include "test/fake_texture_frame.h"
#include "test/frame_utils.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

// Helper class to delegate calls to appropriate container.
class PlanarYuvBufferFactory {
 public:
  static rtc::scoped_refptr<PlanarYuvBuffer> Create(VideoFrameBuffer::Type type,
                                                    int width,
                                                    int height) {
    switch (type) {
      case VideoFrameBuffer::Type::kI420:
        return I420Buffer::Create(width, height);
      case VideoFrameBuffer::Type::kI010:
        return I010Buffer::Create(width, height);
      default:
        RTC_DCHECK_NOTREACHED();
    }
    return nullptr;
  }

  static rtc::scoped_refptr<PlanarYuvBuffer> Copy(const VideoFrameBuffer& src) {
    switch (src.type()) {
      case VideoFrameBuffer::Type::kI420:
        return I420Buffer::Copy(src);
      case VideoFrameBuffer::Type::kI010:
        return I010Buffer::Copy(*src.GetI010());
      default:
        RTC_DCHECK_NOTREACHED();
    }
    return nullptr;
  }

  static rtc::scoped_refptr<PlanarYuvBuffer> Rotate(const VideoFrameBuffer& src,
                                                    VideoRotation rotation) {
    switch (src.type()) {
      case VideoFrameBuffer::Type::kI420:
        return I420Buffer::Rotate(src, rotation);
      case VideoFrameBuffer::Type::kI010:
        return I010Buffer::Rotate(*src.GetI010(), rotation);
      default:
        RTC_DCHECK_NOTREACHED();
    }
    return nullptr;
  }

  static rtc::scoped_refptr<PlanarYuvBuffer> CropAndScaleFrom(
      const VideoFrameBuffer& src,
      int offset_x,
      int offset_y,
      int crop_width,
      int crop_height) {
    switch (src.type()) {
      case VideoFrameBuffer::Type::kI420: {
        rtc::scoped_refptr<I420Buffer> buffer =
            I420Buffer::Create(crop_width, crop_height);
        buffer->CropAndScaleFrom(*src.GetI420(), offset_x, offset_y, crop_width,
                                 crop_height);
        return buffer;
      }
      case VideoFrameBuffer::Type::kI010: {
        rtc::scoped_refptr<I010Buffer> buffer =
            I010Buffer::Create(crop_width, crop_height);
        buffer->CropAndScaleFrom(*src.GetI010(), offset_x, offset_y, crop_width,
                                 crop_height);
        return buffer;
      }
      default:
        RTC_DCHECK_NOTREACHED();
    }
    return nullptr;
  }

  static rtc::scoped_refptr<PlanarYuvBuffer> CropAndScaleFrom(
      const VideoFrameBuffer& src,
      int crop_width,
      int crop_height) {
    const int out_width =
        std::min(src.width(), crop_width * src.height() / crop_height);
    const int out_height =
        std::min(src.height(), crop_height * src.width() / crop_width);
    return CropAndScaleFrom(src, (src.width() - out_width) / 2,
                            (src.height() - out_height) / 2, out_width,
                            out_height);
  }

  static rtc::scoped_refptr<PlanarYuvBuffer>
  ScaleFrom(const VideoFrameBuffer& src, int crop_width, int crop_height) {
    switch (src.type()) {
      case VideoFrameBuffer::Type::kI420: {
        rtc::scoped_refptr<I420Buffer> buffer =
            I420Buffer::Create(crop_width, crop_height);
        buffer->ScaleFrom(*src.GetI420());
        return buffer;
      }
      case VideoFrameBuffer::Type::kI010: {
        rtc::scoped_refptr<I010Buffer> buffer =
            I010Buffer::Create(crop_width, crop_height);
        buffer->ScaleFrom(*src.GetI010());
        return buffer;
      }
      default:
        RTC_DCHECK_NOTREACHED();
    }
    return nullptr;
  }
};

rtc::scoped_refptr<PlanarYuvBuffer> CreateGradient(VideoFrameBuffer::Type type,
                                                   int width,
                                                   int height) {
  rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create(width, height));
  // Initialize with gradient, Y = 128(x/w + y/h), U = 256 x/w, V = 256 y/h
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      buffer->MutableDataY()[x + y * width] =
          128 * (x * height + y * width) / (width * height);
    }
  }
  int chroma_width = buffer->ChromaWidth();
  int chroma_height = buffer->ChromaHeight();
  for (int x = 0; x < chroma_width; x++) {
    for (int y = 0; y < chroma_height; y++) {
      buffer->MutableDataU()[x + y * chroma_width] =
          255 * x / (chroma_width - 1);
      buffer->MutableDataV()[x + y * chroma_width] =
          255 * y / (chroma_height - 1);
    }
  }
  if (type == VideoFrameBuffer::Type::kI420)
    return buffer;

  RTC_DCHECK(type == VideoFrameBuffer::Type::kI010);
  return I010Buffer::Copy(*buffer);
}

rtc::scoped_refptr<NV12BufferInterface> CreateNV12Gradient(int width,
                                                           int height) {
  rtc::scoped_refptr<NV12Buffer> buffer(NV12Buffer::Create(width, height));
  // Initialize with gradient, Y = 128(x/w + y/h), U = 256 x/w, V = 256 y/h
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      buffer->MutableDataY()[x + y * width] =
          128 * (x * height + y * width) / (width * height);
    }
  }
  int chroma_width = buffer->ChromaWidth();
  int chroma_height = buffer->ChromaHeight();
  for (int x = 0; x < chroma_width; x++) {
    for (int y = 0; y < chroma_height; y++) {
      buffer->MutableDataUV()[x * 2 + y * buffer->StrideUV()] =
          255 * x / (chroma_width - 1);
      buffer->MutableDataUV()[x * 2 + 1 + y * buffer->StrideUV()] =
          255 * y / (chroma_height - 1);
    }
  }
  return buffer;
}

// The offsets and sizes describe the rectangle extracted from the
// original (gradient) frame, in relative coordinates where the
// original frame correspond to the unit square, 0.0 <= x, y < 1.0.
void CheckCrop(const webrtc::I420BufferInterface& frame,
               double offset_x,
               double offset_y,
               double rel_width,
               double rel_height) {
  int width = frame.width();
  int height = frame.height();
  // Check that pixel values in the corners match the gradient used
  // for initialization.
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      // Pixel coordinates of the corner.
      int x = i * (width - 1);
      int y = j * (height - 1);
      // Relative coordinates, range 0.0 - 1.0 correspond to the
      // size of the uncropped input frame.
      double orig_x = offset_x + i * rel_width;
      double orig_y = offset_y + j * rel_height;

      EXPECT_NEAR(frame.DataY()[x + y * frame.StrideY()] / 256.0,
                  (orig_x + orig_y) / 2, 0.02);
      EXPECT_NEAR(frame.DataU()[x / 2 + (y / 2) * frame.StrideU()] / 256.0,
                  orig_x, 0.02);
      EXPECT_NEAR(frame.DataV()[x / 2 + (y / 2) * frame.StrideV()] / 256.0,
                  orig_y, 0.02);
    }
  }
}

void CheckRotate(int width,
                 int height,
                 webrtc::VideoRotation rotation,
                 const webrtc::I420BufferInterface& rotated) {
  int rotated_width = width;
  int rotated_height = height;

  if (rotation == kVideoRotation_90 || rotation == kVideoRotation_270) {
    std::swap(rotated_width, rotated_height);
  }
  EXPECT_EQ(rotated_width, rotated.width());
  EXPECT_EQ(rotated_height, rotated.height());

  // Clock-wise order (with 0,0 at top-left)
  const struct {
    int x;
    int y;
  } corners[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
  // Corresponding corner colors of the frame produced by CreateGradient.
  const struct {
    int y;
    int u;
    int v;
  } colors[] = {{0, 0, 0}, {127, 255, 0}, {255, 255, 255}, {127, 0, 255}};
  int corner_offset = static_cast<int>(rotation) / 90;

  for (int i = 0; i < 4; i++) {
    int j = (i + corner_offset) % 4;
    int x = corners[j].x * (rotated_width - 1);
    int y = corners[j].y * (rotated_height - 1);
    EXPECT_EQ(colors[i].y, rotated.DataY()[x + y * rotated.StrideY()]);
    EXPECT_EQ(colors[i].u,
              rotated.DataU()[(x / 2) + (y / 2) * rotated.StrideU()]);
    EXPECT_EQ(colors[i].v,
              rotated.DataV()[(x / 2) + (y / 2) * rotated.StrideV()]);
  }
}

}  // namespace

TEST(TestVideoFrame, WidthHeightValues) {
  VideoFrame frame =
      VideoFrame::Builder()
          .set_video_frame_buffer(I420Buffer::Create(10, 10, 10, 14, 90))
          .set_rotation(webrtc::kVideoRotation_0)
          .set_timestamp_ms(789)
          .build();
  const int valid_value = 10;
  EXPECT_EQ(valid_value, frame.width());
  EXPECT_EQ(valid_value, frame.height());
  frame.set_timestamp(123u);
  EXPECT_EQ(123u, frame.timestamp());
  frame.set_ntp_time_ms(456);
  EXPECT_EQ(456, frame.ntp_time_ms());
  EXPECT_EQ(789, frame.render_time_ms());
}

TEST(TestVideoFrame, ShallowCopy) {
  uint32_t timestamp = 1;
  int64_t ntp_time_ms = 2;
  int64_t timestamp_us = 3;
  int stride_y = 15;
  int stride_u = 10;
  int stride_v = 10;
  int width = 15;
  int height = 15;

  const int kSizeY = 400;
  const int kSizeU = 100;
  const int kSizeV = 100;
  const VideoRotation kRotation = kVideoRotation_270;
  uint8_t buffer_y[kSizeY];
  uint8_t buffer_u[kSizeU];
  uint8_t buffer_v[kSizeV];
  memset(buffer_y, 16, kSizeY);
  memset(buffer_u, 8, kSizeU);
  memset(buffer_v, 4, kSizeV);

  VideoFrame frame1 = VideoFrame::Builder()
                          .set_video_frame_buffer(I420Buffer::Copy(
                              width, height, buffer_y, stride_y, buffer_u,
                              stride_u, buffer_v, stride_v))
                          .set_rotation(kRotation)
                          .set_timestamp_us(0)
                          .build();
  frame1.set_timestamp(timestamp);
  frame1.set_ntp_time_ms(ntp_time_ms);
  frame1.set_timestamp_us(timestamp_us);
  VideoFrame frame2(frame1);

  EXPECT_EQ(frame1.video_frame_buffer(), frame2.video_frame_buffer());
  const webrtc::I420BufferInterface* yuv1 =
      frame1.video_frame_buffer()->GetI420();
  const webrtc::I420BufferInterface* yuv2 =
      frame2.video_frame_buffer()->GetI420();
  EXPECT_EQ(yuv1->DataY(), yuv2->DataY());
  EXPECT_EQ(yuv1->DataU(), yuv2->DataU());
  EXPECT_EQ(yuv1->DataV(), yuv2->DataV());

  EXPECT_EQ(frame2.timestamp(), frame1.timestamp());
  EXPECT_EQ(frame2.ntp_time_ms(), frame1.ntp_time_ms());
  EXPECT_EQ(frame2.timestamp_us(), frame1.timestamp_us());
  EXPECT_EQ(frame2.rotation(), frame1.rotation());

  frame2.set_timestamp(timestamp + 1);
  frame2.set_ntp_time_ms(ntp_time_ms + 1);
  frame2.set_timestamp_us(timestamp_us + 1);
  frame2.set_rotation(kVideoRotation_90);

  EXPECT_NE(frame2.timestamp(), frame1.timestamp());
  EXPECT_NE(frame2.ntp_time_ms(), frame1.ntp_time_ms());
  EXPECT_NE(frame2.timestamp_us(), frame1.timestamp_us());
  EXPECT_NE(frame2.rotation(), frame1.rotation());
}

TEST(TestVideoFrame, TextureInitialValues) {
  VideoFrame frame = test::FakeNativeBuffer::CreateFrame(
      640, 480, 100, 10, webrtc::kVideoRotation_0);
  EXPECT_EQ(640, frame.width());
  EXPECT_EQ(480, frame.height());
  EXPECT_EQ(100u, frame.timestamp());
  EXPECT_EQ(10, frame.render_time_ms());
  ASSERT_TRUE(frame.video_frame_buffer() != nullptr);
  EXPECT_TRUE(frame.video_frame_buffer()->type() ==
              VideoFrameBuffer::Type::kNative);

  frame.set_timestamp(200);
  EXPECT_EQ(200u, frame.timestamp());
  frame.set_timestamp_us(20);
  EXPECT_EQ(20, frame.timestamp_us());
}

class TestPlanarYuvBuffer
    : public ::testing::TestWithParam<VideoFrameBuffer::Type> {};

rtc::scoped_refptr<I420Buffer> CreateAndFillBuffer() {
  auto buf = I420Buffer::Create(20, 10);
  memset(buf->MutableDataY(), 1, 200);
  memset(buf->MutableDataU(), 2, 50);
  memset(buf->MutableDataV(), 3, 50);
  return buf;
}

TEST_P(TestPlanarYuvBuffer, Copy) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf1;
  switch (GetParam()) {
    case VideoFrameBuffer::Type::kI420: {
      buf1 = CreateAndFillBuffer();
      break;
    }
    case VideoFrameBuffer::Type::kI010: {
      buf1 = I010Buffer::Copy(*CreateAndFillBuffer());
      break;
    }
    default:
      RTC_DCHECK_NOTREACHED();
  }

  rtc::scoped_refptr<PlanarYuvBuffer> buf2 =
      PlanarYuvBufferFactory::Copy(*buf1);
  EXPECT_TRUE(test::FrameBufsEqual(buf1->ToI420(), buf2->ToI420()));
}

TEST_P(TestPlanarYuvBuffer, Scale) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf =
      CreateGradient(GetParam(), 200, 100);

  // Pure scaling, no cropping.
  rtc::scoped_refptr<PlanarYuvBuffer> scaled_buffer =
      PlanarYuvBufferFactory::ScaleFrom(*buf, 150, 75);
  CheckCrop(*scaled_buffer->ToI420(), 0.0, 0.0, 1.0, 1.0);
}

TEST_P(TestPlanarYuvBuffer, CropXCenter) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf =
      CreateGradient(GetParam(), 200, 100);

  // Pure center cropping, no scaling.
  rtc::scoped_refptr<PlanarYuvBuffer> scaled_buffer =
      PlanarYuvBufferFactory::CropAndScaleFrom(*buf, 50, 0, 100, 100);
  CheckCrop(*scaled_buffer->ToI420(), 0.25, 0.0, 0.5, 1.0);
}

TEST_P(TestPlanarYuvBuffer, CropXNotCenter) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf =
      CreateGradient(GetParam(), 200, 100);

  // Non-center cropping, no scaling.
  rtc::scoped_refptr<PlanarYuvBuffer> scaled_buffer =
      PlanarYuvBufferFactory::CropAndScaleFrom(*buf, 25, 0, 100, 100);
  CheckCrop(*scaled_buffer->ToI420(), 0.125, 0.0, 0.5, 1.0);
}

TEST_P(TestPlanarYuvBuffer, CropYCenter) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf =
      CreateGradient(GetParam(), 100, 200);

  // Pure center cropping, no scaling.
  rtc::scoped_refptr<PlanarYuvBuffer> scaled_buffer =
      PlanarYuvBufferFactory::CropAndScaleFrom(*buf, 0, 50, 100, 100);
  CheckCrop(*scaled_buffer->ToI420(), 0.0, 0.25, 1.0, 0.5);
}

TEST_P(TestPlanarYuvBuffer, CropYNotCenter) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf =
      CreateGradient(GetParam(), 100, 200);

  // Pure center cropping, no scaling.
  rtc::scoped_refptr<PlanarYuvBuffer> scaled_buffer =
      PlanarYuvBufferFactory::CropAndScaleFrom(*buf, 0, 25, 100, 100);
  CheckCrop(*scaled_buffer->ToI420(), 0.0, 0.125, 1.0, 0.5);
}

TEST_P(TestPlanarYuvBuffer, CropAndScale16x9) {
  rtc::scoped_refptr<PlanarYuvBuffer> buf =
      CreateGradient(GetParam(), 640, 480);

  // Pure center cropping, no scaling.
  rtc::scoped_refptr<PlanarYuvBuffer> scaled_buffer =
      PlanarYuvBufferFactory::CropAndScaleFrom(*buf, 320, 180);
  CheckCrop(*scaled_buffer->ToI420(), 0.0, 0.125, 1.0, 0.75);
}

INSTANTIATE_TEST_SUITE_P(All,
                         TestPlanarYuvBuffer,
                         ::testing::Values(VideoFrameBuffer::Type::kI420,
                                           VideoFrameBuffer::Type::kI010));

TEST(TestNV12Buffer, CropAndScale) {
  const int kSourceWidth = 640;
  const int kSourceHeight = 480;
  const int kScaledWidth = 320;
  const int kScaledHeight = 240;
  const int kCropLeft = 40;
  const int kCropTop = 30;
  const int kCropRight = 0;
  const int kCropBottom = 30;

  rtc::scoped_refptr<VideoFrameBuffer> buf =
      CreateNV12Gradient(kSourceWidth, kSourceHeight);

  rtc::scoped_refptr<VideoFrameBuffer> scaled_buffer = buf->CropAndScale(
      kCropLeft, kCropTop, kSourceWidth - kCropLeft - kCropRight,
      kSourceHeight - kCropTop - kCropBottom, kScaledWidth, kScaledHeight);

  // Parameters to CheckCrop indicate what part of the source frame is in the
  // scaled frame.
  const float kOffsetX = (kCropLeft + 0.0) / kSourceWidth;
  const float kOffsetY = (kCropTop + 0.0) / kSourceHeight;
  const float kRelativeWidth =
      (kSourceWidth - kCropLeft - kCropRight + 0.0) / kSourceWidth;
  const float kRelativeHeight =
      (kSourceHeight - kCropTop - kCropBottom + 0.0) / kSourceHeight;
  CheckCrop(*scaled_buffer->ToI420(), kOffsetX, kOffsetY, kRelativeWidth,
            kRelativeHeight);
}

class TestPlanarYuvBufferRotate
    : public ::testing::TestWithParam<
          std::tuple<webrtc::VideoRotation, VideoFrameBuffer::Type>> {};

TEST_P(TestPlanarYuvBufferRotate, Rotates) {
  const webrtc::VideoRotation rotation = std::get<0>(GetParam());
  const VideoFrameBuffer::Type type = std::get<1>(GetParam());
  rtc::scoped_refptr<PlanarYuvBuffer> buffer = CreateGradient(type, 640, 480);
  rtc::scoped_refptr<PlanarYuvBuffer> rotated_buffer =
      PlanarYuvBufferFactory::Rotate(*buffer, rotation);
  CheckRotate(640, 480, rotation, *rotated_buffer->ToI420());
}

INSTANTIATE_TEST_SUITE_P(
    Rotate,
    TestPlanarYuvBufferRotate,
    ::testing::Combine(::testing::Values(kVideoRotation_0,
                                         kVideoRotation_90,
                                         kVideoRotation_180,
                                         kVideoRotation_270),
                       ::testing::Values(VideoFrameBuffer::Type::kI420,
                                         VideoFrameBuffer::Type::kI010)));

TEST(TestUpdateRect, CanCompare) {
  VideoFrame::UpdateRect a = {0, 0, 100, 200};
  VideoFrame::UpdateRect b = {0, 0, 100, 200};
  VideoFrame::UpdateRect c = {1, 0, 100, 200};
  VideoFrame::UpdateRect d = {0, 1, 100, 200};
  EXPECT_TRUE(a == b);
  EXPECT_FALSE(a == c);
  EXPECT_FALSE(a == d);
}

TEST(TestUpdateRect, ComputesIsEmpty) {
  VideoFrame::UpdateRect a = {0, 0, 0, 0};
  VideoFrame::UpdateRect b = {0, 0, 100, 200};
  VideoFrame::UpdateRect c = {1, 100, 0, 0};
  VideoFrame::UpdateRect d = {1, 100, 100, 200};
  EXPECT_TRUE(a.IsEmpty());
  EXPECT_FALSE(b.IsEmpty());
  EXPECT_TRUE(c.IsEmpty());
  EXPECT_FALSE(d.IsEmpty());
}

TEST(TestUpdateRectUnion, NonIntersecting) {
  VideoFrame::UpdateRect a = {0, 0, 10, 20};
  VideoFrame::UpdateRect b = {100, 200, 10, 20};
  a.Union(b);
  EXPECT_EQ(a, VideoFrame::UpdateRect({0, 0, 110, 220}));
}

TEST(TestUpdateRectUnion, Intersecting) {
  VideoFrame::UpdateRect a = {0, 0, 10, 10};
  VideoFrame::UpdateRect b = {5, 5, 30, 20};
  a.Union(b);
  EXPECT_EQ(a, VideoFrame::UpdateRect({0, 0, 35, 25}));
}

TEST(TestUpdateRectUnion, OneInsideAnother) {
  VideoFrame::UpdateRect a = {0, 0, 100, 100};
  VideoFrame::UpdateRect b = {5, 5, 30, 20};
  a.Union(b);
  EXPECT_EQ(a, VideoFrame::UpdateRect({0, 0, 100, 100}));
}

TEST(TestUpdateRectIntersect, NonIntersecting) {
  VideoFrame::UpdateRect a = {0, 0, 10, 20};
  VideoFrame::UpdateRect b = {100, 200, 10, 20};
  a.Intersect(b);
  EXPECT_EQ(a, VideoFrame::UpdateRect({0, 0, 0, 0}));
}

TEST(TestUpdateRectIntersect, Intersecting) {
  VideoFrame::UpdateRect a = {0, 0, 10, 10};
  VideoFrame::UpdateRect b = {5, 5, 30, 20};
  a.Intersect(b);
  EXPECT_EQ(a, VideoFrame::UpdateRect({5, 5, 5, 5}));
}

TEST(TestUpdateRectIntersect, OneInsideAnother) {
  VideoFrame::UpdateRect a = {0, 0, 100, 100};
  VideoFrame::UpdateRect b = {5, 5, 30, 20};
  a.Intersect(b);
  EXPECT_EQ(a, VideoFrame::UpdateRect({5, 5, 30, 20}));
}

TEST(TestUpdateRectScale, NoScale) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {100, 50, 100, 200};
  VideoFrame::UpdateRect scaled =
      a.ScaleWithFrame(width, height, 0, 0, width, height, width, height);
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({100, 50, 100, 200}));
}

TEST(TestUpdateRectScale, CropOnly) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {100, 50, 100, 200};
  VideoFrame::UpdateRect scaled = a.ScaleWithFrame(
      width, height, 10, 10, width - 20, height - 20, width - 20, height - 20);
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({90, 40, 100, 200}));
}

TEST(TestUpdateRectScale, CropOnlyToOddOffset) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {100, 50, 100, 200};
  VideoFrame::UpdateRect scaled = a.ScaleWithFrame(
      width, height, 5, 5, width - 10, height - 10, width - 10, height - 10);
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({94, 44, 102, 202}));
}

TEST(TestUpdateRectScale, ScaleByHalf) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {100, 60, 100, 200};
  VideoFrame::UpdateRect scaled = a.ScaleWithFrame(
      width, height, 0, 0, width, height, width / 2, height / 2);
  // Scaled by half and +2 pixels in all directions.
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({48, 28, 54, 104}));
}

TEST(TestUpdateRectScale, CropToUnchangedRegionBelowUpdateRect) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {100, 60, 100, 200};
  VideoFrame::UpdateRect scaled = a.ScaleWithFrame(
      width, height, (width - 10) / 2, (height - 10) / 2, 10, 10, 10, 10);
  // Update is out of the cropped frame.
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({0, 0, 0, 0}));
}

TEST(TestUpdateRectScale, CropToUnchangedRegionAboveUpdateRect) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {600, 400, 10, 10};
  VideoFrame::UpdateRect scaled = a.ScaleWithFrame(
      width, height, (width - 10) / 2, (height - 10) / 2, 10, 10, 10, 10);
  // Update is out of the cropped frame.
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({0, 0, 0, 0}));
}

TEST(TestUpdateRectScale, CropInsideUpdate) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {300, 200, 100, 100};
  VideoFrame::UpdateRect scaled = a.ScaleWithFrame(
      width, height, (width - 10) / 2, (height - 10) / 2, 10, 10, 10, 10);
  // Cropped frame is inside the update rect.
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({0, 0, 10, 10}));
}

TEST(TestUpdateRectScale, CropAndScaleByHalf) {
  const int width = 640;
  const int height = 480;
  VideoFrame::UpdateRect a = {100, 60, 100, 200};
  VideoFrame::UpdateRect scaled =
      a.ScaleWithFrame(width, height, 10, 10, width - 20, height - 20,
                       (width - 20) / 2, (height - 20) / 2);
  // Scaled by half and +3 pixels in all directions, because of odd offset after
  // crop and scale.
  EXPECT_EQ(scaled, VideoFrame::UpdateRect({42, 22, 56, 106}));
}

}  // namespace webrtc
