Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Unified Diff: talk/session/media/planarfunctions_unittest.cc

Issue 1691463002: Move talk/session/media -> webrtc/pc (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Last rebase Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « talk/session/media/mediasink.h ('k') | talk/session/media/rtcpmuxfilter.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/session/media/planarfunctions_unittest.cc
diff --git a/talk/session/media/planarfunctions_unittest.cc b/talk/session/media/planarfunctions_unittest.cc
deleted file mode 100644
index 9e5624bb1c144836ba1c771870b0629126be9179..0000000000000000000000000000000000000000
--- a/talk/session/media/planarfunctions_unittest.cc
+++ /dev/null
@@ -1,942 +0,0 @@
-/*
- * libjingle
- * Copyright 2014 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "libyuv/convert.h"
-#include "libyuv/convert_from.h"
-#include "libyuv/convert_from_argb.h"
-#include "libyuv/mjpeg_decoder.h"
-#include "libyuv/planar_functions.h"
-#include "webrtc/base/flags.h"
-#include "webrtc/base/gunit.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/media/base/testutils.h"
-#include "webrtc/media/base/videocommon.h"
-
-// Undefine macros for the windows build.
-#undef max
-#undef min
-
-using cricket::DumpPlanarYuvTestImage;
-
-DEFINE_bool(planarfunctions_dump, false,
- "whether to write out scaled images for inspection");
-DEFINE_int(planarfunctions_repeat, 1,
- "how many times to perform each scaling operation (for perf testing)");
-
-namespace cricket {
-
-// Number of testing colors in each color channel.
-static const int kTestingColorChannelResolution = 6;
-
-// The total number of testing colors
-// kTestingColorNum = kTestingColorChannelResolution^3;
-static const int kTestingColorNum = kTestingColorChannelResolution *
- kTestingColorChannelResolution * kTestingColorChannelResolution;
-
-static const int kWidth = 1280;
-static const int kHeight = 720;
-static const int kAlignment = 16;
-
-class PlanarFunctionsTest : public testing::TestWithParam<int> {
- protected:
- PlanarFunctionsTest() : dump_(false), repeat_(1) {
- InitializeColorBand();
- }
-
- virtual void SetUp() {
- dump_ = FLAG_planarfunctions_dump;
- repeat_ = FLAG_planarfunctions_repeat;
- }
-
- // Initialize the color band for testing.
- void InitializeColorBand() {
- testing_color_y_.reset(new uint8_t[kTestingColorNum]);
- testing_color_u_.reset(new uint8_t[kTestingColorNum]);
- testing_color_v_.reset(new uint8_t[kTestingColorNum]);
- testing_color_r_.reset(new uint8_t[kTestingColorNum]);
- testing_color_g_.reset(new uint8_t[kTestingColorNum]);
- testing_color_b_.reset(new uint8_t[kTestingColorNum]);
- int color_counter = 0;
- for (int i = 0; i < kTestingColorChannelResolution; ++i) {
- uint8_t color_r =
- static_cast<uint8_t>(i * 255 / (kTestingColorChannelResolution - 1));
- for (int j = 0; j < kTestingColorChannelResolution; ++j) {
- uint8_t color_g = static_cast<uint8_t>(
- j * 255 / (kTestingColorChannelResolution - 1));
- for (int k = 0; k < kTestingColorChannelResolution; ++k) {
- uint8_t color_b = static_cast<uint8_t>(
- k * 255 / (kTestingColorChannelResolution - 1));
- testing_color_r_[color_counter] = color_r;
- testing_color_g_[color_counter] = color_g;
- testing_color_b_[color_counter] = color_b;
- // Converting the testing RGB colors to YUV colors.
- ConvertRgbPixel(color_r, color_g, color_b,
- &(testing_color_y_[color_counter]),
- &(testing_color_u_[color_counter]),
- &(testing_color_v_[color_counter]));
- ++color_counter;
- }
- }
- }
- }
- // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia.
- // (from lmivideoframe_unittest.cc)
- void ConvertRgbPixel(uint8_t r,
- uint8_t g,
- uint8_t b,
- uint8_t* y,
- uint8_t* u,
- uint8_t* v) {
- *y = ClampUint8(.257 * r + .504 * g + .098 * b + 16);
- *u = ClampUint8(-.148 * r - .291 * g + .439 * b + 128);
- *v = ClampUint8(.439 * r - .368 * g - .071 * b + 128);
- }
-
- uint8_t ClampUint8(double value) {
- value = std::max(0., std::min(255., value));
- uint8_t uint8_value = static_cast<uint8_t>(value);
- return uint8_value;
- }
-
- // Generate a Red-Green-Blue inter-weaving chessboard-like
- // YUV testing image (I420/I422/I444).
- // The pattern looks like c0 c1 c2 c3 ...
- // c1 c2 c3 c4 ...
- // c2 c3 c4 c5 ...
- // ...............
- // The size of each chrome block is (block_size) x (block_size).
- uint8_t* CreateFakeYuvTestingImage(int height,
- int width,
- int block_size,
- libyuv::JpegSubsamplingType subsample_type,
- uint8_t*& y_pointer,
- uint8_t*& u_pointer,
- uint8_t*& v_pointer) {
- if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; }
- int y_size = height * width;
- int u_size, v_size;
- int vertical_sample_ratio = 1, horizontal_sample_ratio = 1;
- switch (subsample_type) {
- case libyuv::kJpegYuv420:
- u_size = ((height + 1) >> 1) * ((width + 1) >> 1);
- v_size = u_size;
- vertical_sample_ratio = 2, horizontal_sample_ratio = 2;
- break;
- case libyuv::kJpegYuv422:
- u_size = height * ((width + 1) >> 1);
- v_size = u_size;
- vertical_sample_ratio = 1, horizontal_sample_ratio = 2;
- break;
- case libyuv::kJpegYuv444:
- v_size = u_size = y_size;
- vertical_sample_ratio = 1, horizontal_sample_ratio = 1;
- break;
- case libyuv::kJpegUnknown:
- default:
- return NULL;
- break;
- }
- uint8_t* image_pointer = new uint8_t[y_size + u_size + v_size + kAlignment];
- y_pointer = ALIGNP(image_pointer, kAlignment);
- u_pointer = ALIGNP(&image_pointer[y_size], kAlignment);
- v_pointer = ALIGNP(&image_pointer[y_size + u_size], kAlignment);
- uint8_t* current_y_pointer = y_pointer;
- uint8_t* current_u_pointer = u_pointer;
- uint8_t* current_v_pointer = v_pointer;
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) % kTestingColorNum;
- *(current_y_pointer++) = testing_color_y_[color];
- if (i % horizontal_sample_ratio == 0 &&
- j % vertical_sample_ratio == 0) {
- *(current_u_pointer++) = testing_color_u_[color];
- *(current_v_pointer++) = testing_color_v_[color];
- }
- }
- }
- return image_pointer;
- }
-
- // Generate a Red-Green-Blue inter-weaving chessboard-like
- // YUY2/UYVY testing image.
- // The pattern looks like c0 c1 c2 c3 ...
- // c1 c2 c3 c4 ...
- // c2 c3 c4 c5 ...
- // ...............
- // The size of each chrome block is (block_size) x (block_size).
- uint8_t* CreateFakeInterleaveYuvTestingImage(int height,
- int width,
- int block_size,
- uint8_t*& yuv_pointer,
- FourCC fourcc_type) {
- if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; }
- if (fourcc_type != FOURCC_YUY2 && fourcc_type != FOURCC_UYVY) {
- LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type)
- << " is not supported.";
- return NULL;
- }
- // Regularize the width of the output to be even.
- int awidth = (width + 1) & ~1;
-
- uint8_t* image_pointer = new uint8_t[2 * height * awidth + kAlignment];
- yuv_pointer = ALIGNP(image_pointer, kAlignment);
- uint8_t* current_yuv_pointer = yuv_pointer;
- switch (fourcc_type) {
- case FOURCC_YUY2: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < awidth; i += 2, current_yuv_pointer += 4) {
- int color1 = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- int color2 = (((i + 1) / block_size) + (j / block_size)) %
- kTestingColorNum;
- current_yuv_pointer[0] = testing_color_y_[color1];
- if (i < width) {
- current_yuv_pointer[1] = static_cast<uint8_t>(
- (static_cast<uint32_t>(testing_color_u_[color1]) +
- static_cast<uint32_t>(testing_color_u_[color2])) /
- 2);
- current_yuv_pointer[2] = testing_color_y_[color2];
- current_yuv_pointer[3] = static_cast<uint8_t>(
- (static_cast<uint32_t>(testing_color_v_[color1]) +
- static_cast<uint32_t>(testing_color_v_[color2])) /
- 2);
- } else {
- current_yuv_pointer[1] = testing_color_u_[color1];
- current_yuv_pointer[2] = 0;
- current_yuv_pointer[3] = testing_color_v_[color1];
- }
- }
- }
- break;
- }
- case FOURCC_UYVY: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < awidth; i += 2, current_yuv_pointer += 4) {
- int color1 = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- int color2 = (((i + 1) / block_size) + (j / block_size)) %
- kTestingColorNum;
- if (i < width) {
- current_yuv_pointer[0] = static_cast<uint8_t>(
- (static_cast<uint32_t>(testing_color_u_[color1]) +
- static_cast<uint32_t>(testing_color_u_[color2])) /
- 2);
- current_yuv_pointer[1] = testing_color_y_[color1];
- current_yuv_pointer[2] = static_cast<uint8_t>(
- (static_cast<uint32_t>(testing_color_v_[color1]) +
- static_cast<uint32_t>(testing_color_v_[color2])) /
- 2);
- current_yuv_pointer[3] = testing_color_y_[color2];
- } else {
- current_yuv_pointer[0] = testing_color_u_[color1];
- current_yuv_pointer[1] = testing_color_y_[color1];
- current_yuv_pointer[2] = testing_color_v_[color1];
- current_yuv_pointer[3] = 0;
- }
- }
- }
- break;
- }
- }
- return image_pointer;
- }
-
- // Generate a Red-Green-Blue inter-weaving chessboard-like
- // NV12 testing image.
- // (Note: No interpolation is used.)
- // The pattern looks like c0 c1 c2 c3 ...
- // c1 c2 c3 c4 ...
- // c2 c3 c4 c5 ...
- // ...............
- // The size of each chrome block is (block_size) x (block_size).
- uint8_t* CreateFakeNV12TestingImage(int height,
- int width,
- int block_size,
- uint8_t*& y_pointer,
- uint8_t*& uv_pointer) {
- if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; }
-
- uint8_t* image_pointer =
- new uint8_t[height * width +
- ((height + 1) / 2) * ((width + 1) / 2) * 2 + kAlignment];
- y_pointer = ALIGNP(image_pointer, kAlignment);
- uv_pointer = y_pointer + height * width;
- uint8_t* current_uv_pointer = uv_pointer;
- uint8_t* current_y_pointer = y_pointer;
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_y_pointer++) = testing_color_y_[color];
- }
- if (j % 2 == 0) {
- for (int i = 0; i < width; i += 2, current_uv_pointer += 2) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- current_uv_pointer[0] = testing_color_u_[color];
- current_uv_pointer[1] = testing_color_v_[color];
- }
- }
- }
- return image_pointer;
- }
-
- // Generate a Red-Green-Blue inter-weaving chessboard-like
- // M420 testing image.
- // (Note: No interpolation is used.)
- // The pattern looks like c0 c1 c2 c3 ...
- // c1 c2 c3 c4 ...
- // c2 c3 c4 c5 ...
- // ...............
- // The size of each chrome block is (block_size) x (block_size).
- uint8_t* CreateFakeM420TestingImage(int height,
- int width,
- int block_size,
- uint8_t*& m420_pointer) {
- if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; }
-
- uint8_t* image_pointer =
- new uint8_t[height * width +
- ((height + 1) / 2) * ((width + 1) / 2) * 2 + kAlignment];
- m420_pointer = ALIGNP(image_pointer, kAlignment);
- uint8_t* current_m420_pointer = m420_pointer;
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_m420_pointer++) = testing_color_y_[color];
- }
- if (j % 2 == 1) {
- for (int i = 0; i < width; i += 2, current_m420_pointer += 2) {
- int color = ((i / block_size) + ((j - 1) / block_size)) %
- kTestingColorNum;
- current_m420_pointer[0] = testing_color_u_[color];
- current_m420_pointer[1] = testing_color_v_[color];
- }
- }
- }
- return image_pointer;
- }
-
- // Generate a Red-Green-Blue inter-weaving chessboard-like
- // ARGB/ABGR/RAW/BG24 testing image.
- // The pattern looks like c0 c1 c2 c3 ...
- // c1 c2 c3 c4 ...
- // c2 c3 c4 c5 ...
- // ...............
- // The size of each chrome block is (block_size) x (block_size).
- uint8_t* CreateFakeArgbTestingImage(int height,
- int width,
- int block_size,
- uint8_t*& argb_pointer,
- FourCC fourcc_type) {
- if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; }
- uint8_t* image_pointer = NULL;
- if (fourcc_type == FOURCC_ABGR || fourcc_type == FOURCC_BGRA ||
- fourcc_type == FOURCC_ARGB) {
- image_pointer = new uint8_t[height * width * 4 + kAlignment];
- } else if (fourcc_type == FOURCC_RAW || fourcc_type == FOURCC_24BG) {
- image_pointer = new uint8_t[height * width * 3 + kAlignment];
- } else {
- LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type)
- << " is not supported.";
- return NULL;
- }
- argb_pointer = ALIGNP(image_pointer, kAlignment);
- uint8_t* current_pointer = argb_pointer;
- switch (fourcc_type) {
- case FOURCC_ARGB: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_pointer++) = testing_color_b_[color];
- *(current_pointer++) = testing_color_g_[color];
- *(current_pointer++) = testing_color_r_[color];
- *(current_pointer++) = 255;
- }
- }
- break;
- }
- case FOURCC_ABGR: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_pointer++) = testing_color_r_[color];
- *(current_pointer++) = testing_color_g_[color];
- *(current_pointer++) = testing_color_b_[color];
- *(current_pointer++) = 255;
- }
- }
- break;
- }
- case FOURCC_BGRA: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_pointer++) = 255;
- *(current_pointer++) = testing_color_r_[color];
- *(current_pointer++) = testing_color_g_[color];
- *(current_pointer++) = testing_color_b_[color];
- }
- }
- break;
- }
- case FOURCC_24BG: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_pointer++) = testing_color_b_[color];
- *(current_pointer++) = testing_color_g_[color];
- *(current_pointer++) = testing_color_r_[color];
- }
- }
- break;
- }
- case FOURCC_RAW: {
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- int color = ((i / block_size) + (j / block_size)) %
- kTestingColorNum;
- *(current_pointer++) = testing_color_r_[color];
- *(current_pointer++) = testing_color_g_[color];
- *(current_pointer++) = testing_color_b_[color];
- }
- }
- break;
- }
- default: {
- LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type)
- << " is not supported.";
- }
- }
- return image_pointer;
- }
-
- // Check if two memory chunks are equal.
- // (tolerate MSE errors within a threshold).
- static bool IsMemoryEqual(const uint8_t* ibuf,
- const uint8_t* obuf,
- int osize,
- double average_error) {
- double sse = cricket::ComputeSumSquareError(ibuf, obuf, osize);
- double error = sse / osize; // Mean Squared Error.
- double PSNR = cricket::ComputePSNR(sse, osize);
- LOG(LS_INFO) << "Image MSE: " << error << " Image PSNR: " << PSNR
- << " First Diff Byte: " << FindDiff(ibuf, obuf, osize);
- return (error < average_error);
- }
-
- // Returns the index of the first differing byte. Easier to debug than memcmp.
- static int FindDiff(const uint8_t* buf1, const uint8_t* buf2, int len) {
- int i = 0;
- while (i < len && buf1[i] == buf2[i]) {
- i++;
- }
- return (i < len) ? i : -1;
- }
-
- // Dump the result image (ARGB format).
- void DumpArgbImage(const uint8_t* obuf, int width, int height) {
- DumpPlanarArgbTestImage(GetTestName(), obuf, width, height);
- }
-
- // Dump the result image (YUV420 format).
- void DumpYuvImage(const uint8_t* obuf, int width, int height) {
- DumpPlanarYuvTestImage(GetTestName(), obuf, width, height);
- }
-
- std::string GetTestName() {
- const testing::TestInfo* const test_info =
- testing::UnitTest::GetInstance()->current_test_info();
- std::string test_name(test_info->name());
- return test_name;
- }
-
- bool dump_;
- int repeat_;
-
- // Y, U, V and R, G, B channels of testing colors.
- rtc::scoped_ptr<uint8_t[]> testing_color_y_;
- rtc::scoped_ptr<uint8_t[]> testing_color_u_;
- rtc::scoped_ptr<uint8_t[]> testing_color_v_;
- rtc::scoped_ptr<uint8_t[]> testing_color_r_;
- rtc::scoped_ptr<uint8_t[]> testing_color_g_;
- rtc::scoped_ptr<uint8_t[]> testing_color_b_;
-};
-
-TEST_F(PlanarFunctionsTest, I420Copy) {
- uint8_t* y_pointer = nullptr;
- uint8_t* u_pointer = nullptr;
- uint8_t* v_pointer = nullptr;
- int y_pitch = kWidth;
- int u_pitch = (kWidth + 1) >> 1;
- int v_pitch = (kWidth + 1) >> 1;
- int y_size = kHeight * kWidth;
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1);
- int block_size = 3;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer,
- v_pointer));
- // Allocate space for the output image.
- rtc::scoped_ptr<uint8_t[]> yuv_output(
- new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment]);
- uint8_t* y_output_pointer = ALIGNP(yuv_output.get(), kAlignment);
- uint8_t* u_output_pointer = y_output_pointer + y_size;
- uint8_t* v_output_pointer = u_output_pointer + uv_size;
-
- for (int i = 0; i < repeat_; ++i) {
- libyuv::I420Copy(y_pointer, y_pitch,
- u_pointer, u_pitch,
- v_pointer, v_pitch,
- y_output_pointer, y_pitch,
- u_output_pointer, u_pitch,
- v_output_pointer, v_pitch,
- kWidth, kHeight);
- }
-
- // Expect the copied frame to be exactly the same.
- EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer,
- I420_SIZE(kHeight, kWidth), 1.e-6));
-
- if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); }
-}
-
-TEST_F(PlanarFunctionsTest, I422ToI420) {
- uint8_t* y_pointer = nullptr;
- uint8_t* u_pointer = nullptr;
- uint8_t* v_pointer = nullptr;
- int y_pitch = kWidth;
- int u_pitch = (kWidth + 1) >> 1;
- int v_pitch = (kWidth + 1) >> 1;
- int y_size = kHeight * kWidth;
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1);
- int block_size = 2;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv422, y_pointer, u_pointer,
- v_pointer));
- // Allocate space for the output image.
- rtc::scoped_ptr<uint8_t[]> yuv_output(
- new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment]);
- uint8_t* y_output_pointer = ALIGNP(yuv_output.get(), kAlignment);
- uint8_t* u_output_pointer = y_output_pointer + y_size;
- uint8_t* v_output_pointer = u_output_pointer + uv_size;
- // Generate the expected output.
- uint8_t* y_expected_pointer = nullptr;
- uint8_t* u_expected_pointer = nullptr;
- uint8_t* v_expected_pointer = nullptr;
- rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer,
- u_expected_pointer, v_expected_pointer));
-
- for (int i = 0; i < repeat_; ++i) {
- libyuv::I422ToI420(y_pointer, y_pitch,
- u_pointer, u_pitch,
- v_pointer, v_pitch,
- y_output_pointer, y_pitch,
- u_output_pointer, u_pitch,
- v_output_pointer, v_pitch,
- kWidth, kHeight);
- }
-
- // Compare the output frame with what is expected; expect exactly the same.
- // Note: MSE should be set to a larger threshold if an odd block width
- // is used, since the conversion will be lossy.
- EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer,
- I420_SIZE(kHeight, kWidth), 1.e-6));
-
- if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); }
-}
-
-TEST_P(PlanarFunctionsTest, M420ToI420) {
- // Get the unalignment offset
- int unalignment = GetParam();
- uint8_t* m420_pointer = NULL;
- int y_pitch = kWidth;
- int m420_pitch = kWidth;
- int u_pitch = (kWidth + 1) >> 1;
- int v_pitch = (kWidth + 1) >> 1;
- int y_size = kHeight * kWidth;
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1);
- int block_size = 2;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> yuv_input(
- CreateFakeM420TestingImage(kHeight, kWidth, block_size, m420_pointer));
- // Allocate space for the output image.
- rtc::scoped_ptr<uint8_t[]> yuv_output(
- new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]);
- uint8_t* y_output_pointer =
- ALIGNP(yuv_output.get(), kAlignment) + unalignment;
- uint8_t* u_output_pointer = y_output_pointer + y_size;
- uint8_t* v_output_pointer = u_output_pointer + uv_size;
- // Generate the expected output.
- uint8_t* y_expected_pointer = nullptr;
- uint8_t* u_expected_pointer = nullptr;
- uint8_t* v_expected_pointer = nullptr;
- rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer,
- u_expected_pointer, v_expected_pointer));
-
- for (int i = 0; i < repeat_; ++i) {
- libyuv::M420ToI420(m420_pointer, m420_pitch,
- y_output_pointer, y_pitch,
- u_output_pointer, u_pitch,
- v_output_pointer, v_pitch,
- kWidth, kHeight);
- }
- // Compare the output frame with what is expected; expect exactly the same.
- // Note: MSE should be set to a larger threshold if an odd block width
- // is used, since the conversion will be lossy.
- EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer,
- I420_SIZE(kHeight, kWidth), 1.e-6));
-
- if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); }
-}
-
-TEST_P(PlanarFunctionsTest, NV12ToI420) {
- // Get the unalignment offset
- int unalignment = GetParam();
- uint8_t* y_pointer = nullptr;
- uint8_t* uv_pointer = nullptr;
- int y_pitch = kWidth;
- int uv_pitch = 2 * ((kWidth + 1) >> 1);
- int u_pitch = (kWidth + 1) >> 1;
- int v_pitch = (kWidth + 1) >> 1;
- int y_size = kHeight * kWidth;
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1);
- int block_size = 2;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeNV12TestingImage(
- kHeight, kWidth, block_size, y_pointer, uv_pointer));
- // Allocate space for the output image.
- rtc::scoped_ptr<uint8_t[]> yuv_output(
- new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]);
- uint8_t* y_output_pointer =
- ALIGNP(yuv_output.get(), kAlignment) + unalignment;
- uint8_t* u_output_pointer = y_output_pointer + y_size;
- uint8_t* v_output_pointer = u_output_pointer + uv_size;
- // Generate the expected output.
- uint8_t* y_expected_pointer = nullptr;
- uint8_t* u_expected_pointer = nullptr;
- uint8_t* v_expected_pointer = nullptr;
- rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer,
- u_expected_pointer, v_expected_pointer));
-
- for (int i = 0; i < repeat_; ++i) {
- libyuv::NV12ToI420(y_pointer, y_pitch,
- uv_pointer, uv_pitch,
- y_output_pointer, y_pitch,
- u_output_pointer, u_pitch,
- v_output_pointer, v_pitch,
- kWidth, kHeight);
- }
- // Compare the output frame with what is expected; expect exactly the same.
- // Note: MSE should be set to a larger threshold if an odd block width
- // is used, since the conversion will be lossy.
- EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer,
- I420_SIZE(kHeight, kWidth), 1.e-6));
-
- if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); }
-}
-
-// A common macro for testing converting YUY2/UYVY to I420.
-#define TEST_YUVTOI420(SRC_NAME, MSE, BLOCK_SIZE) \
- TEST_P(PlanarFunctionsTest, SRC_NAME##ToI420) { \
- /* Get the unalignment offset.*/ \
- int unalignment = GetParam(); \
- uint8_t* yuv_pointer = nullptr; \
- int yuv_pitch = 2 * ((kWidth + 1) & ~1); \
- int y_pitch = kWidth; \
- int u_pitch = (kWidth + 1) >> 1; \
- int v_pitch = (kWidth + 1) >> 1; \
- int y_size = kHeight * kWidth; \
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); \
- int block_size = 2; \
- /* Generate a fake input image.*/ \
- rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeInterleaveYuvTestingImage( \
- kHeight, kWidth, BLOCK_SIZE, yuv_pointer, FOURCC_##SRC_NAME)); \
- /* Allocate space for the output image.*/ \
- rtc::scoped_ptr<uint8_t[]> yuv_output( \
- new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); \
- uint8_t* y_output_pointer = \
- ALIGNP(yuv_output.get(), kAlignment) + unalignment; \
- uint8_t* u_output_pointer = y_output_pointer + y_size; \
- uint8_t* v_output_pointer = u_output_pointer + uv_size; \
- /* Generate the expected output.*/ \
- uint8_t* y_expected_pointer = nullptr; \
- uint8_t* u_expected_pointer = nullptr; \
- uint8_t* v_expected_pointer = nullptr; \
- rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( \
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, \
- u_expected_pointer, v_expected_pointer)); \
- for (int i = 0; i < repeat_; ++i) { \
- libyuv::SRC_NAME##ToI420(yuv_pointer, yuv_pitch, y_output_pointer, \
- y_pitch, u_output_pointer, u_pitch, \
- v_output_pointer, v_pitch, kWidth, kHeight); \
- } \
- /* Compare the output frame with what is expected.*/ \
- /* Note: MSE should be set to a larger threshold if an odd block width*/ \
- /* is used, since the conversion will be lossy.*/ \
- EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, \
- I420_SIZE(kHeight, kWidth), MSE)); \
- if (dump_) { \
- DumpYuvImage(y_output_pointer, kWidth, kHeight); \
- } \
- }
-
-// TEST_P(PlanarFunctionsTest, YUV2ToI420)
-TEST_YUVTOI420(YUY2, 1.e-6, 2);
-// TEST_P(PlanarFunctionsTest, UYVYToI420)
-TEST_YUVTOI420(UYVY, 1.e-6, 2);
-
-// A common macro for testing converting I420 to ARGB, BGRA and ABGR.
-#define TEST_YUVTORGB(SRC_NAME, DST_NAME, JPG_TYPE, MSE, BLOCK_SIZE) \
- TEST_F(PlanarFunctionsTest, SRC_NAME##To##DST_NAME) { \
- uint8_t* y_pointer = nullptr; \
- uint8_t* u_pointer = nullptr; \
- uint8_t* v_pointer = nullptr; \
- uint8_t* argb_expected_pointer = NULL; \
- int y_pitch = kWidth; \
- int u_pitch = (kWidth + 1) >> 1; \
- int v_pitch = (kWidth + 1) >> 1; \
- /* Generate a fake input image.*/ \
- rtc::scoped_ptr<uint8_t[]> yuv_input( \
- CreateFakeYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, JPG_TYPE, \
- y_pointer, u_pointer, v_pointer)); \
- /* Generate the expected output.*/ \
- rtc::scoped_ptr<uint8_t[]> argb_expected( \
- CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \
- argb_expected_pointer, FOURCC_##DST_NAME)); \
- /* Allocate space for the output.*/ \
- rtc::scoped_ptr<uint8_t[]> argb_output( \
- new uint8_t[kHeight * kWidth * 4 + kAlignment]); \
- uint8_t* argb_pointer = ALIGNP(argb_expected.get(), kAlignment); \
- for (int i = 0; i < repeat_; ++i) { \
- libyuv::SRC_NAME##To##DST_NAME(y_pointer, y_pitch, u_pointer, u_pitch, \
- v_pointer, v_pitch, argb_pointer, \
- kWidth * 4, kWidth, kHeight); \
- } \
- EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \
- kHeight* kWidth * 4, MSE)); \
- if (dump_) { \
- DumpArgbImage(argb_pointer, kWidth, kHeight); \
- } \
- }
-
-// TEST_F(PlanarFunctionsTest, I420ToARGB)
-TEST_YUVTORGB(I420, ARGB, libyuv::kJpegYuv420, 3., 2);
-// TEST_F(PlanarFunctionsTest, I420ToABGR)
-TEST_YUVTORGB(I420, ABGR, libyuv::kJpegYuv420, 3., 2);
-// TEST_F(PlanarFunctionsTest, I420ToBGRA)
-TEST_YUVTORGB(I420, BGRA, libyuv::kJpegYuv420, 3., 2);
-// TEST_F(PlanarFunctionsTest, I422ToARGB)
-TEST_YUVTORGB(I422, ARGB, libyuv::kJpegYuv422, 3., 2);
-// TEST_F(PlanarFunctionsTest, I444ToARGB)
-TEST_YUVTORGB(I444, ARGB, libyuv::kJpegYuv444, 3., 3);
-// Note: an empirical MSE tolerance 3.0 is used here for the probable
-// error from float-to-uint8_t type conversion.
-
-TEST_F(PlanarFunctionsTest, I400ToARGB_Reference) {
- uint8_t* y_pointer = nullptr;
- uint8_t* u_pointer = nullptr;
- uint8_t* v_pointer = nullptr;
- int y_pitch = kWidth;
- int u_pitch = (kWidth + 1) >> 1;
- int v_pitch = (kWidth + 1) >> 1;
- int block_size = 3;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer,
- v_pointer));
- // As the comparison standard, we convert a grayscale image (by setting both
- // U and V channels to be 128) using an I420 converter.
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1);
-
- rtc::scoped_ptr<uint8_t[]> uv(new uint8_t[uv_size + kAlignment]);
- u_pointer = v_pointer = ALIGNP(uv.get(), kAlignment);
- memset(u_pointer, 128, uv_size);
-
- // Allocate space for the output image and generate the expected output.
- rtc::scoped_ptr<uint8_t[]> argb_expected(
- new uint8_t[kHeight * kWidth * 4 + kAlignment]);
- rtc::scoped_ptr<uint8_t[]> argb_output(
- new uint8_t[kHeight * kWidth * 4 + kAlignment]);
- uint8_t* argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment);
- uint8_t* argb_pointer = ALIGNP(argb_output.get(), kAlignment);
-
- libyuv::I420ToARGB(y_pointer, y_pitch,
- u_pointer, u_pitch,
- v_pointer, v_pitch,
- argb_expected_pointer, kWidth * 4,
- kWidth, kHeight);
- for (int i = 0; i < repeat_; ++i) {
- libyuv::I400ToARGB_Reference(y_pointer, y_pitch,
- argb_pointer, kWidth * 4,
- kWidth, kHeight);
- }
-
- // Note: I420ToARGB and I400ToARGB_Reference should produce identical results.
- EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer,
- kHeight * kWidth * 4, 2.));
- if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); }
-}
-
-TEST_P(PlanarFunctionsTest, I400ToARGB) {
- // Get the unalignment offset
- int unalignment = GetParam();
- uint8_t* y_pointer = nullptr;
- uint8_t* u_pointer = nullptr;
- uint8_t* v_pointer = nullptr;
- int y_pitch = kWidth;
- int u_pitch = (kWidth + 1) >> 1;
- int v_pitch = (kWidth + 1) >> 1;
- int block_size = 3;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer,
- v_pointer));
- // As the comparison standard, we convert a grayscale image (by setting both
- // U and V channels to be 128) using an I420 converter.
- int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1);
-
- // 1 byte extra if in the unaligned mode.
- rtc::scoped_ptr<uint8_t[]> uv(new uint8_t[uv_size * 2 + kAlignment]);
- u_pointer = ALIGNP(uv.get(), kAlignment);
- v_pointer = u_pointer + uv_size;
- memset(u_pointer, 128, uv_size);
- memset(v_pointer, 128, uv_size);
-
- // Allocate space for the output image and generate the expected output.
- rtc::scoped_ptr<uint8_t[]> argb_expected(
- new uint8_t[kHeight * kWidth * 4 + kAlignment]);
- // 1 byte extra if in the misalinged mode.
- rtc::scoped_ptr<uint8_t[]> argb_output(
- new uint8_t[kHeight * kWidth * 4 + kAlignment + unalignment]);
- uint8_t* argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment);
- uint8_t* argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment;
-
- libyuv::I420ToARGB(y_pointer, y_pitch,
- u_pointer, u_pitch,
- v_pointer, v_pitch,
- argb_expected_pointer, kWidth * 4,
- kWidth, kHeight);
- for (int i = 0; i < repeat_; ++i) {
- libyuv::I400ToARGB(y_pointer, y_pitch,
- argb_pointer, kWidth * 4,
- kWidth, kHeight);
- }
-
- // Note: current I400ToARGB uses an approximate method,
- // so the error tolerance is larger here.
- EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer,
- kHeight * kWidth * 4, 64.0));
- if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); }
-}
-
-TEST_P(PlanarFunctionsTest, ARGBToI400) {
- // Get the unalignment offset
- int unalignment = GetParam();
- // Create a fake ARGB input image.
- uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL;
- uint8_t* argb_pointer = NULL;
- int block_size = 3;
- // Generate a fake input image.
- rtc::scoped_ptr<uint8_t[]> argb_input(CreateFakeArgbTestingImage(
- kHeight, kWidth, block_size, argb_pointer, FOURCC_ARGB));
- // Generate the expected output. Only Y channel is used
- rtc::scoped_ptr<uint8_t[]> yuv_expected(CreateFakeYuvTestingImage(
- kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer,
- v_pointer));
- // Allocate space for the Y output.
- rtc::scoped_ptr<uint8_t[]> y_output(
- new uint8_t[kHeight * kWidth + kAlignment + unalignment]);
- uint8_t* y_output_pointer = ALIGNP(y_output.get(), kAlignment) + unalignment;
-
- for (int i = 0; i < repeat_; ++i) {
- libyuv::ARGBToI400(argb_pointer, kWidth * 4, y_output_pointer, kWidth,
- kWidth, kHeight);
- }
- // Check if the output matches the input Y channel.
- // Note: an empirical MSE tolerance 2.0 is used here for the probable
- // error from float-to-uint8_t type conversion.
- EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer,
- kHeight * kWidth, 2.));
- if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); }
-}
-
-// A common macro for testing converting RAW, BG24, BGRA, and ABGR
-// to ARGB.
-#define TEST_ARGB(SRC_NAME, FC_ID, BPP, BLOCK_SIZE) \
- TEST_P(PlanarFunctionsTest, SRC_NAME##ToARGB) { \
- int unalignment = GetParam(); /* Get the unalignment offset.*/ \
- uint8_t* argb_expected_pointer = NULL, * src_pointer = NULL; \
- /* Generate a fake input image.*/ \
- rtc::scoped_ptr<uint8_t[]> src_input(CreateFakeArgbTestingImage( \
- kHeight, kWidth, BLOCK_SIZE, src_pointer, FOURCC_##FC_ID)); \
- /* Generate the expected output.*/ \
- rtc::scoped_ptr<uint8_t[]> argb_expected(CreateFakeArgbTestingImage( \
- kHeight, kWidth, BLOCK_SIZE, argb_expected_pointer, FOURCC_ARGB)); \
- /* Allocate space for the output; 1 byte extra if in the unaligned mode.*/ \
- rtc::scoped_ptr<uint8_t[]> argb_output( \
- new uint8_t[kHeight * kWidth * 4 + kAlignment + unalignment]); \
- uint8_t* argb_pointer = \
- ALIGNP(argb_output.get(), kAlignment) + unalignment; \
- for (int i = 0; i < repeat_; ++i) { \
- libyuv::SRC_NAME##ToARGB(src_pointer, kWidth*(BPP), argb_pointer, \
- kWidth * 4, kWidth, kHeight); \
- } \
- /* Compare the result; expect identical.*/ \
- EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \
- kHeight* kWidth * 4, 1.e-6)); \
- if (dump_) { \
- DumpArgbImage(argb_pointer, kWidth, kHeight); \
- } \
- }
-
-TEST_ARGB(RAW, RAW, 3, 3); // TEST_P(PlanarFunctionsTest, RAWToARGB)
-TEST_ARGB(BG24, 24BG, 3, 3); // TEST_P(PlanarFunctionsTest, BG24ToARGB)
-TEST_ARGB(ABGR, ABGR, 4, 3); // TEST_P(PlanarFunctionsTest, ABGRToARGB)
-TEST_ARGB(BGRA, BGRA, 4, 3); // TEST_P(PlanarFunctionsTest, BGRAToARGB)
-
-// Parameter Test: The parameter is the unalignment offset.
-// Aligned data for testing assembly versions.
-INSTANTIATE_TEST_CASE_P(PlanarFunctionsAligned, PlanarFunctionsTest,
- ::testing::Values(0));
-
-// Purposely unalign the output argb pointer to test slow path (C version).
-INSTANTIATE_TEST_CASE_P(PlanarFunctionsMisaligned, PlanarFunctionsTest,
- ::testing::Values(1));
-
-} // namespace cricket
« no previous file with comments | « talk/session/media/mediasink.h ('k') | talk/session/media/rtcpmuxfilter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698