128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/*
228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * libjingle
328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Copyright 2004 Google Inc.
428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *
528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *
828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     this list of conditions and the following disclaimer.
1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     and/or other materials provided with the distribution.
1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     derived from this software without specific prior written permission.
1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *
1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */
2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifndef TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_
2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_
3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
31ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org#include <algorithm>
3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <string>
3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
3428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/convert.h"
3528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/convert_from.h"
3628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/planar_functions.h"
3728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/rotate.h"
38a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/base/testutils.h"
39a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/base/videocommon.h"
40a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/base/videoframe.h"
41d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/gunit.h"
42d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/pathutils.h"
43d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/stream.h"
44d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/stringutils.h"
456c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org#include "webrtc/common_video/rotation.h"
4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#if defined(_MSC_VER)
4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define ALIGN16(var) __declspec(align(16)) var
4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else
5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define ALIGN16(var) var __attribute__((aligned(16)))
5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define kImageFilename "faces.1280x720_P420.yuv"
5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define kJpeg420Filename "faces_I420.jpg"
5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define kJpeg422Filename "faces_I422.jpg"
5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define kJpeg444Filename "faces_I444.jpg"
5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define kJpeg411Filename "faces_I411.jpg"
5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define kJpeg400Filename "faces_I400.jpg"
5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Generic test class for testing various video frame implementations.
6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgtemplate <class T>
6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgclass VideoFrameTest : public testing::Test {
6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org public:
6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  VideoFrameTest() : repeat_(1) {}
6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org protected:
6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kWidth = 1280;
6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kHeight = 720;
6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kAlignment = 16;
7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kMinWidthAll = 1;  // Constants for ConstructYUY2AllSizes.
7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kMinHeightAll = 1;
7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kMaxWidthAll = 17;
7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kMaxHeightAll = 23;
7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Load a video frame from disk.
7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  bool LoadFrameNoRepeat(T* frame) {
7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int save_repeat = repeat_;  // This LoadFrame disables repeat.
7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    repeat_ = 1;
7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    bool success = LoadFrame(kImageFilename, cricket::FOURCC_I420,
8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                            kWidth, kHeight, frame);
8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    repeat_ = save_repeat;
8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return success;
8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
850c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  bool LoadFrame(const std::string& filename,
860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 uint32_t format,
870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t width,
880c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t height,
890c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 T* frame) {
906c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    return LoadFrame(filename, format, width, height, width, abs(height),
916c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                     webrtc::kVideoRotation_0, frame);
926c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  }
936c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  bool LoadFrame(const std::string& filename,
940c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 uint32_t format,
950c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t width,
960c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t height,
976c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 int dw,
986c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 int dh,
996c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 webrtc::VideoRotation rotation,
10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 T* frame) {
101d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(filename));
10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return LoadFrame(ms.get(), format, width, height, dw, dh, rotation, frame);
10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Load a video frame from a memory stream.
1050c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  bool LoadFrame(rtc::MemoryStream* ms,
1060c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 uint32_t format,
1070c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t width,
1080c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t height,
1090c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 T* frame) {
1106c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    return LoadFrame(ms, format, width, height, width, abs(height),
1116c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                     webrtc::kVideoRotation_0, frame);
1126c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  }
1136c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  bool LoadFrame(rtc::MemoryStream* ms,
1140c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 uint32_t format,
1150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t width,
1160c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t height,
1176c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 int dw,
1186c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 int dh,
1196c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 webrtc::VideoRotation rotation,
12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 T* frame) {
12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!ms) {
12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return false;
12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t data_size;
12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    bool ret = ms->GetSize(&data_size);
12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ret);
12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (ret) {
1280c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      ret = LoadFrame(reinterpret_cast<uint8_t*>(ms->GetBuffer()), data_size,
12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                      format, width, height, dw, dh, rotation, frame);
13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
13128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return ret;
13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Load a frame from a raw buffer.
1340c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  bool LoadFrame(uint8_t* sample,
1350c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 size_t sample_size,
1360c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 uint32_t format,
1370c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t width,
1380c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t height,
1390c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 T* frame) {
1406c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    return LoadFrame(sample, sample_size, format, width, height, width,
1416c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                     abs(height), webrtc::kVideoRotation_0, frame);
1426c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  }
1430c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  bool LoadFrame(uint8_t* sample,
1446c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 size_t sample_size,
1450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 uint32_t format,
1460c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t width,
1470c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                 int32_t height,
1486c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 int dw,
1496c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 int dh,
1506c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                 webrtc::VideoRotation rotation,
15128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 T* frame) {
15228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    bool ret = false;
15328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      ret = frame->Init(format, width, height, dw, dh,
155b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                        sample, sample_size, 1, 1, 0, rotation);
15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return ret;
15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
160d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  rtc::MemoryStream* LoadSample(const std::string& filename) {
161d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::Pathname path(cricket::GetTestFilePath(filename));
162d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::FileStream> fs(
163d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        rtc::Filesystem::OpenFile(path, "rb"));
16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!fs.get()) {
165a3344cfda4645b3a08fd58813a9ae7b33809c56bthorcarpenter@google.com      LOG(LS_ERROR) << "Could not open test file path: " << path.pathname()
166a3344cfda4645b3a08fd58813a9ae7b33809c56bthorcarpenter@google.com                    << " from current dir "
167a3344cfda4645b3a08fd58813a9ae7b33809c56bthorcarpenter@google.com                    << rtc::Filesystem::GetCurrentDirectory().pathname();
16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    char buf[4096];
172d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
173d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        new rtc::MemoryStream());
174d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::StreamResult res = Flow(fs.get(), buf, sizeof(buf), ms.get());
175d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    if (res != rtc::SR_SUCCESS) {
176a3344cfda4645b3a08fd58813a9ae7b33809c56bthorcarpenter@google.com      LOG(LS_ERROR) << "Could not load test file path: " << path.pathname();
17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return ms.release();
18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Write an I420 frame out to disk.
18428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  bool DumpFrame(const std::string& prefix,
18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 const cricket::VideoFrame& frame) {
18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    char filename[256];
187d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::sprintfn(filename, sizeof(filename), "%s.%dx%d_P420.yuv",
18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                        prefix.c_str(), frame.GetWidth(), frame.GetHeight());
18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = cricket::VideoFrame::SizeOf(frame.GetWidth(),
19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                  frame.GetHeight());
1910c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> out(new uint8_t[out_size]);
19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    frame.CopyToBuffer(out.get(), out_size);
19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return DumpSample(filename, out.get(), out_size);
19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  bool DumpSample(const std::string& filename, const void* buffer, int size) {
197d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::Pathname path(filename);
198d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::FileStream> fs(
199d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        rtc::Filesystem::OpenFile(path, "wb"));
20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!fs.get()) {
20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return false;
20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
204d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    return (fs->Write(buffer, size, NULL, NULL) == rtc::SR_SUCCESS);
20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
20628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Create a test image in the desired color space.
20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // The image is a checkerboard pattern with 63x63 squares, which allows
20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // I420 chroma artifacts to easily be seen on the square boundaries.
21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // The pattern is { { green, orange }, { blue, purple } }
21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // There is also a gradient within each square to ensure that the luma
21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // values are handled properly.
2130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  rtc::MemoryStream* CreateYuv422Sample(uint32_t fourcc,
2140c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                        uint32_t width,
2150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                        uint32_t height) {
21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int y1_pos, y2_pos, u_pos, v_pos;
21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) {
21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
21928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
221d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
222d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        new rtc::MemoryStream);
22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int awidth = (width + 1) & ~1;
22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int size = awidth * 2 * height;
22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!ms->ReserveSize(size)) {
22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
22728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
2280c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    for (uint32_t y = 0; y < height; ++y) {
22928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      for (int x = 0; x < awidth; x += 2) {
2300c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        uint8_t quad[4];
23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        quad[y1_pos] = (x % 63 + y % 63) + 64;
23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        quad[y2_pos] = ((x + 1) % 63 + y % 63) + 64;
23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        quad[u_pos] = ((x / 63) & 1) ? 192 : 64;
23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        quad[v_pos] = ((y / 63) & 1) ? 192 : 64;
23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        ms->Write(quad, sizeof(quad), NULL, NULL);
23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return ms.release();
23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Create a test image for YUV 420 formats with 12 bits per pixel.
2420c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  rtc::MemoryStream* CreateYuvSample(uint32_t width,
2430c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                     uint32_t height,
2440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                     uint32_t bpp) {
245d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
246d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        new rtc::MemoryStream);
24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!ms->ReserveSize(width * height * bpp / 8)) {
24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
24928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
2510c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    for (uint32_t i = 0; i < width * height * bpp / 8; ++i) {
25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      char value = ((i / 63) & 1) ? 192 : 64;
25328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      ms->Write(&value, sizeof(value), NULL, NULL);
25428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return ms.release();
25628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
25728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
2580c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  rtc::MemoryStream* CreateRgbSample(uint32_t fourcc,
2590c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                     uint32_t width,
2600c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                     uint32_t height) {
26128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int r_pos, g_pos, b_pos, bytes;
26228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) {
26328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
26428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
26528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
266d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
267d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        new rtc::MemoryStream);
26828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!ms->ReserveSize(width * height * bytes)) {
26928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return NULL;
27028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
27128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
2720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    for (uint32_t y = 0; y < height; ++y) {
2730c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      for (uint32_t x = 0; x < width; ++x) {
2740c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        uint8_t rgb[4] = {255, 255, 255, 255};
27528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[r_pos] = ((x / 63) & 1) ? 224 : 32;
27628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[g_pos] = (x % 63 + y % 63) + 96;
27728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[b_pos] = ((y / 63) & 1) ? 224 : 32;
27828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        ms->Write(rgb, bytes, NULL, NULL);
27928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
28028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
28128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return ms.release();
28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
28428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Simple conversion routines to verify the optimized VideoFrame routines.
28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Converts from the specified colorspace to I420.
286d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  bool ConvertYuv422(const rtc::MemoryStream* ms,
2870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     uint32_t fourcc,
2880c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     uint32_t width,
2890c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     uint32_t height,
29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                     T* frame) {
29128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int y1_pos, y2_pos, u_pos, v_pos;
29228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) {
29328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return false;
29428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
29528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
2960c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* start = reinterpret_cast<const uint8_t*>(ms->GetBuffer());
29728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int awidth = (width + 1) & ~1;
298b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    frame->InitToBlack(width, height, 1, 1, 0);
29928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride_y = frame->GetYPitch();
30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride_u = frame->GetUPitch();
30128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride_v = frame->GetVPitch();
3020c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    for (uint32_t y = 0; y < height; ++y) {
3030c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      for (uint32_t x = 0; x < width; x += 2) {
3040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        const uint8_t* quad1 = start + (y * awidth + x) * 2;
30528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        frame->GetYPlane()[stride_y * y + x] = quad1[y1_pos];
30628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        if ((x + 1) < width) {
30728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          frame->GetYPlane()[stride_y * y + x + 1] = quad1[y2_pos];
30828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        }
30928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        if ((y & 1) == 0) {
3100c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström          const uint8_t* quad2 = quad1 + awidth * 2;
31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          if ((y + 1) >= height) {
31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org            quad2 = quad1;
31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          }
31428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          frame->GetUPlane()[stride_u * (y / 2) + x / 2] =
31528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org              (quad1[u_pos] + quad2[u_pos] + 1) / 2;
31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          frame->GetVPlane()[stride_v * (y / 2) + x / 2] =
31728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org              (quad1[v_pos] + quad2[v_pos] + 1) / 2;
31828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        }
31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
32128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return true;
32228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
32328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
32428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Convert RGB to 420.
32528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // A negative height inverts the image.
326d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  bool ConvertRgb(const rtc::MemoryStream* ms,
3270c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                  uint32_t fourcc,
3280c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                  int32_t width,
3290c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                  int32_t height,
33028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  T* frame) {
33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int r_pos, g_pos, b_pos, bytes;
33228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) {
33328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return false;
33428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
33528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int pitch = width * bytes;
3360c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* start = reinterpret_cast<const uint8_t*>(ms->GetBuffer());
33728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (height < 0) {
33828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      height = -height;
33928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      start = start + pitch * (height - 1);
34028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      pitch = -pitch;
34128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
342b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    frame->InitToBlack(width, height, 1, 1, 0);
34328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride_y = frame->GetYPitch();
34428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride_u = frame->GetUPitch();
34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride_v = frame->GetVPitch();
3460c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    for (int32_t y = 0; y < height; y += 2) {
3470c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      for (int32_t x = 0; x < width; x += 2) {
3480c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        const uint8_t* rgb[4];
3490c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        uint8_t yuv[4][3];
35028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[0] = start + y * pitch + x * bytes;
35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[1] = rgb[0] + ((x + 1) < width ? bytes : 0);
35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[2] = rgb[0] + ((y + 1) < height ? pitch : 0);
35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        rgb[3] = rgb[2] + ((x + 1) < width ? bytes : 0);
35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        for (size_t i = 0; i < 4; ++i) {
35528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          ConvertRgbPixel(rgb[i][r_pos], rgb[i][g_pos], rgb[i][b_pos],
35628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &yuv[i][0], &yuv[i][1], &yuv[i][2]);
35728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        }
35828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        frame->GetYPlane()[stride_y * y + x] = yuv[0][0];
35928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        if ((x + 1) < width) {
36028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          frame->GetYPlane()[stride_y * y + x + 1] = yuv[1][0];
36128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        }
36228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        if ((y + 1) < height) {
36328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          frame->GetYPlane()[stride_y * (y + 1) + x] = yuv[2][0];
36428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          if ((x + 1) < width) {
36528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org            frame->GetYPlane()[stride_y * (y + 1) + x + 1] = yuv[3][0];
36628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          }
36728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        }
36828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        frame->GetUPlane()[stride_u * (y / 2) + x / 2] =
36928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org            (yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1] + 2) / 4;
37028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        frame->GetVPlane()[stride_v * (y / 2) + x / 2] =
37128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org            (yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2] + 2) / 4;
37228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
37328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
37428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return true;
37528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia.
3780c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  void ConvertRgbPixel(uint8_t r,
3790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                       uint8_t g,
3800c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                       uint8_t b,
3810c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                       uint8_t* y,
3820c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                       uint8_t* u,
3830c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                       uint8_t* v) {
38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    *y = static_cast<int>(.257 * r + .504 * g + .098 * b) + 16;
38528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    *u = static_cast<int>(-.148 * r - .291 * g + .439 * b) + 128;
38628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    *v = static_cast<int>(.439 * r - .368 * g - .071 * b) + 128;
38728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
38828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
3890c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  bool GetYuv422Packing(uint32_t fourcc,
3900c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        int* y1_pos,
3910c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        int* y2_pos,
3920c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        int* u_pos,
3930c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        int* v_pos) {
39428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (fourcc == cricket::FOURCC_YUY2) {
39528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *y1_pos = 0; *u_pos = 1; *y2_pos = 2; *v_pos = 3;
39628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_UYVY) {
39728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *u_pos = 0; *y1_pos = 1; *v_pos = 2; *y2_pos = 3;
39828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else {
39928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return false;
40028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
40128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return true;
40228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
40328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
4040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  bool GetRgbPacking(uint32_t fourcc,
4050c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     int* r_pos,
4060c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     int* g_pos,
4070c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     int* b_pos,
4080c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     int* bytes) {
40928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (fourcc == cricket::FOURCC_RAW) {
41028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 3;  // RGB in memory.
41128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_24BG) {
41228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 3;  // BGR in memory.
41328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_ABGR) {
41428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 4;  // RGBA in memory.
41528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_BGRA) {
41628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *r_pos = 1; *g_pos = 2; *b_pos = 3; *bytes = 4;  // ARGB in memory.
41728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_ARGB) {
41828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 4;  // BGRA in memory.
41928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else {
42028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return false;
42128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
42228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return true;
42328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
42428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
42528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Comparison functions for testing.
42628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsNull(const cricket::VideoFrame& frame) {
42728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return !frame.GetYPlane();
42828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
42928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
43028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsSize(const cricket::VideoFrame& frame,
4310c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     uint32_t width,
4320c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     uint32_t height) {
4330c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    return !IsNull(frame) && frame.GetYPitch() >= static_cast<int32_t>(width) &&
4340c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           frame.GetUPitch() >= static_cast<int32_t>(width) / 2 &&
4350c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           frame.GetVPitch() >= static_cast<int32_t>(width) / 2 &&
4360c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           frame.GetWidth() == width && frame.GetHeight() == height;
43728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
43828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
43928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsPlaneEqual(const std::string& name,
4400c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                           const uint8_t* plane1,
4410c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                           uint32_t pitch1,
4420c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                           const uint8_t* plane2,
4430c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                           uint32_t pitch2,
4440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                           uint32_t width,
4450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                           uint32_t height,
44628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           int max_error) {
4470c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* r1 = plane1;
4480c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* r2 = plane2;
4490c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    for (uint32_t y = 0; y < height; ++y) {
4500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      for (uint32_t x = 0; x < width; ++x) {
45128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        if (abs(static_cast<int>(r1[x] - r2[x])) > max_error) {
45228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          LOG(LS_INFO) << "IsPlaneEqual(" << name << "): pixel["
45328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                       << x << "," << y << "] differs: "
45428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                       << static_cast<int>(r1[x]) << " vs "
45528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                       << static_cast<int>(r2[x]);
45628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org          return false;
45728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        }
45828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
45928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      r1 += pitch1;
46028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      r2 += pitch2;
46128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
46228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return true;
46328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
46428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
46528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsEqual(const cricket::VideoFrame& frame,
4660c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      size_t width,
4670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      size_t height,
4680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      size_t pixel_width,
4690c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      size_t pixel_height,
4700c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      int64_t time_stamp,
4710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      const uint8_t* y,
4720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      uint32_t ypitch,
4730c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      const uint8_t* u,
4740c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      uint32_t upitch,
4750c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      const uint8_t* v,
4760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                      uint32_t vpitch,
47728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                      int max_error) {
4780c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    return IsSize(frame, static_cast<uint32_t>(width),
4790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                  static_cast<uint32_t>(height)) &&
4800c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           frame.GetPixelWidth() == pixel_width &&
4810c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           frame.GetPixelHeight() == pixel_height &&
4820c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           frame.GetTimeStamp() == time_stamp &&
4830c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           IsPlaneEqual("y", frame.GetYPlane(), frame.GetYPitch(), y, ypitch,
4840c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        static_cast<uint32_t>(width),
4850c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        static_cast<uint32_t>(height), max_error) &&
4860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           IsPlaneEqual("u", frame.GetUPlane(), frame.GetUPitch(), u, upitch,
4870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        static_cast<uint32_t>((width + 1) / 2),
4880c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        static_cast<uint32_t>((height + 1) / 2), max_error) &&
4890c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           IsPlaneEqual("v", frame.GetVPlane(), frame.GetVPitch(), v, vpitch,
4900c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        static_cast<uint32_t>((width + 1) / 2),
4910c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        static_cast<uint32_t>((height + 1) / 2), max_error);
49228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
49328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
49428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsEqual(const cricket::VideoFrame& frame1,
49528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                      const cricket::VideoFrame& frame2,
49628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                      int max_error) {
49728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return IsEqual(frame1,
49828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetWidth(), frame2.GetHeight(),
49928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetPixelWidth(), frame2.GetPixelHeight(),
500b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                   frame2.GetTimeStamp(),
50128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetYPlane(), frame2.GetYPitch(),
50228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetUPlane(), frame2.GetUPitch(),
50328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetVPlane(), frame2.GetVPitch(),
50428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   max_error);
50528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
50628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
50728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsEqualWithCrop(const cricket::VideoFrame& frame1,
50828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              const cricket::VideoFrame& frame2,
50928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              int hcrop, int vcrop, int max_error) {
51028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return frame1.GetWidth() <= frame2.GetWidth() &&
51128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org           frame1.GetHeight() <= frame2.GetHeight() &&
51228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org           IsEqual(frame1,
51328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetWidth() - hcrop * 2,
51428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetHeight() - vcrop * 2,
51528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetPixelWidth(), frame2.GetPixelHeight(),
516b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                   frame2.GetTimeStamp(),
51728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetYPlane() + vcrop * frame2.GetYPitch()
51828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                       + hcrop,
51928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetYPitch(),
52028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetUPlane() + vcrop * frame2.GetUPitch() / 2
52128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                       + hcrop / 2,
52228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetUPitch(),
52328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetVPlane() + vcrop * frame2.GetVPitch() / 2
52428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                       + hcrop / 2,
52528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   frame2.GetVPitch(),
52628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                   max_error);
52728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
52828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
52928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool IsBlack(const cricket::VideoFrame& frame) {
53028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return !IsNull(frame) &&
53128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        *frame.GetYPlane() == 16 &&
53228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        *frame.GetUPlane() == 128 &&
53328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        *frame.GetVPlane() == 128;
53428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
53528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
53628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  ////////////////////////
53728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Construction tests //
53828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  ////////////////////////
53928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
54028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a I420 buffer.
54128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI420() {
54228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
54328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsNull(frame));
544d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
54528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
54628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420,
54728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame));
54828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
5490c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* y = reinterpret_cast<uint8_t*>(ms.get()->GetBuffer());
5500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* u = y + kWidth * kHeight;
5510c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* v = u + kWidth * kHeight / 4;
5520c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, y, kWidth, u,
5530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        kWidth / 2, v, kWidth / 2, 0));
55428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
55528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
55628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YV12 buffer.
55728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYV12() {
55828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
559d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
56028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
56128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YV12,
56228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame));
56328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
5640c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* y = reinterpret_cast<uint8_t*>(ms.get()->GetBuffer());
5650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* v = y + kWidth * kHeight;
5660c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* u = v + kWidth * kHeight / 4;
5670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, y, kWidth, u,
5680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                        kWidth / 2, v, kWidth / 2, 0));
56928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
57028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
57128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a I422 buffer.
57228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI422() {
57328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
57428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
57528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t buf_size = kWidth * kHeight * 2;
5760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[buf_size + kAlignment]);
5770c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* y = ALIGNP(buf.get(), kAlignment);
5780c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* u = y + kWidth * kHeight;
5790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* v = u + (kWidth / 2) * kHeight;
58028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(),
58128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    frame1.GetUPlane(), frame1.GetUPitch(),
58228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    frame1.GetVPlane(), frame1.GetVPitch(),
58328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    y, kWidth,
58428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    u, kWidth / 2,
58528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    v, kWidth / 2,
58628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    kWidth, kHeight));
58728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(y, buf_size, cricket::FOURCC_I422,
58828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
5899caf2765b285f7511d8355177c2d55209d7573e4wu@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 1));
59028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
59128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
59228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer.
59328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2() {
59428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
59528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
59628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t buf_size = kWidth * kHeight * 2;
5970c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[buf_size + kAlignment]);
5980c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* yuy2 = ALIGNP(buf.get(), kAlignment);
59928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(),
60028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    frame1.GetUPlane(), frame1.GetUPitch(),
60128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    frame1.GetVPlane(), frame1.GetVPitch(),
60228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    yuy2, kWidth * 2,
60328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    kWidth, kHeight));
60428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2,
60528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
60628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
60728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
60828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
60928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer with buffer unaligned.
61028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2Unaligned() {
61128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
61228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
61328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t buf_size = kWidth * kHeight * 2;
6140c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[buf_size + kAlignment + 1]);
6150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* yuy2 = ALIGNP(buf.get(), kAlignment) + 1;
61628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(),
61728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    frame1.GetUPlane(), frame1.GetUPitch(),
61828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    frame1.GetVPlane(), frame1.GetVPitch(),
61928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    yuy2, kWidth * 2,
62028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                    kWidth, kHeight));
62128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2,
62228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
62328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
62428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
62528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
62628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a wide YUY2 buffer.
62728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Normal is 1280x720.  Wide is 12800x72
62828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2Wide() {
62928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
630d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
63128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth * 10, kHeight / 10));
63228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
63328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2,
63428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              kWidth * 10, kHeight / 10,
63528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              &frame1));
63628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
63728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth * 10, kHeight / 10, &frame2));
63828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
63928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
64028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
64128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a UYVY buffer.
64228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructUyvy() {
64328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
644d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
64528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
64628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
64728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
64828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              &frame1));
64928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
65028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
65128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
65228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
65328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
65428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a random buffer.
65528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // We are merely verifying that the code succeeds and is free of crashes.
65628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructM420() {
65728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
658d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
65928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
66028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
66128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_M420,
66228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame));
66328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
66428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
66528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructNV21() {
66628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
667d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
66828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
66928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
67028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_NV21,
67128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame));
67228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
67328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
67428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructNV12() {
67528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
676d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
67728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
67828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
67928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_NV12,
68028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame));
68128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
68228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
68328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a ABGR buffer
68428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
68528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructABGR() {
68628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
687d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
68828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ABGR, kWidth, kHeight));
68928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
69028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ABGR, kWidth, kHeight,
69128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           &frame1));
69228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ABGR,
69328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
69428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
69528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
69628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
69728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a ARGB buffer
69828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
69928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGB() {
70028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
701d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
70228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));
70328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
70428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,
70528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           &frame1));
70628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
70728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
70828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
70928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
71028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
71128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a wide ARGB buffer
71228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Normal is 1280x720.  Wide is 12800x72
71328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGBWide() {
71428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
715d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
71628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth * 10, kHeight / 10));
71728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
71828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB,
71928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           kWidth * 10, kHeight / 10, &frame1));
72028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
72128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth * 10, kHeight / 10, &frame2));
72228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
72328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
72428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
72528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an BGRA buffer.
72628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
72728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructBGRA() {
72828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
729d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
73028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_BGRA, kWidth, kHeight));
73128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
73228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_BGRA, kWidth, kHeight,
73328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           &frame1));
73428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_BGRA,
73528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
73628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
73728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
73828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
73928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a 24BG buffer.
74028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
74128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void Construct24BG() {
74228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
743d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
74428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_24BG, kWidth, kHeight));
74528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
74628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_24BG, kWidth, kHeight,
74728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           &frame1));
74828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_24BG,
74928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
75028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
75128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
75228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
75328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a raw RGB buffer.
75428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
75528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructRaw() {
75628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
757d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
75828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_RAW, kWidth, kHeight));
75928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
76028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_RAW, kWidth, kHeight,
76128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           &frame1));
76228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_RAW,
76328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
76428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
76528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
76628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
76728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a RGB565 buffer
76828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructRGB565() {
76928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
77028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
7710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]);
7720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* out = ALIGNP(outbuf.get(), kAlignment);
77328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
77428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
77528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBP,
77628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out,
77728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size, kWidth * 2));
77828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBP,
77928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
78028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 20));
78128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
78228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
78328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a ARGB1555 buffer
78428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGB1555() {
78528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
78628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
7870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]);
7880c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* out = ALIGNP(outbuf.get(), kAlignment);
78928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
79028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
79128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBO,
79228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out,
79328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size, kWidth * 2));
79428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBO,
79528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
79628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 20));
79728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
79828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
79928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a ARGB4444 buffer
80028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGB4444() {
80128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
80228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
8030c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]);
8040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* out = ALIGNP(outbuf.get(), kAlignment);
80528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
80628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
80728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_R444,
80828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out,
80928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size, kWidth * 2));
81028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_R444,
81128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
81228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 20));
81328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
81428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
81528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Macro to help test different rotations
8164b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org#define TEST_MIRROR(FOURCC, BPP)                                               \
8176c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  void Construct##FOURCC##Mirror() {                                           \
8184b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    T frame1, frame2, frame3;                                                  \
8196c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                                     \
8204b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org        CreateYuvSample(kWidth, kHeight, BPP));                                \
8214b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
8226c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC, kWidth,          \
8236c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          -kHeight, kWidth, kHeight,                           \
8246c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          webrtc::kVideoRotation_180, &frame1));               \
8254b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    size_t data_size;                                                          \
8264b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    bool ret = ms->GetSize(&data_size);                                        \
8274b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    EXPECT_TRUE(ret);                                                          \
8286c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC, kWidth, kHeight, kWidth, \
8296c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                            kHeight,                                           \
8300c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                            reinterpret_cast<uint8_t*>(ms->GetBuffer()),       \
831b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                            data_size, 1, 1, 0, webrtc::kVideoRotation_0));    \
8324b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    int width_rotate = static_cast<int>(frame1.GetWidth());                    \
8334b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    int height_rotate = static_cast<int>(frame1.GetHeight());                  \
834b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0));     \
8356c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    libyuv::I420Mirror(                                                        \
8366c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame2.GetYPlane(), frame2.GetYPitch(), frame2.GetUPlane(),            \
8376c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame2.GetUPitch(), frame2.GetVPlane(), frame2.GetVPitch(),            \
8386c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame3.GetYPlane(), frame3.GetYPitch(), frame3.GetUPlane(),            \
8396c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame3.GetUPitch(), frame3.GetVPlane(), frame3.GetVPitch(), kWidth,    \
8406c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        kHeight);                                                              \
8414b320cf2149b317c9ab08fe7c7017f5756651e69magjed@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));                                   \
84228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
84328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
84428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_MIRROR(I420, 420)
84528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
84628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Macro to help test different rotations
84728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define TEST_ROTATE(FOURCC, BPP, ROTATE)                                       \
8486c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org  void Construct##FOURCC##Rotate##ROTATE() {                                   \
84928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2, frame3;                                                  \
8506c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                                     \
85128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, BPP));                                \
85228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
8536c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC, kWidth, kHeight, \
8546c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_##ROTATE,    \
8556c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame1));                                           \
85628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t data_size;                                                          \
85728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    bool ret = ms->GetSize(&data_size);                                        \
85828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ret);                                                          \
8596c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC, kWidth, kHeight, kWidth, \
8606c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                            kHeight,                                           \
8610c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                            reinterpret_cast<uint8_t*>(ms->GetBuffer()),       \
862b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                            data_size, 1, 1, 0, webrtc::kVideoRotation_0));    \
863a3344cfda4645b3a08fd58813a9ae7b33809c56bthorcarpenter@google.com    int width_rotate = static_cast<int>(frame1.GetWidth());                    \
864a3344cfda4645b3a08fd58813a9ae7b33809c56bthorcarpenter@google.com    int height_rotate = static_cast<int>(frame1.GetHeight());                  \
865b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0));     \
8666c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    libyuv::I420Rotate(                                                        \
8676c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame2.GetYPlane(), frame2.GetYPitch(), frame2.GetUPlane(),            \
8686c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame2.GetUPitch(), frame2.GetVPlane(), frame2.GetVPitch(),            \
8696c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame3.GetYPlane(), frame3.GetYPitch(), frame3.GetUPlane(),            \
8706c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        frame3.GetUPitch(), frame3.GetVPlane(), frame3.GetVPitch(), kWidth,    \
8716c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org        kHeight, libyuv::kRotate##ROTATE);                                     \
87228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));                                   \
87328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
87428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
87528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image with rotation.
87628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(I420, 12, 0)
87728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(I420, 12, 90)
87828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(I420, 12, 180)
87928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(I420, 12, 270)
88028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 0)
88128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 90)
88228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 180)
88328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 270)
88428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 0)
88528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 90)
88628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 180)
88728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 270)
88828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 0)
88928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 90)
89028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 180)
89128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 270)
89228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 0)
89328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 90)
89428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 180)
89528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 270)
89628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 0)
89728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 90)
89828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 180)
89928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 270)
90028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
90128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a UYVY buffer rotated 90 degrees.
90228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructUyvyRotate90() {
90328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame2;
904d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
90528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
90628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9076c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
9086c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_90, &frame2));
90928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
91028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
91128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a UYVY buffer rotated 180 degrees.
91228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructUyvyRotate180() {
91328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame2;
914d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
91528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
91628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9176c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
9186c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_180,
9196c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
92028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
92128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
92228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a UYVY buffer rotated 270 degrees.
92328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructUyvyRotate270() {
92428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame2;
925d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
92628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
92728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9286c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
9296c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_270,
9306c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
93128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
93228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
93328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer rotated 90 degrees.
93428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2Rotate90() {
93528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame2;
936d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
93728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
93828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9396c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
9406c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_90, &frame2));
94128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
94228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
94328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer rotated 180 degrees.
94428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2Rotate180() {
94528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame2;
946d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
94728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
94828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9496c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
9506c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_180,
9516c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
95228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
95328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
95428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer rotated 270 degrees.
95528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2Rotate270() {
95628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame2;
957d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
95828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
95928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9606c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
9616c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight, webrtc::kVideoRotation_270,
9626c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
96328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
96428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
96528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test 1 pixel edge case image I420 buffer.
96628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI4201Pixel() {
96728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
9680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t pixel[3] = {1, 2, 3};
96928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
9706c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1, pixel,
971b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                             sizeof(pixel), 1, 1, 0, webrtc::kVideoRotation_0));
97228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
9730c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* y = pixel;
9740c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* u = y + 1;
9750c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* v = u + 1;
9760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    EXPECT_TRUE(IsEqual(frame, 1, 1, 1, 1, 0, y, 1, u, 1, v, 1, 0));
97728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
97828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
97914ee8cc9c7c04f0125bdb1e46226918ca090a66bmagjed@webrtc.org  // Test 5 pixel edge case image.
98028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI4205Pixel() {
98128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
9820c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t pixels5x5[5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) * 2];
98328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    memset(pixels5x5, 1, 5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) *  2);
98428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
9856c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 5, 5, 5, 5, pixels5x5,
986b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                             sizeof(pixels5x5), 1, 1, 0,
9876c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                             webrtc::kVideoRotation_0));
98828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
98914ee8cc9c7c04f0125bdb1e46226918ca090a66bmagjed@webrtc.org    EXPECT_EQ(5u, frame.GetWidth());
99014ee8cc9c7c04f0125bdb1e46226918ca090a66bmagjed@webrtc.org    EXPECT_EQ(5u, frame.GetHeight());
99114ee8cc9c7c04f0125bdb1e46226918ca090a66bmagjed@webrtc.org    EXPECT_EQ(5, frame.GetYPitch());
99214ee8cc9c7c04f0125bdb1e46226918ca090a66bmagjed@webrtc.org    EXPECT_EQ(3, frame.GetUPitch());
99314ee8cc9c7c04f0125bdb1e46226918ca090a66bmagjed@webrtc.org    EXPECT_EQ(3, frame.GetVPitch());
99428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
99528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
99628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test 1 pixel edge case image ARGB buffer.
99728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGB1Pixel() {
99828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
9990c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t pixel[4] = {64, 128, 192, 255};
100028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
10016c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 1, 1, 1, 1, pixel,
1002b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                             sizeof(pixel), 1, 1, 0,
10036c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                             webrtc::kVideoRotation_0));
100428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
100528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Convert back to ARGB.
100628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = 4;
10070c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]);
10080c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* out = ALIGNP(outbuf.get(), kAlignment);
100928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
101028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
101128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out,
101228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size,    // buffer size
101328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size));  // stride
101428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  #ifdef USE_LMI_CONVERT
101528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // TODO(fbarchard): Expected to fail, but not crash.
101628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_FALSE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2));
101728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  #else
101828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // TODO(fbarchard): Check for overwrite.
101928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2));
102028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  #endif
102128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
102228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
102328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test Black, White and Grey pixels.
102428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGBBlackWhitePixel() {
102528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
10260c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t pixel[10 * 4] = {0,   0,   0,   255,   // Black.
10270c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             0,   0,   0,   255,   // Black.
10280c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             64,  64,  64,  255,   // Dark Grey.
10290c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             64,  64,  64,  255,   // Dark Grey.
10300c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             128, 128, 128, 255,   // Grey.
10310c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             128, 128, 128, 255,   // Grey.
10320c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             196, 196, 196, 255,   // Light Grey.
10330c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             196, 196, 196, 255,   // Light Grey.
10340c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             255, 255, 255, 255,   // White.
10350c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             255, 255, 255, 255};  // White.
103628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
103728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
10386c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 10, 1, 10, 1, pixel,
1039b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                             sizeof(pixel), 1, 1, 0,
10406c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                             webrtc::kVideoRotation_0));
104128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
104228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Convert back to ARGB
104328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = 10 * 4;
10440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]);
10450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* out = ALIGNP(outbuf.get(), kAlignment);
104628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
104728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
104828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out,
104928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size,    // buffer size.
105028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                 out_size));  // stride.
105128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("argb", pixel, out_size,
105228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             out, out_size,
105328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             out_size, 1, 2));
105428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
105528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
105628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I420 buffer with horizontal cropping.
105728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI420CropHorizontal() {
105828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
105928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
106028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_I420, kWidth, kHeight,
10616c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth * 3 / 4, kHeight, webrtc::kVideoRotation_0,
10626c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
106328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, kWidth / 8, 0, 0));
106428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
106528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
106628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer with horizontal cropping.
106728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2CropHorizontal() {
106828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
1069d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
107028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
107128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
107228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
107328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              &frame1));
107428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
10756c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth * 3 / 4, kHeight, webrtc::kVideoRotation_0,
10766c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
107728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, kWidth / 8, 0, 0));
107828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
107928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
108028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an ARGB buffer with horizontal cropping.
108128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGBCropHorizontal() {
108228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
1083d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
108428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));
108528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
108628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,
108728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                           &frame1));
108828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,
10896c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth * 3 / 4, kHeight, webrtc::kVideoRotation_0,
10906c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
109128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, kWidth / 8, 0, 2));
109228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
109328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
109428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I420 buffer, cropping top and bottom.
109528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI420CropVertical() {
109628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
109728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
109828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_I420, kWidth, kHeight,
10996c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          kWidth, kHeight * 3 / 4, webrtc::kVideoRotation_0,
11006c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                          &frame2));
110128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, 0, kHeight / 8, 0));
110228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
110328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
110428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from I420 synonymous formats.
110528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructI420Aliases() {
110628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2, frame3;
110728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_I420, kWidth, kHeight,
110828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &frame1));
110928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_IYUV, kWidth, kHeight,
111028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &frame2));
111128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_YU12, kWidth, kHeight,
111228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &frame3));
111328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
111428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));
111528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
111628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
111728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I420 MJPG buffer.
111828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructMjpgI420() {
111928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
112028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
112128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg420Filename,
112228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
112328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
112428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
112528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
112628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I422 MJPG buffer.
112728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructMjpgI422() {
112828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
112928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
113028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg422Filename,
113128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
113228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
113328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
113428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
113528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I444 MJPG buffer.
113628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructMjpgI444() {
113728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
113828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
113928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg444Filename,
114028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
114128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
114228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
114328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
114428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I444 MJPG buffer.
114528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructMjpgI411() {
114628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
114728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
114828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg411Filename,
114928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
115028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
115128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
115228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
115328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I400 MJPG buffer.
115428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(fbarchard): Stronger compare on chroma.  Compare agaisnt a grey image.
115528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructMjpgI400() {
115628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
115728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
115828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg400Filename,
115928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
116028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("y", frame1.GetYPlane(), frame1.GetYPitch(),
116128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             frame2.GetYPlane(), frame2.GetYPitch(),
116228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             kWidth, kHeight, 32));
116328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 128));
116428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
116528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
116628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from an I420 MJPG buffer.
11670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  void ValidateFrame(const char* name,
11680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     uint32_t fourcc,
11690c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     int data_adjust,
11700c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     int size_adjust,
11710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                     bool expected_result) {
117228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
1173d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(name));
117416d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
11750c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    const uint8_t* sample =
11760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        reinterpret_cast<const uint8_t*>(ms.get()->GetBuffer());
117728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t sample_size;
117828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ms->GetSize(&sample_size);
117928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Optional adjust size to test invalid size.
118028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t data_size = sample_size + data_adjust;
118128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
118228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Allocate a buffer with end page aligned.
118328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    const int kPadToHeapSized = 16 * 1024 * 1024;
11840c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> page_buffer(
11850c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström        new uint8_t[((data_size + kPadToHeapSized + 4095) & ~4095)]);
11860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* data_ptr = page_buffer.get();
118728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (!data_ptr) {
118828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      LOG(LS_WARNING) << "Failed to allocate memory for ValidateFrame test.";
118928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_FALSE(expected_result);  // NULL is okay if failure was expected.
119028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return;
119128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
119228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    data_ptr += kPadToHeapSized + (-(static_cast<int>(data_size)) & 4095);
1193ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org    memcpy(data_ptr, sample, std::min(data_size, sample_size));
119428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
119528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(expected_result, frame.Validate(fourcc, kWidth, kHeight,
119628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                data_ptr,
119728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                sample_size + size_adjust));
119828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
119928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
120028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
120128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I420 MJPG buffer.
120228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateMjpgI420() {
120328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kJpeg420Filename, cricket::FOURCC_MJPG, 0, 0, true);
120428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
120528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
120628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I422 MJPG buffer.
120728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateMjpgI422() {
120828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kJpeg422Filename, cricket::FOURCC_MJPG, 0, 0, true);
120928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
121028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
121128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I444 MJPG buffer.
121228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateMjpgI444() {
121328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kJpeg444Filename, cricket::FOURCC_MJPG, 0, 0, true);
121428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
121528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
121628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I411 MJPG buffer.
121728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateMjpgI411() {
121828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kJpeg411Filename, cricket::FOURCC_MJPG, 0, 0, true);
121928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
122028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
122128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I400 MJPG buffer.
122228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateMjpgI400() {
122328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kJpeg400Filename, cricket::FOURCC_MJPG, 0, 0, true);
122428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
122528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
122628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I420 buffer.
122728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateI420() {
122828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 0, 0, true);
122928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
123028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
123128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I420 buffer where size is too small
123228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateI420SmallSize() {
123328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 0, -16384, false);
123428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
123528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
123628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I420 buffer where size is too large (16 MB)
123728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Will produce warning but pass.
123828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateI420LargeSize() {
123928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 16000000, 16000000,
124028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  true);
124128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
124228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
124328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate for I420 buffer where size is 1 GB (not reasonable).
124428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateI420HugeSize() {
124528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifndef WIN32  // TODO(fbarchard): Reenable when fixing bug 9603762.
124628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 1000000000u,
124728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  1000000000u, false);
124828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
124928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
125028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
125128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // The following test that Validate crashes if the size is greater than the
125228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // actual buffer size.
125328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(fbarchard): Consider moving a filter into the capturer/plugin.
1254ff134ebd3d35ae2edd6eaa63b0a19cb16cc256b7tfarina#if defined(_MSC_VER) && !defined(NDEBUG)
125528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int ExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
125628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (code == EXCEPTION_ACCESS_VIOLATION) {
125728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      LOG(LS_INFO) << "Caught EXCEPTION_ACCESS_VIOLATION as expected.";
125828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return EXCEPTION_EXECUTE_HANDLER;
125928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else {
126028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      LOG(LS_INFO) << "Did not catch EXCEPTION_ACCESS_VIOLATION.  Unexpected.";
126128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return EXCEPTION_CONTINUE_SEARCH;
126228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
126328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
126428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
126528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate fails for truncated MJPG data buffer.  If ValidateFrame
126628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // crashes the exception handler will return and unittest passes with OK.
126728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateMjpgI420InvalidSize() {
126828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    __try {
126928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      ValidateFrame(kJpeg420Filename, cricket::FOURCC_MJPG, -16384, 0, false);
127028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      FAIL() << "Validate was expected to cause EXCEPTION_ACCESS_VIOLATION.";
127128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } __except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation())) {
127228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return;  // Successfully crashed in ValidateFrame.
127328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
127428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
127528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
127628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test validate fails for truncated I420 buffer.
127728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ValidateI420InvalidSize() {
127828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    __try {
127928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      ValidateFrame(kImageFilename, cricket::FOURCC_I420, -16384, 0, false);
128028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      FAIL() << "Validate was expected to cause EXCEPTION_ACCESS_VIOLATION.";
128128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } __except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation())) {
128228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return;  // Successfully crashed in ValidateFrame.
128328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
128428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
128528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
128628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
128728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer (and synonymous formats).
128828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2Aliases() {
128928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2, frame3, frame4;
1290d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
129128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
129228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
129328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
129428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              &frame1));
129528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
129628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
129728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUVS,
129828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame3));
129928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUYV,
130028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame4));
130128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
130228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));
130328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame4, 0));
130428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
130528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
130628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a UYVY buffer (and synonymous formats).
130728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructUyvyAliases() {
130828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2, frame3, frame4;
1309d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
131028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
131128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
131228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
131328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              &frame1));
131428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
131528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame2));
131628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_2VUY,
131728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame3));
131828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_HDYC,
131928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          kWidth, kHeight, &frame4));
132028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
132128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));
132228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame4, 0));
132328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
132428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
132528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test creating a copy.
132628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructCopy() {
132728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
132828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
132928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
133028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_TRUE(frame2.Init(frame1));
133128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
133228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
133328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
133428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
133528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test creating a copy and check that it just increments the refcount.
133628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructCopyIsRef() {
133728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
133828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
133928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
134028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_TRUE(frame2.Init(frame1));
134128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
134228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
134328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(frame1.GetYPlane(), frame2.GetYPlane());
134428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(frame1.GetUPlane(), frame2.GetUPlane());
134528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(frame1.GetVPlane(), frame2.GetVPlane());
134628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
134728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
134828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test creating an empty image and initing it to black.
134928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructBlack() {
135028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
135128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
1352b09b660c53ff2c499d149e05e5c435f5057273fcmagjed      EXPECT_TRUE(frame.InitToBlack(kWidth, kHeight, 1, 1, 0));
135328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
135428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsSize(frame, kWidth, kHeight));
135528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsBlack(frame));
135628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
135728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
135828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer with a range of sizes.
135928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Only tests that conversion does not crash or corrupt heap.
136028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructYuy2AllSizes() {
136128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
136228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int height = kMinHeightAll; height <= kMaxHeightAll; ++height) {
136328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      for (int width = kMinWidthAll; width <= kMaxWidthAll; ++width) {
1364d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        rtc::scoped_ptr<rtc::MemoryStream> ms(
136528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org            CreateYuv422Sample(cricket::FOURCC_YUY2, width, height));
136628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        ASSERT_TRUE(ms.get() != NULL);
136728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2, width, height,
136828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                  &frame1));
136928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
137028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              width, height, &frame2));
137128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(IsEqual(frame1, frame2, 0));
137228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
137328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
137428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
137528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
137628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test constructing an image from a ARGB buffer with a range of sizes.
137728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Only tests that conversion does not crash or corrupt heap.
137828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConstructARGBAllSizes() {
137928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
138028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int height = kMinHeightAll; height <= kMaxHeightAll; ++height) {
138128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      for (int width = kMinWidthAll; width <= kMaxWidthAll; ++width) {
1382d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        rtc::scoped_ptr<rtc::MemoryStream> ms(
138328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org            CreateRgbSample(cricket::FOURCC_ARGB, width, height));
138428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        ASSERT_TRUE(ms.get() != NULL);
138528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, width, height,
138628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                               &frame1));
138728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
138828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              width, height, &frame2));
138928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(IsEqual(frame1, frame2, 64));
139028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
139128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
139228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Test a practical window size for screencasting usecase.
139328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    const int kOddWidth = 1228;
139428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    const int kOddHeight = 260;
139528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int j = 0; j < 2; ++j) {
139628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      for (int i = 0; i < 2; ++i) {
1397d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org        rtc::scoped_ptr<rtc::MemoryStream> ms(
139828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kOddWidth + i, kOddHeight + j));
139928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        ASSERT_TRUE(ms.get() != NULL);
140028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB,
140128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                               kOddWidth + i, kOddHeight + j,
140228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                               &frame1));
140328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
140428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                              kOddWidth + i, kOddHeight + j, &frame2));
140528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        EXPECT_TRUE(IsEqual(frame1, frame2, 64));
140628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
140728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
140828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
140928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
141028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests re-initing an existing image.
14111d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org  void Reset(webrtc::VideoRotation rotation, bool apply_rotation) {
141228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
1413d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
141428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        LoadSample(kImageFilename));
141516d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
141628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t data_size;
141728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ms->GetSize(&data_size);
1418b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    EXPECT_TRUE(frame1.InitToBlack(kWidth, kHeight, 1, 1, 0));
1419b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    EXPECT_TRUE(frame2.InitToBlack(kWidth, kHeight, 1, 1, 0));
142028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsBlack(frame1));
142128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
14226c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(frame1.Reset(cricket::FOURCC_I420, kWidth, kHeight, kWidth,
14230c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             kHeight,
14240c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             reinterpret_cast<uint8_t*>(ms->GetBuffer()),
14250c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                             data_size, 1, 1, 0, rotation, apply_rotation));
14261d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    if (apply_rotation)
14271d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org      EXPECT_EQ(webrtc::kVideoRotation_0, frame1.GetVideoRotation());
14281d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    else
14291d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org      EXPECT_EQ(rotation, frame1.GetVideoRotation());
14301d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org
14311d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    // Swapp width and height if the frame is rotated 90 or 270 degrees.
14321d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    if (apply_rotation && (rotation == webrtc::kVideoRotation_90
14331d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org        || rotation == webrtc::kVideoRotation_270)) {
14341d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org      EXPECT_TRUE(kHeight == frame1.GetWidth());
14351d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org      EXPECT_TRUE(kWidth == frame1.GetHeight());
14361d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    } else {
14371d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org      EXPECT_TRUE(kWidth == frame1.GetWidth());
14381d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org      EXPECT_TRUE(kHeight == frame1.GetHeight());
14391d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    }
144028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_FALSE(IsBlack(frame1));
144128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_FALSE(IsEqual(frame1, frame2, 0));
144228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
144328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
14441d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org  void ResetAndApplyRotation() {
14451d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    Reset(webrtc::kVideoRotation_90, true);
14461d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org  }
14471d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org
14481d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org  void ResetAndDontApplyRotation() {
14491d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org    Reset(webrtc::kVideoRotation_90, false);
14501d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org  }
14511d82813961d49e1a433024221b6f7164856635ecperkj@webrtc.org
145228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  //////////////////////
145328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Conversion tests //
145428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  //////////////////////
145528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
145628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  enum ToFrom { TO, FROM };
145728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
145828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Helper function for test converting from I420 to packed formats.
14590c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  inline void ConvertToBuffer(int bpp,
14600c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                              int rowpad,
14610c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                              bool invert,
14620c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                              ToFrom to_from,
14630c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                              int error,
14640c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                              uint32_t fourcc,
14650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                              int (*RGBToI420)(const uint8_t* src_frame,
14660c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               int src_stride_frame,
14670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               uint8_t* dst_y,
14680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               int dst_stride_y,
14690c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               uint8_t* dst_u,
14700c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               int dst_stride_u,
14710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               uint8_t* dst_v,
14720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               int dst_stride_v,
14730c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               int width,
14740c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                               int height)) {
147528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
147628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int repeat_to = (to_from == TO) ? repeat_ : 1;
147728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int repeat_from  = (to_from == FROM) ? repeat_ : 1;
147828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
147928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int astride = kWidth * bpp + rowpad;
148028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = astride * kHeight;
14810c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment + 1]);
148228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    memset(outbuf.get(), 0, out_size + kAlignment + 1);
14830c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* outtop = ALIGNP(outbuf.get(), kAlignment);
14840c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* out = outtop;
148528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int stride = astride;
148628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (invert) {
148728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      out += (kHeight - 1) * stride;  // Point to last row.
148828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      stride = -stride;
148928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
149028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
149128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
149228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_to; ++i) {
149328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(fourcc,
149428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                    out,
149528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                    out_size, stride));
149628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
1497b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    EXPECT_TRUE(frame2.InitToBlack(kWidth, kHeight, 1, 1, 0));
149828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_from; ++i) {
149928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(0, RGBToI420(out, stride,
150028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             frame2.GetYPlane(), frame2.GetYPitch(),
150128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             frame2.GetUPlane(), frame2.GetUPitch(),
150228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             frame2.GetVPlane(), frame2.GetVPitch(),
150328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                             kWidth, kHeight));
150428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
150528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (rowpad) {
150628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(0, outtop[kWidth * bpp]);  // Ensure stride skipped end of row.
150728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_NE(0, outtop[astride]);       // Ensure pixel at start of 2nd row.
150828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else {
150928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_NE(0, outtop[kWidth * bpp]);  // Expect something to be here.
151028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
151128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0, outtop[out_size]);      // Ensure no overrun.
151228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, error));
151328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
151428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
151528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kError = 20;
151628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kErrorHigh = 40;
151728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static const int kOddStride = 23;
151828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
151928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests ConvertToRGBBuffer formats.
152028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGBBuffer() {
152128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, false, TO, kError,
152228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
152328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
152428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToBGRABuffer() {
152528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, false, TO, kError,
152628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
152728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
152828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToABGRBuffer() {
152928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, false, TO, kError,
153028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
153128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
153228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRGB24Buffer() {
153328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, false, TO, kError,
153428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
153528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
153628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRAWBuffer() {
153728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, false, TO, kError,
153828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
153928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
154028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRGB565Buffer() {
154128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
154228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
154328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
154428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGB1555Buffer() {
154528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
154628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
154728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
154828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGB4444Buffer() {
154928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
155028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
155128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
155228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToI400Buffer() {
155328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(1, 0, false, TO, 128,
155428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
155528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
155628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToYUY2Buffer() {
155728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
155828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
155928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
156028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToUYVYBuffer() {
156128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
156228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
156328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
156428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
156528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests ConvertToRGBBuffer formats with odd stride.
156628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGBBufferStride() {
156728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, TO, kError,
156828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
156928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
157028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToBGRABufferStride() {
157128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, TO, kError,
157228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
157328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
157428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToABGRBufferStride() {
157528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, TO, kError,
157628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
157728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
157828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRGB24BufferStride() {
157928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, TO, kError,
158028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
158128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
158228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRAWBufferStride() {
158328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, TO, kError,
158428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
158528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
158628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRGB565BufferStride() {
158728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
158828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
158928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
159028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGB1555BufferStride() {
159128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
159228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
159328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
159428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGB4444BufferStride() {
159528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
159628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
159728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
159828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToI400BufferStride() {
159928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, TO, 128,
160028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
160128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
160228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToYUY2BufferStride() {
160328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
160428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
160528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
160628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToUYVYBufferStride() {
160728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
160828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
160928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
161028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
161128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests ConvertToRGBBuffer formats with negative stride to invert image.
161228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGBBufferInverted() {
161328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, true, TO, kError,
161428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
161528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
161628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToBGRABufferInverted() {
161728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, true, TO, kError,
161828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
161928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
162028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToABGRBufferInverted() {
162128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, true, TO, kError,
162228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
162328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
162428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRGB24BufferInverted() {
162528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, true, TO, kError,
162628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
162728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
162828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRAWBufferInverted() {
162928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, true, TO, kError,
163028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
163128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
163228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToRGB565BufferInverted() {
163328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
163428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
163528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
163628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGB1555BufferInverted() {
163728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
163828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
163928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
164028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToARGB4444BufferInverted() {
164128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
164228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
164328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
164428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToI400BufferInverted() {
164528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(1, 0, true, TO, 128,
164628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
164728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
164828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToYUY2BufferInverted() {
164928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
165028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
165128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
165228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToUYVYBufferInverted() {
165328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
165428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
165528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
165628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
165728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests ConvertFrom formats.
165828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGBBuffer() {
165928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, false, FROM, kError,
166028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
166128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
166228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromBGRABuffer() {
166328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, false, FROM, kError,
166428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
166528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
166628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromABGRBuffer() {
166728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, false, FROM, kError,
166828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
166928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
167028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRGB24Buffer() {
167128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, false, FROM, kError,
167228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
167328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
167428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRAWBuffer() {
167528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, false, FROM, kError,
167628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
167728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
167828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRGB565Buffer() {
167928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
168028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
168128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
168228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGB1555Buffer() {
168328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
168428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
168528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
168628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGB4444Buffer() {
168728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
168828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
168928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
169028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromI400Buffer() {
169128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(1, 0, false, FROM, 128,
169228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
169328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
169428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromYUY2Buffer() {
169528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
169628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
169728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
169828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromUYVYBuffer() {
169928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
170028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
170128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
170228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
170328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests ConvertFrom formats with odd stride.
170428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGBBufferStride() {
170528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, FROM, kError,
170628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
170728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
170828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromBGRABufferStride() {
170928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, FROM, kError,
171028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
171128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
171228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromABGRBufferStride() {
171328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, FROM, kError,
171428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
171528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
171628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRGB24BufferStride() {
171728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, FROM, kError,
171828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
171928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
172028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRAWBufferStride() {
172128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, FROM, kError,
172228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
172328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
172428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRGB565BufferStride() {
172528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
172628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
172728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
172828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGB1555BufferStride() {
172928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
173028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
173128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
173228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGB4444BufferStride() {
173328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
173428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
173528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
173628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromI400BufferStride() {
173728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, FROM, 128,
173828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
173928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
174028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromYUY2BufferStride() {
174128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
174228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
174328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
174428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromUYVYBufferStride() {
174528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
174628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
174728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
174828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
174928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Tests ConvertFrom formats with negative stride to invert image.
175028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGBBufferInverted() {
175128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, true, FROM, kError,
175228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
175328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
175428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromBGRABufferInverted() {
175528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, true, FROM, kError,
175628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
175728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
175828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromABGRBufferInverted() {
175928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(4, 0, true, FROM, kError,
176028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
176128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
176228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRGB24BufferInverted() {
176328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, true, FROM, kError,
176428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
176528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
176628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRAWBufferInverted() {
176728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(3, 0, true, FROM, kError,
176828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
176928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
177028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromRGB565BufferInverted() {
177128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
177228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
177328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
177428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGB1555BufferInverted() {
177528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
177628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
177728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
177828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromARGB4444BufferInverted() {
177928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
178028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
178128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
178228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromI400BufferInverted() {
178328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(1, 0, true, FROM, 128,
178428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
178528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
178628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromYUY2BufferInverted() {
178728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
178828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
178928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
179028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertFromUYVYBufferInverted() {
179128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
179228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
179328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
179428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
179528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Test converting from I420 to I422.
179628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void ConvertToI422Buffer() {
179728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame1, frame2;
179828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
17990c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[out_size + kAlignment]);
18000c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* y = ALIGNP(buf.get(), kAlignment);
18010c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* u = y + kWidth * kHeight;
18020c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t* v = u + (kWidth / 2) * kHeight;
180328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
180428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
180528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(),
180628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      frame1.GetUPlane(), frame1.GetUPitch(),
180728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      frame1.GetVPlane(), frame1.GetVPitch(),
180828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      y, kWidth,
180928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      u, kWidth / 2,
181028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      v, kWidth / 2,
181128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      kWidth, kHeight));
181228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
18136c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(frame2.Init(cricket::FOURCC_I422, kWidth, kHeight, kWidth,
1814b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                            kHeight, y, out_size, 1, 1, 0,
18156c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                            webrtc::kVideoRotation_0));
18169caf2765b285f7511d8355177c2d55209d7573e4wu@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 1));
181728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
181828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
181928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  ///////////////////
182028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // General tests //
182128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  ///////////////////
182228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
182328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void Copy() {
1824d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<T> source(new T);
1825d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<cricket::VideoFrame> target;
182628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(source.get()));
182728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    target.reset(source->Copy());
182828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(*source, *target, 0));
182928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    source.reset();
183028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(target->GetYPlane() != NULL);
183128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
183228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
183328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void CopyIsRef() {
1834d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<T> source(new T);
1835f09e7b8a4f521447ea56e3e8c5ff2f6826feacf2magjed@webrtc.org    rtc::scoped_ptr<const cricket::VideoFrame> target;
183628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(source.get()));
183728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    target.reset(source->Copy());
183828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(*source, *target, 0));
1839f09e7b8a4f521447ea56e3e8c5ff2f6826feacf2magjed@webrtc.org    const T* const_source = source.get();
1840f09e7b8a4f521447ea56e3e8c5ff2f6826feacf2magjed@webrtc.org    EXPECT_EQ(const_source->GetYPlane(), target->GetYPlane());
1841f09e7b8a4f521447ea56e3e8c5ff2f6826feacf2magjed@webrtc.org    EXPECT_EQ(const_source->GetUPlane(), target->GetUPlane());
1842f09e7b8a4f521447ea56e3e8c5ff2f6826feacf2magjed@webrtc.org    EXPECT_EQ(const_source->GetVPlane(), target->GetVPlane());
184328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
184428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
184528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void MakeExclusive() {
1846d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<T> source(new T);
1847d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<cricket::VideoFrame> target;
184828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(source.get()));
184928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    target.reset(source->Copy());
185028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(target->MakeExclusive());
185128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(*source, *target, 0));
185228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_NE(target->GetYPlane(), source->GetYPlane());
185328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_NE(target->GetUPlane(), source->GetUPlane());
185428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_NE(target->GetVPlane(), source->GetVPlane());
185528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
185628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
185728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void CopyToBuffer() {
185828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
1859d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
186028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        LoadSample(kImageFilename));
186116d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
186228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight,
186328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &frame));
186428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 3 / 2;
18650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> out(new uint8_t[out_size]);
186628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
186728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size));
186828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
186928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0, memcmp(out.get(), ms->GetBuffer(), out_size));
187028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
187128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
187228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void CopyToFrame() {
187328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T source;
1874d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
187528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        LoadSample(kImageFilename));
187616d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
187728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight,
187828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &source));
187928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
188028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Create the target frame by loading from a file.
188128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T target;
188228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&target));
188328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_FALSE(IsBlack(target));
188428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
188528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Stretch and check if the stretched target is black.
188628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    source.CopyToFrame(&target);
188728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
188828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsEqual(source, target, 0));
188928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
189028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
189128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void Write() {
189228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
1893d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
189428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        LoadSample(kImageFilename));
189516d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
1896d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::MemoryStream ms2;
189728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t size;
189828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms->GetSize(&size));
189928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(ms2.ReserveSize(size));
190028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight,
190128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          &frame));
190228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
190328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      ms2.SetPosition(0u);  // Useful when repeat_ > 1.
190428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      int error;
1905d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org      EXPECT_EQ(rtc::SR_SUCCESS, frame.Write(&ms2, &error));
190628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
190728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = cricket::VideoFrame::SizeOf(kWidth, kHeight);
190828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0, memcmp(ms2.GetBuffer(), ms->GetBuffer(), out_size));
190928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
191028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
191128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void CopyToBuffer1Pixel() {
191228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t out_size = 3;
19130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    rtc::scoped_ptr<uint8_t[]> out(new uint8_t[out_size + 1]);
191428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    memset(out.get(), 0xfb, out_size + 1);  // Fill buffer
19150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint8_t pixel[3] = {1, 2, 3};
191628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T frame;
19176c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org    EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1, pixel,
1918b09b660c53ff2c499d149e05e5c435f5057273fcmagjed                           sizeof(pixel), 1, 1, 0,
19196c930c71831b6eda6e85903c505459569a02ad9aguoweis@webrtc.org                           webrtc::kVideoRotation_0));
192028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
192128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size));
192228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
192328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(1, out.get()[0]);  // Check Y.  Should be 1.
192428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(2, out.get()[1]);  // Check U.  Should be 2.
192528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(3, out.get()[2]);  // Check V.  Should be 3.
192628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(0xfb, out.get()[3]);  // Check sentinel is still intact.
192728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
192828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
192928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  void StretchToFrame() {
193028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Create the source frame as a black frame.
193128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T source;
1932b09b660c53ff2c499d149e05e5c435f5057273fcmagjed    EXPECT_TRUE(source.InitToBlack(kWidth * 2, kHeight * 2, 1, 1, 0));
193328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsSize(source, kWidth * 2, kHeight * 2));
193428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
193528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Create the target frame by loading from a file.
193628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T target1;
193728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&target1));
193828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_FALSE(IsBlack(target1));
193928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
194028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Stretch and check if the stretched target is black.
194128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    source.StretchToFrame(&target1, true, false);
194228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsBlack(target1));
194328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
194428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Crop and stretch and check if the stretched target is black.
194528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    T target2;
194628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&target2));
194728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    source.StretchToFrame(&target2, true, true);
194828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_TRUE(IsBlack(target2));
194928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    EXPECT_EQ(source.GetTimeStamp(), target2.GetTimeStamp());
195028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
195128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
195228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int repeat_;
195328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org};
195428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
195528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif  // TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_
1956