diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-01 03:30:39 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-01 03:30:39 +0000 |
commit | 7155d7caafd2aa1fb822dc5672c90ea446247e8d (patch) | |
tree | b8197522349c36f1141b13b354a031d96f8c146c /media | |
parent | d76d7c4b106b272e6c6cea47e5b91c9f8e83e31c (diff) | |
download | chromium_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.cc | 9 | ||||
-rw-r--r-- | media/base/yuv_convert_unittest.cc | 337 |
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(), |