summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-01 03:30:39 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-01 03:30:39 +0000
commit7155d7caafd2aa1fb822dc5672c90ea446247e8d (patch)
treeb8197522349c36f1141b13b354a031d96f8c146c /media
parentd76d7c4b106b272e6c6cea47e5b91c9f8e83e31c (diff)
downloadchromium_src-7155d7caafd2aa1fb822dc5672c90ea446247e8d.zip
chromium_src-7155d7caafd2aa1fb822dc5672c90ea446247e8d.tar.gz
chromium_src-7155d7caafd2aa1fb822dc5672c90ea446247e8d.tar.bz2
Add check for zero-sized source YUV + tests.
Took the time to clean up said tests for improved coverage. BUG=90173 TEST=media_unittests Review URL: http://codereview.chromium.org/7794016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99113 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/yuv_convert.cc9
-rw-r--r--media/base/yuv_convert_unittest.cc337
2 files changed, 155 insertions, 191 deletions
diff --git a/media/base/yuv_convert.cc b/media/base/yuv_convert.cc
index bf0f2ca..d332065 100644
--- a/media/base/yuv_convert.cc
+++ b/media/base/yuv_convert.cc
@@ -177,6 +177,12 @@ void ScaleYUVToRGB32(const uint8* y_buf,
YUVType yuv_type,
Rotate view_rotate,
ScaleFilter filter) {
+ // Handle zero sized sources and destinations.
+ if ((yuv_type == YV12 && (source_width < 2 || source_height < 2)) ||
+ (yuv_type == YV16 && (source_width < 2 || source_height < 1)) ||
+ width == 0 || height == 0)
+ return;
+
// 4096 allows 3 buffers to fit in 12k.
// Helps performance on CPU with 16K L1 cache.
// Large enough for 3830x2160 and 30" displays which are 2560x1600.
@@ -216,9 +222,6 @@ void ScaleYUVToRGB32(const uint8* y_buf,
source_height = -source_height;
}
- // Handle zero sized destination.
- if (width == 0 || height == 0)
- return;
int source_dx = source_width * kFractionMax / width;
int source_dy = source_height * kFractionMax / height;
#if USE_MMX && defined(_MSC_VER)
diff --git a/media/base/yuv_convert_unittest.cc b/media/base/yuv_convert_unittest.cc
index 6140cb0..78c4f85 100644
--- a/media/base/yuv_convert_unittest.cc
+++ b/media/base/yuv_convert_unittest.cc
@@ -4,6 +4,7 @@
#include "base/base_paths.h"
#include "base/file_util.h"
+#include "base/logging.h"
#include "base/path_service.h"
#include "media/base/djb2.h"
#include "media/base/yuv_convert.h"
@@ -18,31 +19,63 @@ static const int kScaledWidth = 1024;
static const int kScaledHeight = 768;
static const int kBpp = 4;
-// Surface sizes.
-static const size_t kYUV12Size = kSourceYSize * 12 / 8;
-static const size_t kYUV16Size = kSourceYSize * 16 / 8;
-static const size_t kYUY2Size = kSourceYSize * 16 / 8;
-static const size_t kRGBSize = kSourceYSize * kBpp;
-static const size_t kRGB24Size = kSourceYSize * 3;
-static const size_t kRGBSizeConverted = kSourceYSize * kBpp;
+// Surface sizes for various test files.
+static const int kYUV12Size = kSourceYSize * 12 / 8;
+static const int kYUV16Size = kSourceYSize * 16 / 8;
+static const int kYUY2Size = kSourceYSize * 16 / 8;
+static const int kRGBSize = kSourceYSize * kBpp;
+static const int kRGBSizeScaled = kScaledWidth * kScaledHeight * kBpp;
+static const int kRGB24Size = kSourceYSize * 3;
+static const int kRGBSizeConverted = kSourceYSize * kBpp;
+
+// Helper for reading test data into a scoped_array<uint8>.
+static void ReadData(const FilePath::CharType* filename,
+ int expected_size,
+ scoped_array<uint8>* data) {
+ data->reset(new uint8[expected_size]);
+
+ FilePath path;
+ CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &path));
+ path = path.Append(FILE_PATH_LITERAL("media"))
+ .Append(FILE_PATH_LITERAL("test"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(filename);
+
+ // Verify file size is correct.
+ int64 actual_size = 0;
+ file_util::GetFileSize(path, &actual_size);
+ CHECK_EQ(actual_size, expected_size);
+
+ // Verify bytes read are correct.
+ int bytes_read = file_util::ReadFile(
+ path, reinterpret_cast<char*>(data->get()), expected_size);
+ CHECK_EQ(bytes_read, expected_size);
+}
+
+static void ReadYV12Data(scoped_array<uint8>* data) {
+ ReadData(FILE_PATH_LITERAL("bali_640x360_P420.yuv"), kYUV12Size, data);
+}
+
+static void ReadYV16Data(scoped_array<uint8>* data) {
+ ReadData(FILE_PATH_LITERAL("bali_640x360_P422.yuv"), kYUV16Size, data);
+}
+
+static void ReadRGB24Data(scoped_array<uint8>* data) {
+ ReadData(FILE_PATH_LITERAL("bali_640x360_RGB24.rgb"), kRGB24Size, data);
+}
+
+static void ReadYUY2Data(scoped_array<uint8>* data) {
+ ReadData(FILE_PATH_LITERAL("bali_640x360_YUY2.yuv"), kYUY2Size, data);
+}
TEST(YUVConvertTest, YV12) {
// Allocate all surfaces.
- scoped_array<uint8> yuv_bytes(new uint8[kYUV12Size]);
+ scoped_array<uint8> yuv_bytes;
scoped_array<uint8> rgb_bytes(new uint8[kRGBSize]);
scoped_array<uint8> rgb_converted_bytes(new uint8[kRGBSizeConverted]);
// Read YUV reference data from file.
- FilePath yuv_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
- yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_P420.yuv"));
- EXPECT_EQ(static_cast<int>(kYUV12Size),
- file_util::ReadFile(yuv_url,
- reinterpret_cast<char*>(yuv_bytes.get()),
- static_cast<int>(kYUV12Size)));
+ ReadYV12Data(&yuv_bytes);
// Convert a frame of YUV to 32 bit ARGB.
media::ConvertYUVToRGB32(yuv_bytes.get(),
@@ -62,21 +95,12 @@ TEST(YUVConvertTest, YV12) {
TEST(YUVConvertTest, YV16) {
// Allocate all surfaces.
- scoped_array<uint8> yuv_bytes(new uint8[kYUV16Size]);
+ scoped_array<uint8> yuv_bytes;
scoped_array<uint8> rgb_bytes(new uint8[kRGBSize]);
scoped_array<uint8> rgb_converted_bytes(new uint8[kRGBSizeConverted]);
- // Read YV16 reference data from file.
- FilePath yuv_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
- yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_P422.yuv"));
- EXPECT_EQ(static_cast<int>(kYUV16Size),
- file_util::ReadFile(yuv_url,
- reinterpret_cast<char*>(yuv_bytes.get()),
- static_cast<int>(kYUV16Size)));
+ // Read YUV reference data from file.
+ ReadYV16Data(&yuv_bytes);
// Convert a frame of YUV to 32 bit ARGB.
media::ConvertYUVToRGB32(yuv_bytes.get(), // Y
@@ -94,153 +118,109 @@ TEST(YUVConvertTest, YV16) {
EXPECT_EQ(4222342047u, rgb_hash);
}
-TEST(YUVScaleTest, YV12) {
- // Read YUV reference data from file.
- FilePath yuv_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
- yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_P420.yuv"));
- const size_t size_of_yuv = kSourceYSize * 12 / 8; // 12 bpp.
- scoped_array<uint8> yuv_bytes(new uint8[size_of_yuv]);
- EXPECT_EQ(static_cast<int>(size_of_yuv),
- file_util::ReadFile(yuv_url,
- reinterpret_cast<char*>(yuv_bytes.get()),
- static_cast<int>(size_of_yuv)));
-
- // Scale a frame of YUV to 32 bit ARGB.
- const size_t size_of_rgb_scaled = kScaledWidth * kScaledHeight * kBpp;
- scoped_array<uint8> rgb_source_bytes(new uint8[size_of_rgb_scaled]);
-
- media::ScaleYUVToRGB32(yuv_bytes.get(), // Y
- yuv_bytes.get() + kSourceYSize, // U
- yuv_bytes.get() + kSourceYSize * 5 / 4, // V
- rgb_source_bytes.get(), // Rgb output
- kSourceWidth, kSourceHeight, // Dimensions
- kScaledWidth, kScaledHeight, // Dimensions
- kSourceWidth, // YStride
- kSourceWidth / 2, // UvStride
- kScaledWidth * kBpp, // RgbStride
- media::YV12,
+struct YUVScaleTestData {
+ YUVScaleTestData(media::YUVType y, media::ScaleFilter s, uint32 r)
+ : yuv_type(y),
+ scale_filter(s),
+ rgb_hash(r) {
+ }
+
+ media::YUVType yuv_type;
+ media::ScaleFilter scale_filter;
+ uint32 rgb_hash;
+};
+
+class YUVScaleTest : public ::testing::TestWithParam<YUVScaleTestData> {
+ public:
+ YUVScaleTest() {
+ switch (GetParam().yuv_type) {
+ case media::YV12:
+ ReadYV12Data(&yuv_bytes_);
+ break;
+ case media::YV16:
+ ReadYV16Data(&yuv_bytes_);
+ break;
+ }
+
+ rgb_bytes_.reset(new uint8[kRGBSizeScaled]);
+ }
+
+ // Helpers for getting the proper Y, U and V plane offsets.
+ uint8* y_plane() { return yuv_bytes_.get(); }
+ uint8* u_plane() { return yuv_bytes_.get() + kSourceYSize; }
+ uint8* v_plane() {
+ switch (GetParam().yuv_type) {
+ case media::YV12:
+ return yuv_bytes_.get() + kSourceYSize * 5 / 4;
+ case media::YV16:
+ return yuv_bytes_.get() + kSourceYSize * 3 / 2;
+ }
+ return NULL;
+ }
+
+ scoped_array<uint8> yuv_bytes_;
+ scoped_array<uint8> rgb_bytes_;
+};
+
+TEST_P(YUVScaleTest, Normal) {
+ media::ScaleYUVToRGB32(y_plane(), // Y
+ u_plane(), // U
+ v_plane(), // V
+ rgb_bytes_.get(), // RGB output
+ kSourceWidth, kSourceHeight, // Dimensions
+ kScaledWidth, kScaledHeight, // Dimensions
+ kSourceWidth, // YStride
+ kSourceWidth / 2, // UvStride
+ kScaledWidth * kBpp, // RgbStride
+ GetParam().yuv_type,
media::ROTATE_0,
- media::FILTER_NONE);
+ GetParam().scale_filter);
- uint32 rgb_hash = DJB2Hash(rgb_source_bytes.get(), size_of_rgb_scaled,
- kDJB2HashSeed);
- EXPECT_EQ(4259656254u, rgb_hash);
+ uint32 rgb_hash = DJB2Hash(rgb_bytes_.get(), kRGBSizeScaled, kDJB2HashSeed);
+ EXPECT_EQ(GetParam().rgb_hash, rgb_hash);
}
-TEST(YUVFilterScaleTest, YV12) {
- // Read YUV reference data from file.
- FilePath yuv_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
- yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_P420.yuv"));
- const size_t size_of_yuv = kSourceYSize * 12 / 8; // 12 bpp.
- scoped_array<uint8> yuv_bytes(new uint8[size_of_yuv]);
- EXPECT_EQ(static_cast<int>(size_of_yuv),
- file_util::ReadFile(yuv_url,
- reinterpret_cast<char*>(yuv_bytes.get()),
- static_cast<int>(size_of_yuv)));
-
- // Scale a frame of YUV to 32 bit ARGB.
- const size_t size_of_rgb_scaled = kScaledWidth * kScaledHeight * kBpp;
- scoped_array<uint8> rgb_source_bytes(new uint8[size_of_rgb_scaled]);
-
- media::ScaleYUVToRGB32(yuv_bytes.get(), // Y
- yuv_bytes.get() + kSourceYSize, // U
- yuv_bytes.get() + kSourceYSize * 5 / 4, // V
- rgb_source_bytes.get(), // Rgb output
- kSourceWidth, kSourceHeight, // Dimensions
- kScaledWidth, kScaledHeight, // Dimensions
- kSourceWidth, // YStride
- kSourceWidth / 2, // UvStride
- kScaledWidth * kBpp, // RgbStride
- media::YV12,
+TEST_P(YUVScaleTest, ZeroSourceSize) {
+ media::ScaleYUVToRGB32(y_plane(), // Y
+ u_plane(), // U
+ v_plane(), // V
+ rgb_bytes_.get(), // RGB output
+ 0, 0, // Dimensions
+ kScaledWidth, kScaledHeight, // Dimensions
+ kSourceWidth, // YStride
+ kSourceWidth / 2, // UvStride
+ kScaledWidth * kBpp, // RgbStride
+ GetParam().yuv_type,
media::ROTATE_0,
- media::FILTER_BILINEAR);
+ GetParam().scale_filter);
- uint32 rgb_hash = DJB2Hash(rgb_source_bytes.get(), size_of_rgb_scaled,
- kDJB2HashSeed);
- EXPECT_EQ(2086305576u, rgb_hash);
+ // Testing for out-of-bound read/writes with AddressSanitizer.
}
-TEST(YUVScaleTest, YV16) {
- // Read YV16 reference data from file.
- FilePath yuv_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
- yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_P422.yuv"));
- const size_t size_of_yuv = kSourceYSize * 16 / 8; // 16 bpp.
- scoped_array<uint8> yuv_bytes(new uint8[size_of_yuv]);
- EXPECT_EQ(static_cast<int>(size_of_yuv),
- file_util::ReadFile(yuv_url,
- reinterpret_cast<char*>(yuv_bytes.get()),
- static_cast<int>(size_of_yuv)));
-
- // Scale a frame of YUV to 32 bit ARGB.
- const size_t size_of_rgb_scaled = kScaledWidth * kScaledHeight * kBpp;
- scoped_array<uint8> rgb_source_bytes(new uint8[size_of_rgb_scaled]);
-
- media::ScaleYUVToRGB32(yuv_bytes.get(), // Y
- yuv_bytes.get() + kSourceYSize, // U
- yuv_bytes.get() + kSourceYSize * 3 / 2, // V
- rgb_source_bytes.get(), // Rgb output
- kSourceWidth, kSourceHeight, // Dimensions
- kScaledWidth, kScaledHeight, // Dimensions
- kSourceWidth, // YStride
- kSourceWidth / 2, // UvStride
- kScaledWidth * kBpp, // RgbStride
- media::YV16,
+TEST_P(YUVScaleTest, ZeroDestinationSize) {
+ media::ScaleYUVToRGB32(y_plane(), // Y
+ u_plane(), // U
+ v_plane(), // V
+ rgb_bytes_.get(), // RGB output
+ kSourceWidth, kSourceHeight, // Dimensions
+ 0, 0, // Dimensions
+ kSourceWidth, // YStride
+ kSourceWidth / 2, // UvStride
+ kScaledWidth * kBpp, // RgbStride
+ GetParam().yuv_type,
media::ROTATE_0,
- media::FILTER_NONE);
+ GetParam().scale_filter);
- uint32 rgb_hash = DJB2Hash(rgb_source_bytes.get(), size_of_rgb_scaled,
- kDJB2HashSeed);
- EXPECT_EQ(974965419u, rgb_hash);
+ // Testing for out-of-bound read/writes with AddressSanitizer.
}
-TEST(YUVFilterScaleTest, YV16) {
- // Read YV16 reference data from file.
- FilePath yuv_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
- yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_P422.yuv"));
- const size_t size_of_yuv = kSourceYSize * 16 / 8; // 16 bpp.
- scoped_array<uint8> yuv_bytes(new uint8[size_of_yuv]);
- EXPECT_EQ(static_cast<int>(size_of_yuv),
- file_util::ReadFile(yuv_url,
- reinterpret_cast<char*>(yuv_bytes.get()),
- static_cast<int>(size_of_yuv)));
-
- // Scale a frame of YUV to 32 bit ARGB.
- const size_t size_of_rgb_scaled = kScaledWidth * kScaledHeight * kBpp;
- scoped_array<uint8> rgb_source_bytes(new uint8[size_of_rgb_scaled]);
-
- media::ScaleYUVToRGB32(yuv_bytes.get(), // Y
- yuv_bytes.get() + kSourceYSize, // U
- yuv_bytes.get() + kSourceYSize * 3 / 2, // V
- rgb_source_bytes.get(), // Rgb output
- kSourceWidth, kSourceHeight, // Dimensions
- kScaledWidth, kScaledHeight, // Dimensions
- kSourceWidth, // YStride
- kSourceWidth / 2, // UvStride
- kScaledWidth * kBpp, // RgbStride
- media::YV16,
- media::ROTATE_0,
- media::FILTER_BILINEAR);
-
- uint32 rgb_hash = DJB2Hash(rgb_source_bytes.get(), size_of_rgb_scaled,
- kDJB2HashSeed);
- EXPECT_EQ(3857179240u, rgb_hash);
-}
+INSTANTIATE_TEST_CASE_P(
+ YUVScaleFormats, YUVScaleTest,
+ ::testing::Values(
+ YUVScaleTestData(media::YV12, media::FILTER_NONE, 4259656254u),
+ YUVScaleTestData(media::YV16, media::FILTER_NONE, 974965419u),
+ YUVScaleTestData(media::YV12, media::FILTER_BILINEAR, 2086305576u),
+ YUVScaleTestData(media::YV16, media::FILTER_BILINEAR, 3857179240u)));
// This tests a known worst case YUV value, and for overflow.
TEST(YUVConvertTest, Clamp) {
@@ -274,21 +254,11 @@ TEST(YUVConvertTest, Clamp) {
TEST(YUVConvertTest, RGB24ToYUV) {
// Allocate all surfaces.
- scoped_array<uint8> rgb_bytes(new uint8[kRGB24Size]);
+ scoped_array<uint8> rgb_bytes;
scoped_array<uint8> yuv_converted_bytes(new uint8[kYUV12Size]);
// Read RGB24 reference data from file.
- FilePath rgb_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &rgb_url));
- rgb_url = rgb_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_RGB24.rgb"));
- EXPECT_EQ(static_cast<int>(kRGB24Size),
- file_util::ReadFile(rgb_url,
- reinterpret_cast<char*>(rgb_bytes.get()),
- static_cast<int>(kRGB24Size)));
-
+ ReadRGB24Data(&rgb_bytes);
// Convert to I420.
media::ConvertRGB24ToYUV(rgb_bytes.get(),
@@ -307,20 +277,11 @@ TEST(YUVConvertTest, RGB24ToYUV) {
TEST(YUVConvertTest, YUY2ToYUV) {
// Allocate all surfaces.
- scoped_array<uint8> yuy_bytes(new uint8[kYUY2Size]);
+ scoped_array<uint8> yuy_bytes;
scoped_array<uint8> yuv_converted_bytes(new uint8[kYUV12Size]);
// Read YUY reference data from file.
- FilePath yuy_url;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuy_url));
- yuy_url = yuy_url.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("bali_640x360_YUY2.yuv"));
- EXPECT_EQ(static_cast<int>(kYUY2Size),
- file_util::ReadFile(yuy_url,
- reinterpret_cast<char*>(yuy_bytes.get()),
- static_cast<int>(kYUY2Size)));
+ ReadYUY2Data(&yuy_bytes);
// Convert to I420.
media::ConvertYUY2ToYUV(yuy_bytes.get(),