10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004 Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifndef TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <string>
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "libyuv/convert.h"
340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "libyuv/convert_from.h"
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "libyuv/format_conversion.h"
360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "libyuv/planar_functions.h"
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "libyuv/rotate.h"
38cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/testutils.h"
39cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/videocommon.h"
40cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/videoframe.h"
412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/gunit.h"
422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/pathutils.h"
432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stream.h"
442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringutils.h"
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#if defined(_MSC_VER)
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define ALIGN16(var) __declspec(align(16)) var
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define ALIGN16(var) var __attribute__((aligned(16)))
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define kImageFilename "faces.1280x720_P420.yuv"
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define kJpeg420Filename "faces_I420.jpg"
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define kJpeg422Filename "faces_I422.jpg"
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define kJpeg444Filename "faces_I444.jpg"
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define kJpeg411Filename "faces_I411.jpg"
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define kJpeg400Filename "faces_I400.jpg"
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Generic test class for testing various video frame implementations.
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate <class T>
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass VideoFrameTest : public testing::Test {
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  VideoFrameTest() : repeat_(1) {}
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected:
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kWidth = 1280;
670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kHeight = 720;
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kAlignment = 16;
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kMinWidthAll = 1;  // Constants for ConstructYUY2AllSizes.
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kMinHeightAll = 1;
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kMaxWidthAll = 17;
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kMaxHeightAll = 23;
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Load a video frame from disk.
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool LoadFrameNoRepeat(T* frame) {
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int save_repeat = repeat_;  // This LoadFrame disables repeat.
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    repeat_ = 1;
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool success = LoadFrame(kImageFilename, cricket::FOURCC_I420,
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            kWidth, kHeight, frame);
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    repeat_ = save_repeat;
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return success;
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool LoadFrame(const std::string& filename, uint32 format,
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 int32 width, int32 height, T* frame) {
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return LoadFrame(filename, format, width, height,
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     width, abs(height), 0, frame);
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool LoadFrame(const std::string& filename, uint32 format,
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 int32 width, int32 height, int dw, int dh, int rotation,
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 T* frame) {
922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(filename));
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return LoadFrame(ms.get(), format, width, height, dw, dh, rotation, frame);
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Load a video frame from a memory stream.
962a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  bool LoadFrame(rtc::MemoryStream* ms, uint32 format,
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 int32 width, int32 height, T* frame) {
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return LoadFrame(ms, format, width, height,
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     width, abs(height), 0, frame);
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1012a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  bool LoadFrame(rtc::MemoryStream* ms, uint32 format,
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 int32 width, int32 height, int dw, int dh, int rotation,
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 T* frame) {
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!ms) {
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size;
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = ms->GetSize(&data_size);
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ret);
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ret) {
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ret = LoadFrame(reinterpret_cast<uint8*>(ms->GetBuffer()), data_size,
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      format, width, height, dw, dh, rotation, frame);
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return ret;
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Load a frame from a raw buffer.
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool LoadFrame(uint8* sample, size_t sample_size, uint32 format,
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 int32 width, int32 height, T* frame) {
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return LoadFrame(sample, sample_size, format, width, height,
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     width, abs(height), 0, frame);
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool LoadFrame(uint8* sample, size_t sample_size, uint32 format,
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 int32 width, int32 height, int dw, int dh, int rotation,
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 T* frame) {
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = false;
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ret = frame->Init(format, width, height, dw, dh,
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        sample, sample_size, 1, 1, 0, 0, rotation);
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return ret;
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::MemoryStream* LoadSample(const std::string& filename) {
1342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::Pathname path(cricket::GetTestFilePath(filename));
1352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::FileStream> fs(
1362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::Filesystem::OpenFile(path, "rb"));
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!fs.get()) {
13892891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com      LOG(LS_ERROR) << "Could not open test file path: " << path.pathname()
13992891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                    << " from current dir "
14092891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                    << rtc::Filesystem::GetCurrentDirectory().pathname();
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    char buf[4096];
1452a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
1462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        new rtc::MemoryStream());
1472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::StreamResult res = Flow(fs.get(), buf, sizeof(buf), ms.get());
1482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    if (res != rtc::SR_SUCCESS) {
14992891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com      LOG(LS_ERROR) << "Could not load test file path: " << path.pathname();
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return ms.release();
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Write an I420 frame out to disk.
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool DumpFrame(const std::string& prefix,
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 const cricket::VideoFrame& frame) {
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    char filename[256];
1602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::sprintfn(filename, sizeof(filename), "%s.%dx%d_P420.yuv",
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        prefix.c_str(), frame.GetWidth(), frame.GetHeight());
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = cricket::VideoFrame::SizeOf(frame.GetWidth(),
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                  frame.GetHeight());
1642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> out(new uint8[out_size]);
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    frame.CopyToBuffer(out.get(), out_size);
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return DumpSample(filename, out.get(), out_size);
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool DumpSample(const std::string& filename, const void* buffer, int size) {
1702a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::Pathname path(filename);
1712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::FileStream> fs(
1722a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::Filesystem::OpenFile(path, "wb"));
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!fs.get()) {
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1772a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    return (fs->Write(buffer, size, NULL, NULL) == rtc::SR_SUCCESS);
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Create a test image in the desired color space.
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // The image is a checkerboard pattern with 63x63 squares, which allows
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // I420 chroma artifacts to easily be seen on the square boundaries.
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // The pattern is { { green, orange }, { blue, purple } }
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // There is also a gradient within each square to ensure that the luma
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // values are handled properly.
1862a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::MemoryStream* CreateYuv422Sample(uint32 fourcc,
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                              uint32 width, uint32 height) {
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int y1_pos, y2_pos, u_pos, v_pos;
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) {
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1932a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
1942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        new rtc::MemoryStream);
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int awidth = (width + 1) & ~1;
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int size = awidth * 2 * height;
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!ms->ReserveSize(size)) {
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (uint32 y = 0; y < height; ++y) {
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (int x = 0; x < awidth; x += 2) {
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        uint8 quad[4];
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        quad[y1_pos] = (x % 63 + y % 63) + 64;
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        quad[y2_pos] = ((x + 1) % 63 + y % 63) + 64;
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        quad[u_pos] = ((x / 63) & 1) ? 192 : 64;
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        quad[v_pos] = ((y / 63) & 1) ? 192 : 64;
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ms->Write(quad, sizeof(quad), NULL, NULL);
2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return ms.release();
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Create a test image for YUV 420 formats with 12 bits per pixel.
2142a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::MemoryStream* CreateYuvSample(uint32 width, uint32 height,
2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           uint32 bpp) {
2162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
2172a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        new rtc::MemoryStream);
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!ms->ReserveSize(width * height * bpp / 8)) {
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (uint32 i = 0; i < width * height * bpp / 8; ++i) {
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      char value = ((i / 63) & 1) ? 192 : 64;
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ms->Write(&value, sizeof(value), NULL, NULL);
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return ms.release();
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2292a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::MemoryStream* CreateRgbSample(uint32 fourcc,
2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           uint32 width, uint32 height) {
2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int r_pos, g_pos, b_pos, bytes;
2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) {
2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
2372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        new rtc::MemoryStream);
2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!ms->ReserveSize(width * height * bytes)) {
2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (uint32 y = 0; y < height; ++y) {
2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (uint32 x = 0; x < width; ++x) {
2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        uint8 rgb[4] = { 255, 255, 255, 255 };
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[r_pos] = ((x / 63) & 1) ? 224 : 32;
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[g_pos] = (x % 63 + y % 63) + 96;
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[b_pos] = ((y / 63) & 1) ? 224 : 32;
2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ms->Write(rgb, bytes, NULL, NULL);
2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return ms.release();
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Simple conversion routines to verify the optimized VideoFrame routines.
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Converts from the specified colorspace to I420.
2562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  bool ConvertYuv422(const rtc::MemoryStream* ms,
2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     uint32 fourcc, uint32 width, uint32 height,
2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     T* frame) {
2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int y1_pos, y2_pos, u_pos, v_pos;
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) {
2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* start = reinterpret_cast<const uint8*>(ms->GetBuffer());
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int awidth = (width + 1) & ~1;
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    frame->InitToBlack(width, height, 1, 1, 0, 0);
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride_y = frame->GetYPitch();
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride_u = frame->GetUPitch();
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride_v = frame->GetVPitch();
2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (uint32 y = 0; y < height; ++y) {
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (uint32 x = 0; x < width; x += 2) {
2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        const uint8* quad1 = start + (y * awidth + x) * 2;
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame->GetYPlane()[stride_y * y + x] = quad1[y1_pos];
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if ((x + 1) < width) {
2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          frame->GetYPlane()[stride_y * y + x + 1] = quad1[y2_pos];
2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if ((y & 1) == 0) {
2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          const uint8* quad2 = quad1 + awidth * 2;
2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          if ((y + 1) >= height) {
2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            quad2 = quad1;
2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          }
2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          frame->GetUPlane()[stride_u * (y / 2) + x / 2] =
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org              (quad1[u_pos] + quad2[u_pos] + 1) / 2;
2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          frame->GetVPlane()[stride_v * (y / 2) + x / 2] =
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org              (quad1[v_pos] + quad2[v_pos] + 1) / 2;
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Convert RGB to 420.
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // A negative height inverts the image.
2942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  bool ConvertRgb(const rtc::MemoryStream* ms,
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  uint32 fourcc, int32 width, int32 height,
2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  T* frame) {
2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int r_pos, g_pos, b_pos, bytes;
2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) {
2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int pitch = width * bytes;
3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* start = reinterpret_cast<const uint8*>(ms->GetBuffer());
3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (height < 0) {
3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      height = -height;
3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      start = start + pitch * (height - 1);
3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      pitch = -pitch;
3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    frame->InitToBlack(width, height, 1, 1, 0, 0);
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride_y = frame->GetYPitch();
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride_u = frame->GetUPitch();
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride_v = frame->GetVPitch();
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int32 y = 0; y < height; y += 2) {
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (int32 x = 0; x < width; x += 2) {
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        const uint8* rgb[4];
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        uint8 yuv[4][3];
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[0] = start + y * pitch + x * bytes;
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[1] = rgb[0] + ((x + 1) < width ? bytes : 0);
3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[2] = rgb[0] + ((y + 1) < height ? pitch : 0);
3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        rgb[3] = rgb[2] + ((x + 1) < width ? bytes : 0);
3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        for (size_t i = 0; i < 4; ++i) {
3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          ConvertRgbPixel(rgb[i][r_pos], rgb[i][g_pos], rgb[i][b_pos],
3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &yuv[i][0], &yuv[i][1], &yuv[i][2]);
3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame->GetYPlane()[stride_y * y + x] = yuv[0][0];
3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if ((x + 1) < width) {
3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          frame->GetYPlane()[stride_y * y + x + 1] = yuv[1][0];
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if ((y + 1) < height) {
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          frame->GetYPlane()[stride_y * (y + 1) + x] = yuv[2][0];
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          if ((x + 1) < width) {
3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            frame->GetYPlane()[stride_y * (y + 1) + x + 1] = yuv[3][0];
3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          }
3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame->GetUPlane()[stride_u * (y / 2) + x / 2] =
3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            (yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1] + 2) / 4;
3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame->GetVPlane()[stride_v * (y / 2) + x / 2] =
3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            (yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2] + 2) / 4;
3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia.
3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertRgbPixel(uint8 r, uint8 g, uint8 b,
3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       uint8* y, uint8* u, uint8* v) {
3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    *y = static_cast<int>(.257 * r + .504 * g + .098 * b) + 16;
3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    *u = static_cast<int>(-.148 * r - .291 * g + .439 * b) + 128;
3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    *v = static_cast<int>(.439 * r - .368 * g - .071 * b) + 128;
3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool GetYuv422Packing(uint32 fourcc,
3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        int* y1_pos, int* y2_pos, int* u_pos, int* v_pos) {
3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (fourcc == cricket::FOURCC_YUY2) {
3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *y1_pos = 0; *u_pos = 1; *y2_pos = 2; *v_pos = 3;
3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_UYVY) {
3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *u_pos = 0; *y1_pos = 1; *v_pos = 2; *y2_pos = 3;
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool GetRgbPacking(uint32 fourcc,
3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     int* r_pos, int* g_pos, int* b_pos, int* bytes) {
3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (fourcc == cricket::FOURCC_RAW) {
3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 3;  // RGB in memory.
3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_24BG) {
3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 3;  // BGR in memory.
3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_ABGR) {
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 4;  // RGBA in memory.
3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_BGRA) {
3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *r_pos = 1; *g_pos = 2; *b_pos = 3; *bytes = 4;  // ARGB in memory.
3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else if (fourcc == cricket::FOURCC_ARGB) {
3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 4;  // BGRA in memory.
3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Comparison functions for testing.
3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsNull(const cricket::VideoFrame& frame) {
3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return !frame.GetYPlane();
3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsSize(const cricket::VideoFrame& frame,
3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     uint32 width, uint32 height) {
3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return !IsNull(frame) &&
3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetYPitch() >= static_cast<int32>(width) &&
3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetUPitch() >= static_cast<int32>(width) / 2 &&
3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetVPitch() >= static_cast<int32>(width) / 2 &&
3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetWidth() == width && frame.GetHeight() == height;
3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsPlaneEqual(const std::string& name,
3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           const uint8* plane1, uint32 pitch1,
3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           const uint8* plane2, uint32 pitch2,
3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           uint32 width, uint32 height,
3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           int max_error) {
4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* r1 = plane1;
4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* r2 = plane2;
4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (uint32 y = 0; y < height; ++y) {
4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (uint32 x = 0; x < width; ++x) {
4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if (abs(static_cast<int>(r1[x] - r2[x])) > max_error) {
4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          LOG(LS_INFO) << "IsPlaneEqual(" << name << "): pixel["
4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       << x << "," << y << "] differs: "
4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       << static_cast<int>(r1[x]) << " vs "
4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       << static_cast<int>(r2[x]);
4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          return false;
4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      r1 += pitch1;
4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      r2 += pitch2;
4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsEqual(const cricket::VideoFrame& frame,
4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      size_t width, size_t height,
4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      size_t pixel_width, size_t pixel_height,
4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      int64 elapsed_time, int64 time_stamp,
4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      const uint8* y, uint32 ypitch,
4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      const uint8* u, uint32 upitch,
4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      const uint8* v, uint32 vpitch,
4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      int max_error) {
42692891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    return IsSize(frame,
42792891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                  static_cast<uint32>(width),
42892891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                  static_cast<uint32>(height)) &&
4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetPixelWidth() == pixel_width &&
4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetPixelHeight() == pixel_height &&
4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetElapsedTime() == elapsed_time &&
4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        frame.GetTimeStamp() == time_stamp &&
4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        IsPlaneEqual("y", frame.GetYPlane(), frame.GetYPitch(), y, ypitch,
43492891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                     static_cast<uint32>(width),
43592891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                     static_cast<uint32>(height), max_error) &&
4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        IsPlaneEqual("u", frame.GetUPlane(), frame.GetUPitch(), u, upitch,
43792891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                     static_cast<uint32>((width + 1) / 2),
43892891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                     static_cast<uint32>((height + 1) / 2), max_error) &&
4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        IsPlaneEqual("v", frame.GetVPlane(), frame.GetVPitch(), v, vpitch,
44092891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                     static_cast<uint32>((width + 1) / 2),
44192891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com                     static_cast<uint32>((height + 1) / 2), max_error);
4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsEqual(const cricket::VideoFrame& frame1,
4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      const cricket::VideoFrame& frame2,
4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      int max_error) {
4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return IsEqual(frame1,
4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetWidth(), frame2.GetHeight(),
4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetPixelWidth(), frame2.GetPixelHeight(),
4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetElapsedTime(), frame2.GetTimeStamp(),
4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetYPlane(), frame2.GetYPitch(),
4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetUPlane(), frame2.GetUPitch(),
4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetVPlane(), frame2.GetVPitch(),
4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   max_error);
4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsEqualWithCrop(const cricket::VideoFrame& frame1,
4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              const cricket::VideoFrame& frame2,
4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              int hcrop, int vcrop, int max_error) {
4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return frame1.GetWidth() <= frame2.GetWidth() &&
4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           frame1.GetHeight() <= frame2.GetHeight() &&
4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           IsEqual(frame1,
4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetWidth() - hcrop * 2,
4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetHeight() - vcrop * 2,
4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetPixelWidth(), frame2.GetPixelHeight(),
4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetElapsedTime(), frame2.GetTimeStamp(),
4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetYPlane() + vcrop * frame2.GetYPitch()
4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       + hcrop,
4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetYPitch(),
4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetUPlane() + vcrop * frame2.GetUPitch() / 2
4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       + hcrop / 2,
4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetUPitch(),
4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetVPlane() + vcrop * frame2.GetVPitch() / 2
4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       + hcrop / 2,
4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   frame2.GetVPitch(),
4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   max_error);
4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static bool IsBlack(const cricket::VideoFrame& frame) {
4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return !IsNull(frame) &&
4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        *frame.GetYPlane() == 16 &&
4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        *frame.GetUPlane() == 128 &&
4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        *frame.GetVPlane() == 128;
4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ////////////////////////
4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Construction tests //
4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ////////////////////////
4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a I420 buffer.
4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI420() {
4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsNull(frame));
4942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420,
4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame));
4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* y = reinterpret_cast<uint8*>(ms.get()->GetBuffer());
5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* u = y + kWidth * kHeight;
5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* v = u + kWidth * kHeight / 4;
5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, 0,
5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        y, kWidth, u, kWidth / 2, v, kWidth / 2, 0));
5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YV12 buffer.
5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYV12() {
5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
5092a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YV12,
5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame));
5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* y = reinterpret_cast<uint8*>(ms.get()->GetBuffer());
5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* v = y + kWidth * kHeight;
5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* u = v + kWidth * kHeight / 4;
5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, 0,
5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        y, kWidth, u, kWidth / 2, v, kWidth / 2, 0));
5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a I422 buffer.
5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI422() {
5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t buf_size = kWidth * kHeight * 2;
5262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> buf(new uint8[buf_size + kAlignment]);
5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* y = ALIGNP(buf.get(), kAlignment);
5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* u = y + kWidth * kHeight;
5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* v = u + (kWidth / 2) * kHeight;
5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(),
5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    frame1.GetUPlane(), frame1.GetUPitch(),
5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    frame1.GetVPlane(), frame1.GetVPitch(),
5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    y, kWidth,
5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    u, kWidth / 2,
5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    v, kWidth / 2,
5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    kWidth, kHeight));
5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(y, buf_size, cricket::FOURCC_I422,
5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
539cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 1));
5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer.
5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2() {
5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t buf_size = kWidth * kHeight * 2;
5472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> buf(new uint8[buf_size + kAlignment]);
5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* yuy2 = ALIGNP(buf.get(), kAlignment);
5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(),
5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    frame1.GetUPlane(), frame1.GetUPitch(),
5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    frame1.GetVPlane(), frame1.GetVPitch(),
5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    yuy2, kWidth * 2,
5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    kWidth, kHeight));
5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2,
5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer with buffer unaligned.
5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2Unaligned() {
5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t buf_size = kWidth * kHeight * 2;
5642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> buf(new uint8[buf_size + kAlignment + 1]);
5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* yuy2 = ALIGNP(buf.get(), kAlignment) + 1;
5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(),
5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    frame1.GetUPlane(), frame1.GetUPitch(),
5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    frame1.GetVPlane(), frame1.GetVPitch(),
5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    yuy2, kWidth * 2,
5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    kWidth, kHeight));
5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2,
5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a wide YUY2 buffer.
5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Normal is 1280x720.  Wide is 12800x72
5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2Wide() {
5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
5802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth * 10, kHeight / 10));
5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2,
5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              kWidth * 10, kHeight / 10,
5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &frame1));
5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth * 10, kHeight / 10, &frame2));
5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a UYVY buffer.
5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructUyvy() {
5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
5942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &frame1));
5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a random buffer.
6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We are merely verifying that the code succeeds and is free of crashes.
6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructM420() {
6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
6082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
6100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_M420,
6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame));
6130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructQ420() {
6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
6172a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_Q420,
6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame));
6220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructNV21() {
6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
6262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_NV21,
6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame));
6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructNV12() {
6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
6352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, 12));
6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_NV12,
6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame));
6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a ABGR buffer
6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructABGR() {
6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
6462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ABGR, kWidth, kHeight));
6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ABGR, kWidth, kHeight,
6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame1));
6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ABGR,
6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a ARGB buffer
6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGB() {
6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
6602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));
6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,
6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame1));
6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a wide ARGB buffer
6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Normal is 1280x720.  Wide is 12800x72
6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGBWide() {
6730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
6742a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth * 10, kHeight / 10));
6760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB,
6780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           kWidth * 10, kHeight / 10, &frame1));
6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth * 10, kHeight / 10, &frame2));
6810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
6820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an BGRA buffer.
6850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
6860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructBGRA() {
6870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
6882a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
6890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_BGRA, kWidth, kHeight));
6900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
6910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_BGRA, kWidth, kHeight,
6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame1));
6930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_BGRA,
6940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
6950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
6960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a 24BG buffer.
6990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
7000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void Construct24BG() {
7010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
7022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
7030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_24BG, kWidth, kHeight));
7040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
7050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_24BG, kWidth, kHeight,
7060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame1));
7070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_24BG,
7080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
7090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
7100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a raw RGB buffer.
7130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Due to rounding, some pixels may differ slightly from the VideoFrame impl.
7140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructRaw() {
7150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
7162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
7170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_RAW, kWidth, kHeight));
7180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
7190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_RAW, kWidth, kHeight,
7200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame1));
7210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_RAW,
7220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
7230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 2));
7240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a RGB565 buffer
7270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructRGB565() {
7280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
7290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
7302a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
73192891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* out = ALIGNP(outbuf.get(), kAlignment);
7320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBP,
7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out,
7360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size, kWidth * 2));
7370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBP,
7380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
7390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 20));
7400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a ARGB1555 buffer
7430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGB1555() {
7440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
7450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
7462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
74792891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* out = ALIGNP(outbuf.get(), kAlignment);
7480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
7490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
7500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBO,
7510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out,
7520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size, kWidth * 2));
7530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBO,
7540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
7550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 20));
7560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a ARGB4444 buffer
7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGB4444() {
7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
7610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
7622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
76392891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* out = ALIGNP(outbuf.get(), kAlignment);
7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
7660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_R444,
7670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out,
7680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size, kWidth * 2));
7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_R444,
7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 20));
7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Macro to help test different Bayer formats.
7750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Error threshold of 60 allows for Bayer format subsampling.
7760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(fbarchard): Refactor this test to go from Bayer to I420 and
7770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // back to bayer, which would be less lossy.
7780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  #define TEST_BYR(NAME, BAYER)                                                \
7790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void NAME() {                                                                \
7800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t bayer_size = kWidth * kHeight;                                      \
7812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[                         \
7820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer_size + kAlignment]);                                             \
78392891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* bayer = ALIGNP(bayerbuf.get(), kAlignment);                         \
7840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;                                                          \
7852a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                         \
7860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));               \
7870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
78892891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8* >(ms->GetBuffer()),     \
7890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               kWidth * 4,                                     \
7900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               bayer, kWidth,                                  \
7910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               kWidth, kHeight);                               \
7920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(bayer, bayer_size, cricket::FOURCC_##BAYER,          \
7930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight,  &frame1));                         \
7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,    \
7950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame2));                                          \
7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 60));                                  \
7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from Bayer formats.
8000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYR(ConstructBayerGRBG, GRBG)
8010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYR(ConstructBayerGBRG, GBRG)
8020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYR(ConstructBayerBGGR, BGGR)
8030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYR(ConstructBayerRGGB, RGGB)
8040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Macro to help test different rotations
8070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define TEST_MIRROR(FOURCC, BPP)                                               \
8080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Construct##FOURCC##Mirror() {                                             \
8090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2, frame3;                                                  \
8102a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                         \
8110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, BPP));                                \
8120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
8130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC,                  \
8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, -kHeight, kWidth, kHeight,                   \
8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_180, &frame1));                    \
8160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size;                                                          \
8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = ms->GetSize(&data_size);                                        \
8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ret);                                                          \
8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC,                          \
8200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            kWidth, kHeight, kWidth, kHeight,                  \
8210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            reinterpret_cast<uint8*>(ms->GetBuffer()),         \
8220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            data_size,                                         \
8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            1, 1, 0, 0, 0));                                   \
82492891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    int width_rotate = static_cast<int>(frame1.GetWidth());                    \
82592891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    int height_rotate = static_cast<int>(frame1.GetHeight());                  \
8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0, 0));  \
8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    libyuv::I420Mirror(frame2.GetYPlane(), frame2.GetYPitch(),                 \
8280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame2.GetUPlane(), frame2.GetUPitch(),                 \
8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame2.GetVPlane(), frame2.GetVPitch(),                 \
8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame3.GetYPlane(), frame3.GetYPitch(),                 \
8310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame3.GetUPlane(), frame3.GetUPitch(),                 \
8320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame3.GetVPlane(), frame3.GetVPitch(),                 \
8330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       kWidth, kHeight);                                       \
8340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));                                   \
8350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_MIRROR(I420, 420)
8380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Macro to help test different rotations
8400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define TEST_ROTATE(FOURCC, BPP, ROTATE)                                       \
8410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Construct##FOURCC##Rotate##ROTATE() {                                     \
8420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2, frame3;                                                  \
8432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                         \
8440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuvSample(kWidth, kHeight, BPP));                                \
8450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
8460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC,                  \
8470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,                    \
8480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_##ROTATE, &frame1));               \
8490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size;                                                          \
8500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = ms->GetSize(&data_size);                                        \
8510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ret);                                                          \
8520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC,                          \
8530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            kWidth, kHeight, kWidth, kHeight,                  \
8540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            reinterpret_cast<uint8*>(ms->GetBuffer()),         \
8550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            data_size,                                         \
8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            1, 1, 0, 0, 0));                                   \
85792891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    int width_rotate = static_cast<int>(frame1.GetWidth());                    \
85892891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    int height_rotate = static_cast<int>(frame1.GetHeight());                  \
8590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0, 0));  \
8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    libyuv::I420Rotate(frame2.GetYPlane(), frame2.GetYPitch(),                 \
8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame2.GetUPlane(), frame2.GetUPitch(),                 \
8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame2.GetVPlane(), frame2.GetVPitch(),                 \
8630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame3.GetYPlane(), frame3.GetYPitch(),                 \
8640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame3.GetUPlane(), frame3.GetUPitch(),                 \
8650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       frame3.GetVPlane(), frame3.GetVPitch(),                 \
8660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       kWidth, kHeight, libyuv::kRotate##ROTATE);              \
8670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));                                   \
8680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image with rotation.
8710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(I420, 12, 0)
8720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(I420, 12, 90)
8730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(I420, 12, 180)
8740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(I420, 12, 270)
8750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 0)
8760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 90)
8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 180)
8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YV12, 12, 270)
8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 0)
8800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 90)
8810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 180)
8820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV12, 12, 270)
8830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 0)
8840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 90)
8850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 180)
8860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(NV21, 12, 270)
8870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 0)
8880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 90)
8890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 180)
8900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(UYVY, 16, 270)
8910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 0)
8920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 90)
8930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 180)
8940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_ROTATE(YUY2, 16, 270)
8950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a UYVY buffer rotated 90 degrees.
8970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructUyvyRotate90() {
8980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame2;
8992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
9000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
9010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
9030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,
9040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_90, &frame2));
9050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a UYVY buffer rotated 180 degrees.
9080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructUyvyRotate180() {
9090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame2;
9102a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
9110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
9120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
9140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,
9150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_180, &frame2));
9160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a UYVY buffer rotated 270 degrees.
9190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructUyvyRotate270() {
9200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame2;
9212a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
9220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
9230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
9250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,
9260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_270, &frame2));
9270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer rotated 90 degrees.
9300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2Rotate90() {
9310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame2;
9322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
9330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
9340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
9360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,
9370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_90, &frame2));
9380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer rotated 180 degrees.
9410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2Rotate180() {
9420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame2;
9432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
9440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
9450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
9470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,
9480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_180, &frame2));
9490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer rotated 270 degrees.
9520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2Rotate270() {
9530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame2;
9542a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
9550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
9560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
9570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
9580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, kWidth, kHeight,
9590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::ROTATION_270, &frame2));
9600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test 1 pixel edge case image I420 buffer.
9630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI4201Pixel() {
9640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
9650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8 pixel[3] = { 1, 2, 3 };
9660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
9670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1,
9680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             pixel, sizeof(pixel),
9690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             1, 1, 0, 0, 0));
9700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
9710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* y = pixel;
9720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* u = y + 1;
9730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* v = u + 1;
9740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame, 1, 1, 1, 1, 0, 0,
9750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        y, 1, u, 1, v, 1, 0));
9760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test 5 pixel edge case image I420 buffer rounds down to 4.
9790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI4205Pixel() {
9800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
9810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8 pixels5x5[5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) *  2];
9820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    memset(pixels5x5, 1, 5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) *  2);
9830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
9840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 5, 5, 5, 5,
9850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             pixels5x5, sizeof(pixels5x5),
9860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             1, 1, 0, 0, 0));
9870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
9880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(4u, frame.GetWidth());
9890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(4u, frame.GetHeight());
9900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(4, frame.GetYPitch());
9910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(2, frame.GetUPitch());
9920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(2, frame.GetVPitch());
9930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test 1 pixel edge case image ARGB buffer.
9960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGB1Pixel() {
9970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
9980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8 pixel[4] = { 64, 128, 192, 255 };
9990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
10000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 1, 1, 1, 1,
10010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             pixel, sizeof(pixel),
10020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             1, 1, 0, 0, 0));
10030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
10040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Convert back to ARGB.
10050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = 4;
10062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
100792891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* out = ALIGNP(outbuf.get(), kAlignment);
10080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
10100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out,
10110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size,    // buffer size
10120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size));  // stride
10130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  #ifdef USE_LMI_CONVERT
10140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TODO(fbarchard): Expected to fail, but not crash.
10150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2));
10160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  #else
10170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TODO(fbarchard): Check for overwrite.
10180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2));
10190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  #endif
10200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test Black, White and Grey pixels.
10230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGBBlackWhitePixel() {
10240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
10250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8 pixel[10 * 4] = { 0, 0, 0, 255,  // Black.
10260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            0, 0, 0, 255,
10270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            64, 64, 64, 255,  // Dark Grey.
10280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            64, 64, 64, 255,
10290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            128, 128, 128, 255,  // Grey.
10300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            128, 128, 128, 255,
10310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            196, 196, 196, 255,  // Light Grey.
10320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            196, 196, 196, 255,
10330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            255, 255, 255, 255,  // White.
10340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            255, 255, 255, 255 };
10350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
10370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 10, 1, 10, 1,
10380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             pixel, sizeof(pixel),
10390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             1, 1, 0, 0, 0));
10400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
10410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Convert back to ARGB
10420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = 10 * 4;
10432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
104492891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* out = ALIGNP(outbuf.get(), kAlignment);
10450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
10470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out,
10480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size,    // buffer size.
10490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                 out_size));  // stride.
10500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("argb", pixel, out_size,
10510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             out, out_size,
10520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             out_size, 1, 2));
10530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I420 buffer with horizontal cropping.
10560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI420CropHorizontal() {
10570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
10580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
10590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_I420, kWidth, kHeight,
10600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth * 3 / 4, kHeight, 0, &frame2));
10610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, kWidth / 8, 0, 0));
10620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer with horizontal cropping.
10650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2CropHorizontal() {
10660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
10672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
10680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
10690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
10700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
10710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &frame1));
10720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
10730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth * 3 / 4, kHeight, 0, &frame2));
10740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, kWidth / 8, 0, 0));
10750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an ARGB buffer with horizontal cropping.
10780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGBCropHorizontal() {
10790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
10802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
10810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));
10820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
10830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,
10840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &frame1));
10850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB, kWidth, kHeight,
10860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth * 3 / 4, kHeight, 0, &frame2));
10870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, kWidth / 8, 0, 2));
10880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I420 buffer, cropping top and bottom.
10910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI420CropVertical() {
10920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
10930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
10940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_I420, kWidth, kHeight,
10950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight * 3 / 4, 0, &frame2));
10960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqualWithCrop(frame2, frame1, 0, kHeight / 8, 0));
10970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from I420 synonymous formats.
11000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructI420Aliases() {
11010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2, frame3;
11020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_I420, kWidth, kHeight,
11030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &frame1));
11040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_IYUV, kWidth, kHeight,
11050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &frame2));
11060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kImageFilename, cricket::FOURCC_YU12, kWidth, kHeight,
11070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &frame3));
11080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
11090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));
11100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I420 MJPG buffer.
11130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructMjpgI420() {
11140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
11150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
11160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg420Filename,
11170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
11180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
11190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I422 MJPG buffer.
11220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructMjpgI422() {
11230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
11240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
11250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg422Filename,
11260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
11270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
11280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I444 MJPG buffer.
11310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructMjpgI444() {
11320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
11330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
11340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg444Filename,
11350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
11360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
11370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I444 MJPG buffer.
11400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructMjpgI411() {
11410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
11420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
11430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg411Filename,
11440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
11450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 32));
11460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I400 MJPG buffer.
11490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(fbarchard): Stronger compare on chroma.  Compare agaisnt a grey image.
11500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructMjpgI400() {
11510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
11520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
11530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(kJpeg400Filename,
11540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          cricket::FOURCC_MJPG, kWidth, kHeight, &frame2));
11550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("y", frame1.GetYPlane(), frame1.GetYPitch(),
11560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             frame2.GetYPlane(), frame2.GetYPitch(),
11570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             kWidth, kHeight, 32));
11580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 128));
11590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from an I420 MJPG buffer.
11620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateFrame(const char* name, uint32 fourcc, int data_adjust,
11630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     int size_adjust, bool expected_result) {
11640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
11652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(name));
1166a39fcda7b56709e660a3d3fd171cb9e963e7e532wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
11670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const uint8* sample = reinterpret_cast<const uint8*>(ms.get()->GetBuffer());
11680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t sample_size;
11690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ms->GetSize(&sample_size);
11700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Optional adjust size to test invalid size.
11710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size = sample_size + data_adjust;
11720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Allocate a buffer with end page aligned.
11740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const int kPadToHeapSized = 16 * 1024 * 1024;
11752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> page_buffer(
11760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        new uint8[((data_size + kPadToHeapSized + 4095) & ~4095)]);
11770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* data_ptr = page_buffer.get();
11780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!data_ptr) {
11790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_WARNING) << "Failed to allocate memory for ValidateFrame test.";
11800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_FALSE(expected_result);  // NULL is okay if failure was expected.
11810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
11820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
11830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    data_ptr += kPadToHeapSized + (-(static_cast<int>(data_size)) & 4095);
11842a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    memcpy(data_ptr, sample, rtc::_min(data_size, sample_size));
11850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
11860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(expected_result, frame.Validate(fourcc, kWidth, kHeight,
11870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                data_ptr,
11880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                sample_size + size_adjust));
11890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
11900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I420 MJPG buffer.
11930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateMjpgI420() {
11940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kJpeg420Filename, cricket::FOURCC_MJPG, 0, 0, true);
11950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I422 MJPG buffer.
11980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateMjpgI422() {
11990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kJpeg422Filename, cricket::FOURCC_MJPG, 0, 0, true);
12000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I444 MJPG buffer.
12030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateMjpgI444() {
12040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kJpeg444Filename, cricket::FOURCC_MJPG, 0, 0, true);
12050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I411 MJPG buffer.
12080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateMjpgI411() {
12090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kJpeg411Filename, cricket::FOURCC_MJPG, 0, 0, true);
12100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I400 MJPG buffer.
12130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateMjpgI400() {
12140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kJpeg400Filename, cricket::FOURCC_MJPG, 0, 0, true);
12150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I420 buffer.
12180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateI420() {
12190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 0, 0, true);
12200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I420 buffer where size is too small
12230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateI420SmallSize() {
12240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 0, -16384, false);
12250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I420 buffer where size is too large (16 MB)
12280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Will produce warning but pass.
12290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateI420LargeSize() {
12300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 16000000, 16000000,
12310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  true);
12320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate for I420 buffer where size is 1 GB (not reasonable).
12350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateI420HugeSize() {
12360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifndef WIN32  // TODO(fbarchard): Reenable when fixing bug 9603762.
12370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ValidateFrame(kImageFilename, cricket::FOURCC_I420, 1000000000u,
12380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  1000000000u, false);
12390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif
12400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // The following test that Validate crashes if the size is greater than the
12430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // actual buffer size.
12440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(fbarchard): Consider moving a filter into the capturer/plugin.
12450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#if defined(_MSC_VER) && defined(_DEBUG)
12460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int ExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
12470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (code == EXCEPTION_ACCESS_VIOLATION) {
12480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_INFO) << "Caught EXCEPTION_ACCESS_VIOLATION as expected.";
12490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return EXCEPTION_EXECUTE_HANDLER;
12500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
12510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_INFO) << "Did not catch EXCEPTION_ACCESS_VIOLATION.  Unexpected.";
12520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return EXCEPTION_CONTINUE_SEARCH;
12530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
12540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate fails for truncated MJPG data buffer.  If ValidateFrame
12570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // crashes the exception handler will return and unittest passes with OK.
12580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateMjpgI420InvalidSize() {
12590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    __try {
12600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ValidateFrame(kJpeg420Filename, cricket::FOURCC_MJPG, -16384, 0, false);
12610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      FAIL() << "Validate was expected to cause EXCEPTION_ACCESS_VIOLATION.";
12620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } __except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation())) {
12630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;  // Successfully crashed in ValidateFrame.
12640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
12650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test validate fails for truncated I420 buffer.
12680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ValidateI420InvalidSize() {
12690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    __try {
12700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ValidateFrame(kImageFilename, cricket::FOURCC_I420, -16384, 0, false);
12710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      FAIL() << "Validate was expected to cause EXCEPTION_ACCESS_VIOLATION.";
12720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } __except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation())) {
12730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;  // Successfully crashed in ValidateFrame.
12740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
12750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif
12770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer (and synonymous formats).
12790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2Aliases() {
12800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2, frame3, frame4;
12812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
12820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight));
12830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
12840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight,
12850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &frame1));
12860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
12870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
12880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUVS,
12890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame3));
12900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUYV,
12910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame4));
12920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
12930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));
12940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame4, 0));
12950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a UYVY buffer (and synonymous formats).
12980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructUyvyAliases() {
12990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2, frame3, frame4;
13002a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
13010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateYuv422Sample(cricket::FOURCC_UYVY, kWidth, kHeight));
13020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
13030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_UYVY, kWidth, kHeight,
13040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &frame1));
13050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_UYVY,
13060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame2));
13070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_2VUY,
13080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame3));
13090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_HDYC,
13100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          kWidth, kHeight, &frame4));
13110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
13120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame3, 0));
13130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame4, 0));
13140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test creating a copy.
13170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructCopy() {
13180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
13190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
13200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
13210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame2.Init(frame1));
13220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
13240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test creating a copy and check that it just increments the refcount.
13270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructCopyIsRef() {
13280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
13290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
13300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
13310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame2.Init(frame1));
13320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
13340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(frame1.GetYPlane(), frame2.GetYPlane());
13350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(frame1.GetUPlane(), frame2.GetUPlane());
13360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(frame1.GetVPlane(), frame2.GetVPlane());
13370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test creating an empty image and initing it to black.
13400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructBlack() {
13410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
13420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
13430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_TRUE(frame.InitToBlack(kWidth, kHeight, 1, 1, 0, 0));
13440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsSize(frame, kWidth, kHeight));
13460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsBlack(frame));
13470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a YUY2 buffer with a range of sizes.
13500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Only tests that conversion does not crash or corrupt heap.
13510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructYuy2AllSizes() {
13520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
13530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int height = kMinHeightAll; height <= kMaxHeightAll; ++height) {
13540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (int width = kMinWidthAll; width <= kMaxWidthAll; ++width) {
13552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::scoped_ptr<rtc::MemoryStream> ms(
13560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            CreateYuv422Sample(cricket::FOURCC_YUY2, width, height));
13570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_TRUE(ms.get() != NULL);
13580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(ConvertYuv422(ms.get(), cricket::FOURCC_YUY2, width, height,
13590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                  &frame1));
13600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2,
13610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              width, height, &frame2));
13620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(IsEqual(frame1, frame2, 0));
13630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
13640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test constructing an image from a ARGB buffer with a range of sizes.
13680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Only tests that conversion does not crash or corrupt heap.
13690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConstructARGBAllSizes() {
13700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
13710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int height = kMinHeightAll; height <= kMaxHeightAll; ++height) {
13720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (int width = kMinWidthAll; width <= kMaxWidthAll; ++width) {
13732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::scoped_ptr<rtc::MemoryStream> ms(
13740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            CreateRgbSample(cricket::FOURCC_ARGB, width, height));
13750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_TRUE(ms.get() != NULL);
13760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB, width, height,
13770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               &frame1));
13780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
13790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              width, height, &frame2));
13800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(IsEqual(frame1, frame2, 64));
13810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
13820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Test a practical window size for screencasting usecase.
13840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const int kOddWidth = 1228;
13850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const int kOddHeight = 260;
13860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int j = 0; j < 2; ++j) {
13870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (int i = 0; i < 2; ++i) {
13882a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::scoped_ptr<rtc::MemoryStream> ms(
13890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kOddWidth + i, kOddHeight + j));
13900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_TRUE(ms.get() != NULL);
13910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(ConvertRgb(ms.get(), cricket::FOURCC_ARGB,
13920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               kOddWidth + i, kOddHeight + j,
13930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               &frame1));
13940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_ARGB,
13950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              kOddWidth + i, kOddHeight + j, &frame2));
13960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        EXPECT_TRUE(IsEqual(frame1, frame2, 64));
13970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
13980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests re-initing an existing image.
14020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void Reset() {
14030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
14042a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
14050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LoadSample(kImageFilename));
1406a39fcda7b56709e660a3d3fd171cb9e963e7e532wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
14070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size;
14080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ms->GetSize(&data_size);
14090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame1.InitToBlack(kWidth, kHeight, 1, 1, 0, 0));
14100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame2.InitToBlack(kWidth, kHeight, 1, 1, 0, 0));
14110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsBlack(frame1));
14120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 0));
14130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame1.Reset(cricket::FOURCC_I420,
14140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             kWidth, kHeight, kWidth, kHeight,
14150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             reinterpret_cast<uint8*>(ms->GetBuffer()),
14160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             data_size, 1, 1, 0, 0, 0));
14170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(IsBlack(frame1));
14180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(IsEqual(frame1, frame2, 0));
14190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //////////////////////
14220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Conversion tests //
14230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //////////////////////
14240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  enum ToFrom { TO, FROM };
14260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Helper function for test converting from I420 to packed formats.
14280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  inline void ConvertToBuffer(int bpp, int rowpad, bool invert, ToFrom to_from,
14290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      int error, uint32 fourcc,
14300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      int (*RGBToI420)(const uint8* src_frame, int src_stride_frame,
14310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       uint8* dst_y, int dst_stride_y,
14320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       uint8* dst_u, int dst_stride_u,
14330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       uint8* dst_v, int dst_stride_v,
14340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       int width, int height)) {
14350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
14360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int repeat_to = (to_from == TO) ? repeat_ : 1;
14370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int repeat_from  = (to_from == FROM) ? repeat_ : 1;
14380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int astride = kWidth * bpp + rowpad;
14400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = astride * kHeight;
14412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment + 1]);
14420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    memset(outbuf.get(), 0, out_size + kAlignment + 1);
144392891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* outtop = ALIGNP(outbuf.get(), kAlignment);
144492891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* out = outtop;
14450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int stride = astride;
14460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (invert) {
14470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      out += (kHeight - 1) * stride;  // Point to last row.
14480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      stride = -stride;
14490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
14500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
14510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_to; ++i) {
14530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(fourcc,
14540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                    out,
14550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                    out_size, stride));
14560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
14570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame2.InitToBlack(kWidth, kHeight, 1, 1, 0, 0));
14580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_from; ++i) {
14590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(0, RGBToI420(out, stride,
14600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             frame2.GetYPlane(), frame2.GetYPitch(),
14610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             frame2.GetUPlane(), frame2.GetUPitch(),
14620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             frame2.GetVPlane(), frame2.GetVPitch(),
14630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             kWidth, kHeight));
14640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
14650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (rowpad) {
14660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(0, outtop[kWidth * bpp]);  // Ensure stride skipped end of row.
14670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_NE(0, outtop[astride]);       // Ensure pixel at start of 2nd row.
14680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
14690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_NE(0, outtop[kWidth * bpp]);  // Expect something to be here.
14700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
14710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0, outtop[out_size]);      // Ensure no overrun.
14720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, error));
14730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kError = 20;
14760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kErrorHigh = 40;
14770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static const int kOddStride = 23;
14780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ConvertToRGBBuffer formats.
14800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGBBuffer() {
14810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, false, TO, kError,
14820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
14830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBGRABuffer() {
14850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, false, TO, kError,
14860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
14870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToABGRBuffer() {
14890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, false, TO, kError,
14900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
14910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRGB24Buffer() {
14930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, false, TO, kError,
14940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
14950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRAWBuffer() {
14970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, false, TO, kError,
14980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
14990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRGB565Buffer() {
15010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
15020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
15030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGB1555Buffer() {
15050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
15060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
15070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGB4444Buffer() {
15090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
15100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
15110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerBGGRBuffer() {
15130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, TO, kErrorHigh,
15140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGGR, libyuv::BayerBGGRToI420);
15150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerGBRGBuffer() {
15170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, TO, kErrorHigh,
15180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GBRG, libyuv::BayerGBRGToI420);
15190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerGRBGBuffer() {
15210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, TO, kErrorHigh,
15220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GRBG, libyuv::BayerGRBGToI420);
15230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerRGGBBuffer() {
15250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, TO, kErrorHigh,
15260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGGB, libyuv::BayerRGGBToI420);
15270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToI400Buffer() {
15290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, TO, 128,
15300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
15310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToYUY2Buffer() {
15330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
15340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
15350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToUYVYBuffer() {
15370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, TO, kError,
15380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
15390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ConvertToRGBBuffer formats with odd stride.
15420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGBBufferStride() {
15430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, TO, kError,
15440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
15450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBGRABufferStride() {
15470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, TO, kError,
15480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
15490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToABGRBufferStride() {
15510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, TO, kError,
15520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
15530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRGB24BufferStride() {
15550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, TO, kError,
15560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
15570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRAWBufferStride() {
15590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, TO, kError,
15600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
15610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRGB565BufferStride() {
15630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
15640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
15650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGB1555BufferStride() {
15670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
15680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
15690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGB4444BufferStride() {
15710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
15720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
15730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerBGGRBufferStride() {
15750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, TO, kErrorHigh,
15760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGGR, libyuv::BayerBGGRToI420);
15770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerGBRGBufferStride() {
15790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, TO, kErrorHigh,
15800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GBRG, libyuv::BayerGBRGToI420);
15810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerGRBGBufferStride() {
15830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, TO, kErrorHigh,
15840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GRBG, libyuv::BayerGRBGToI420);
15850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerRGGBBufferStride() {
15870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, TO, kErrorHigh,
15880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGGB, libyuv::BayerRGGBToI420);
15890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToI400BufferStride() {
15910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, TO, 128,
15920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
15930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToYUY2BufferStride() {
15950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
15960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
15970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToUYVYBufferStride() {
15990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, TO, kError,
16000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
16010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ConvertToRGBBuffer formats with negative stride to invert image.
16040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGBBufferInverted() {
16050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, true, TO, kError,
16060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
16070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBGRABufferInverted() {
16090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, true, TO, kError,
16100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
16110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToABGRBufferInverted() {
16130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, true, TO, kError,
16140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
16150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRGB24BufferInverted() {
16170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, true, TO, kError,
16180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
16190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRAWBufferInverted() {
16210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, true, TO, kError,
16220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
16230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToRGB565BufferInverted() {
16250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
16260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
16270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGB1555BufferInverted() {
16290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
16300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
16310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToARGB4444BufferInverted() {
16330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
16340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
16350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerBGGRBufferInverted() {
16370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, TO, kErrorHigh,
16380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGGR, libyuv::BayerBGGRToI420);
16390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerGBRGBufferInverted() {
16410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, TO, kErrorHigh,
16420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GBRG, libyuv::BayerGBRGToI420);
16430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerGRBGBufferInverted() {
16450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, TO, kErrorHigh,
16460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GRBG, libyuv::BayerGRBGToI420);
16470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToBayerRGGBBufferInverted() {
16490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, TO, kErrorHigh,
16500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGGB, libyuv::BayerRGGBToI420);
16510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToI400BufferInverted() {
16530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, TO, 128,
16540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
16550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToYUY2BufferInverted() {
16570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
16580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
16590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToUYVYBufferInverted() {
16610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, TO, kError,
16620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
16630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ConvertFrom formats.
16660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGBBuffer() {
16670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, false, FROM, kError,
16680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
16690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBGRABuffer() {
16710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, false, FROM, kError,
16720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
16730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromABGRBuffer() {
16750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, false, FROM, kError,
16760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
16770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRGB24Buffer() {
16790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, false, FROM, kError,
16800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
16810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRAWBuffer() {
16830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, false, FROM, kError,
16840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
16850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRGB565Buffer() {
16870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
16880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
16890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGB1555Buffer() {
16910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
16920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
16930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGB4444Buffer() {
16950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
16960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
16970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerBGGRBuffer() {
16990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, FROM, kErrorHigh,
17000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGGR, libyuv::BayerBGGRToI420);
17010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerGBRGBuffer() {
17030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, FROM, kErrorHigh,
17040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GBRG, libyuv::BayerGBRGToI420);
17050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerGRBGBuffer() {
17070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, FROM, kErrorHigh,
17080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GRBG, libyuv::BayerGRBGToI420);
17090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerRGGBBuffer() {
17110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, FROM, kErrorHigh,
17120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGGB, libyuv::BayerRGGBToI420);
17130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromI400Buffer() {
17150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, false, FROM, 128,
17160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
17170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromYUY2Buffer() {
17190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
17200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
17210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromUYVYBuffer() {
17230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, false, FROM, kError,
17240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
17250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ConvertFrom formats with odd stride.
17280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGBBufferStride() {
17290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, FROM, kError,
17300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
17310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBGRABufferStride() {
17330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, FROM, kError,
17340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
17350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromABGRBufferStride() {
17370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, kOddStride, false, FROM, kError,
17380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
17390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRGB24BufferStride() {
17410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, FROM, kError,
17420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
17430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRAWBufferStride() {
17450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, kOddStride, false, FROM, kError,
17460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
17470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRGB565BufferStride() {
17490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
17500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
17510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGB1555BufferStride() {
17530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
17540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
17550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGB4444BufferStride() {
17570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
17580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
17590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerBGGRBufferStride() {
17610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, FROM, kErrorHigh,
17620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGGR, libyuv::BayerBGGRToI420);
17630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerGBRGBufferStride() {
17650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, FROM, kErrorHigh,
17660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GBRG, libyuv::BayerGBRGToI420);
17670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerGRBGBufferStride() {
17690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, FROM, kErrorHigh,
17700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GRBG, libyuv::BayerGRBGToI420);
17710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerRGGBBufferStride() {
17730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, FROM, kErrorHigh,
17740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGGB, libyuv::BayerRGGBToI420);
17750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromI400BufferStride() {
17770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, kOddStride, false, FROM, 128,
17780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
17790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromYUY2BufferStride() {
17810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
17820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
17830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromUYVYBufferStride() {
17850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, kOddStride, false, FROM, kError,
17860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
17870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ConvertFrom formats with negative stride to invert image.
17900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGBBufferInverted() {
17910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, true, FROM, kError,
17920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ARGB, libyuv::ARGBToI420);
17930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBGRABufferInverted() {
17950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, true, FROM, kError,
17960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGRA, libyuv::BGRAToI420);
17970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromABGRBufferInverted() {
17990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(4, 0, true, FROM, kError,
18000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_ABGR, libyuv::ABGRToI420);
18010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRGB24BufferInverted() {
18030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, true, FROM, kError,
18040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_24BG, libyuv::RGB24ToI420);
18050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRAWBufferInverted() {
18070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(3, 0, true, FROM, kError,
18080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RAW, libyuv::RAWToI420);
18090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromRGB565BufferInverted() {
18110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
18120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBP, libyuv::RGB565ToI420);
18130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGB1555BufferInverted() {
18150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
18160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGBO, libyuv::ARGB1555ToI420);
18170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromARGB4444BufferInverted() {
18190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
18200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_R444, libyuv::ARGB4444ToI420);
18210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerBGGRBufferInverted() {
18230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, FROM, kErrorHigh,
18240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_BGGR, libyuv::BayerBGGRToI420);
18250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerGBRGBufferInverted() {
18270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, FROM, kErrorHigh,
18280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GBRG, libyuv::BayerGBRGToI420);
18290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerGRBGBufferInverted() {
18310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, FROM, kErrorHigh,
18320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_GRBG, libyuv::BayerGRBGToI420);
18330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromBayerRGGBBufferInverted() {
18350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, FROM, kErrorHigh,
18360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_RGGB, libyuv::BayerRGGBToI420);
18370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromI400BufferInverted() {
18390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(1, 0, true, FROM, 128,
18400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_I400, libyuv::I400ToI420);
18410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromYUY2BufferInverted() {
18430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
18440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_YUY2, libyuv::YUY2ToI420);
18450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertFromUYVYBufferInverted() {
18470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ConvertToBuffer(2, 0, true, FROM, kError,
18480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    cricket::FOURCC_UYVY, libyuv::UYVYToI420);
18490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
18510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test converting from I420 to I422.
18520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ConvertToI422Buffer() {
18530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame1, frame2;
18540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 2;
18552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> buf(new uint8[out_size + kAlignment]);
18560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* y = ALIGNP(buf.get(), kAlignment);
18570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* u = y + kWidth * kHeight;
18580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8* v = u + (kWidth / 2) * kHeight;
18590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
18600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
18610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(),
18620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                      frame1.GetUPlane(), frame1.GetUPitch(),
18630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                      frame1.GetVPlane(), frame1.GetVPitch(),
18640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                      y, kWidth,
18650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                      u, kWidth / 2,
18660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                      v, kWidth / 2,
18670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                      kWidth, kHeight));
18680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
18690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame2.Init(cricket::FOURCC_I422,
18700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            kWidth, kHeight, kWidth, kHeight,
18710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            y,
18720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            out_size,  1, 1, 0, 0, cricket::ROTATION_0));
1873cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org    EXPECT_TRUE(IsEqual(frame1, frame2, 1));
18740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
18750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
18760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  #define TEST_TOBYR(NAME, BAYER)                                              \
18770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void NAME() {                                                                \
18780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t bayer_size = kWidth * kHeight;                                      \
18792a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[                         \
18800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer_size + kAlignment]);                                             \
188192891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* bayer = ALIGNP(bayerbuf.get(), kAlignment);                         \
18820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;                                                                   \
18832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                         \
18840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));               \
18850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
18860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {                                        \
18870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8*>(ms->GetBuffer()),    \
18880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kWidth * 4,                                   \
18890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 bayer, kWidth,                                \
18900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kWidth, kHeight);                             \
18910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }                                                                          \
18922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms2(                        \
18930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));               \
18940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size;                                                          \
18950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = ms2->GetSize(&data_size);                                       \
18960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ret);                                                          \
18970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    libyuv::Bayer##BAYER##ToARGB(bayer, kWidth,                                \
18980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 reinterpret_cast<uint8*>(ms2->GetBuffer()),   \
18990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kWidth * 4,                                   \
19000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kWidth, kHeight);                             \
19010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("argb",                                           \
19020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        reinterpret_cast<uint8*>(ms->GetBuffer()), kWidth * 4,                 \
19030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        reinterpret_cast<uint8*>(ms2->GetBuffer()), kWidth * 4,                \
19040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        kWidth * 4, kHeight, 240));                                            \
19050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }                                                                            \
19060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void NAME##Unaligned() {                                                     \
19070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t bayer_size = kWidth * kHeight;                                      \
19082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[                         \
19090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer_size + 1 + kAlignment]);                                         \
191092891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* bayer = ALIGNP(bayerbuf.get(), kAlignment) + 1;                     \
19110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;                                                                   \
19122a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                         \
19130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));               \
19140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
19150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {                                        \
19160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8*>(ms->GetBuffer()),    \
19170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kWidth * 4,                                   \
19180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 bayer, kWidth,                                \
19190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kWidth, kHeight);                             \
19200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }                                                                          \
19212a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms2(                        \
19220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));               \
19230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t data_size;                                                          \
19240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = ms2->GetSize(&data_size);                                       \
19250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(ret);                                                          \
19260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    libyuv::Bayer##BAYER##ToARGB(bayer, kWidth,                                \
19270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           reinterpret_cast<uint8*>(ms2->GetBuffer()),         \
19280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           kWidth * 4,                                         \
19290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           kWidth, kHeight);                                   \
19300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("argb",                                           \
19310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        reinterpret_cast<uint8*>(ms->GetBuffer()), kWidth * 4,                 \
19320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        reinterpret_cast<uint8*>(ms2->GetBuffer()), kWidth * 4,                \
19330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        kWidth * 4, kHeight, 240));                                            \
19340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
19350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
19360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests ARGB to Bayer formats.
19370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_TOBYR(ConvertARGBToBayerGRBG, GRBG)
19380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_TOBYR(ConvertARGBToBayerGBRG, GBRG)
19390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_TOBYR(ConvertARGBToBayerBGGR, BGGR)
19400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_TOBYR(ConvertARGBToBayerRGGB, RGGB)
19410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
19420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  #define TEST_BYRTORGB(NAME, BAYER)                                           \
19430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void NAME() {                                                                \
19440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t bayer_size = kWidth * kHeight;                                      \
19452a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[                         \
19460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer_size + kAlignment]);                                             \
194792891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* bayer1 = ALIGNP(bayerbuf.get(), kAlignment);                        \
19480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < kWidth * kHeight; ++i) {                               \
19490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      bayer1[i] = static_cast<uint8>(i * 33u + 183u);                          \
19500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }                                                                          \
19510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;                                                                   \
19522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(                         \
19530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight));               \
19540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms.get() != NULL);                                             \
19550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {                                        \
19560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      libyuv::Bayer##BAYER##ToARGB(bayer1, kWidth,                             \
19570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             reinterpret_cast<uint8*>(ms->GetBuffer()),        \
19580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             kWidth * 4,                                       \
19590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             kWidth, kHeight);                                 \
19600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }                                                                          \
19612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> bayer2buf(new uint8[                        \
19620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer_size + kAlignment]);                                             \
196392891450ef8cbfbaf1e003e4d9f78d102160d631thorcarpenter@google.com    uint8* bayer2 = ALIGNP(bayer2buf.get(), kAlignment);                       \
19640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8*>(ms->GetBuffer()),      \
19650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           kWidth * 4,                                         \
19660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           bayer2, kWidth,                                     \
19670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           kWidth, kHeight);                                   \
19680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsPlaneEqual("bayer",                                          \
19690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer1, kWidth,                                                        \
19700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        bayer2, kWidth,                                                        \
19710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        kWidth, kHeight, 0));                                                  \
19720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
19730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
19740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tests Bayer formats to ARGB.
19750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYRTORGB(ConvertBayerGRBGToARGB, GRBG)
19760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYRTORGB(ConvertBayerGBRGToARGB, GBRG)
19770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYRTORGB(ConvertBayerBGGRToARGB, BGGR)
19780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TEST_BYRTORGB(ConvertBayerRGGBToARGB, RGGB)
19790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
19800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ///////////////////
19810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // General tests //
19820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ///////////////////
19830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
19840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void Copy() {
19852a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<T> source(new T);
19862a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<cricket::VideoFrame> target;
19870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(source.get()));
19880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    target.reset(source->Copy());
19890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(*source, *target, 0));
19900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    source.reset();
19910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(target->GetYPlane() != NULL);
19920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
19930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
19940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CopyIsRef() {
19952a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<T> source(new T);
19962a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<cricket::VideoFrame> target;
19970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(source.get()));
19980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    target.reset(source->Copy());
19990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(*source, *target, 0));
20000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(source->GetYPlane(), target->GetYPlane());
20010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(source->GetUPlane(), target->GetUPlane());
20020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(source->GetVPlane(), target->GetVPlane());
20030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
20040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void MakeExclusive() {
20062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<T> source(new T);
20072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<cricket::VideoFrame> target;
20080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(source.get()));
20090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    target.reset(source->Copy());
20100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(target->MakeExclusive());
20110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(*source, *target, 0));
20120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_NE(target->GetYPlane(), source->GetYPlane());
20130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_NE(target->GetUPlane(), source->GetUPlane());
20140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_NE(target->GetVPlane(), source->GetVPlane());
20150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
20160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CopyToBuffer() {
20180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
20192a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
20200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LoadSample(kImageFilename));
2021a39fcda7b56709e660a3d3fd171cb9e963e7e532wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
20220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight,
20230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &frame));
20240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = kWidth * kHeight * 3 / 2;
20252a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> out(new uint8[out_size]);
20260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
20270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size));
20280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
20290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0, memcmp(out.get(), ms->GetBuffer(), out_size));
20300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
20310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CopyToFrame() {
20330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T source;
20342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
20350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LoadSample(kImageFilename));
2036a39fcda7b56709e660a3d3fd171cb9e963e7e532wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
20370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight,
20380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &source));
20390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create the target frame by loading from a file.
20410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T target;
20420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&target));
20430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(IsBlack(target));
20440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Stretch and check if the stretched target is black.
20460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    source.CopyToFrame(&target);
20470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsEqual(source, target, 0));
20490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
20500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void Write() {
20520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
20532a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::MemoryStream> ms(
20540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LoadSample(kImageFilename));
2055a39fcda7b56709e660a3d3fd171cb9e963e7e532wu@webrtc.org    ASSERT_TRUE(ms.get() != NULL);
20562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::MemoryStream ms2;
20570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t size;
20580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms->GetSize(&size));
20590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(ms2.ReserveSize(size));
20600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight,
20610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &frame));
20620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
20630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ms2.SetPosition(0u);  // Useful when repeat_ > 1.
20640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      int error;
20652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      EXPECT_EQ(rtc::SR_SUCCESS, frame.Write(&ms2, &error));
20660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
20670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = cricket::VideoFrame::SizeOf(kWidth, kHeight);
20680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0, memcmp(ms2.GetBuffer(), ms->GetBuffer(), out_size));
20690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
20700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CopyToBuffer1Pixel() {
20720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t out_size = 3;
20732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<uint8[]> out(new uint8[out_size + 1]);
20740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    memset(out.get(), 0xfb, out_size + 1);  // Fill buffer
20750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint8 pixel[3] = { 1, 2, 3 };
20760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T frame;
20770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1,
20780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           pixel, sizeof(pixel),
20790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           1, 1, 0, 0, 0));
20800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < repeat_; ++i) {
20810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size));
20820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
20830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(1, out.get()[0]);  // Check Y.  Should be 1.
20840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(2, out.get()[1]);  // Check U.  Should be 2.
20850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(3, out.get()[2]);  // Check V.  Should be 3.
20860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(0xfb, out.get()[3]);  // Check sentinel is still intact.
20870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
20880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void StretchToFrame() {
20900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create the source frame as a black frame.
20910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T source;
20920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(source.InitToBlack(kWidth * 2, kHeight * 2, 1, 1, 0, 0));
20930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsSize(source, kWidth * 2, kHeight * 2));
20940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create the target frame by loading from a file.
20960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T target1;
20970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&target1));
20980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(IsBlack(target1));
20990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
21000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Stretch and check if the stretched target is black.
21010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    source.StretchToFrame(&target1, true, false);
21020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsBlack(target1));
21030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
21040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Crop and stretch and check if the stretched target is black.
21050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    T target2;
21060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(LoadFrameNoRepeat(&target2));
21070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    source.StretchToFrame(&target2, true, true);
21080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(IsBlack(target2));
21090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(source.GetElapsedTime(), target2.GetElapsedTime());
21100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(source.GetTimeStamp(), target2.GetTimeStamp());
21110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
21120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
21130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int repeat_;
21140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
21150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
21160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif  // TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_
2117