| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/base_paths.h" | |
| 6 #include "base/file_util.h" | |
| 7 #include "media/base/yuv_scale.h" | |
| 8 #include "media/base/yuv_row.h" | |
| 9 #include "testing/gtest/include/gtest/gtest.h" | |
| 10 | |
| 11 // Reference images were created with the following steps | |
| 12 // ffmpeg -vframes 25 -i bali.mov -vcodec rawvideo -pix_fmt yuv420p -an | |
| 13 // bali.yv12.1280_720.yuv | |
| 14 // yuvhalf -yv12 -skip 24 bali.yv12.1280_720.yuv bali.yv12.640_360.yuv | |
| 15 | |
| 16 // ffmpeg -vframes 25 -i bali.mov -vcodec rawvideo -pix_fmt yuv422p -an | |
| 17 // bali.yv16.1280_720.yuv | |
| 18 // yuvhalf -yv16 -skip 24 bali.yv16.1280_720.yuv bali.yv16.640_360.yuv | |
| 19 | |
| 20 // After running the scale functions in the unit test below, a hash | |
| 21 // is taken and compared to a reference value. | |
| 22 // If the image or code changes, the hash will require an update. | |
| 23 // A process outside the unittest is needed to confirm the new code | |
| 24 // and data are correctly working. At this time, the author used | |
| 25 // the media_player with the same parameters and visually inspected the | |
| 26 // quality. Once satisified that the quality is correct, the hash | |
| 27 // can be updated and used to ensure quality remains the same on | |
| 28 // all future builds and ports. | |
| 29 | |
| 30 // Size of raw image. | |
| 31 static const int kWidth = 640; | |
| 32 static const int kHeight = 360; | |
| 33 static const int kScaledWidth = 1024; | |
| 34 static const int kScaledHeight = 768; | |
| 35 static const int kBpp = 4; | |
| 36 | |
| 37 // TODO(fbarchard): Move hash function to somewhere common. | |
| 38 namespace { | |
| 39 // DJB2 hash | |
| 40 unsigned int hash(unsigned char *s, size_t len, unsigned int hash = 5381) { | |
| 41 while (len--) | |
| 42 hash = hash * 33 + *s++; | |
| 43 return hash; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 TEST(YuvScaleTest, Basic) { | |
| 48 // Read YUV reference data from file. | |
| 49 FilePath yuv_url; | |
| 50 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url)); | |
| 51 yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media")) | |
| 52 .Append(FILE_PATH_LITERAL("test")) | |
| 53 .Append(FILE_PATH_LITERAL("data")) | |
| 54 .Append(FILE_PATH_LITERAL("bali.yv12.640_360.yuv")); | |
| 55 const size_t size_of_yuv = kWidth * kHeight * 12 / 8; // 12 bpp. | |
| 56 uint8* yuv_bytes = new uint8[size_of_yuv]; | |
| 57 EXPECT_EQ(static_cast<int>(size_of_yuv), | |
| 58 file_util::ReadFile(yuv_url, | |
| 59 reinterpret_cast<char*>(yuv_bytes), | |
| 60 static_cast<int>(size_of_yuv))); | |
| 61 | |
| 62 // Scale a frame of YUV to 32 bit ARGB. | |
| 63 const size_t size_of_rgb_scaled = kScaledWidth * kScaledHeight * kBpp; | |
| 64 uint8* rgb_scaled_bytes = new uint8[size_of_rgb_scaled]; | |
| 65 | |
| 66 media::ScaleYV12ToRGB32(yuv_bytes, // Y plane | |
| 67 yuv_bytes + kWidth * kHeight, // U plane | |
| 68 yuv_bytes + kWidth * kHeight * 5 / 4, // V plane | |
| 69 rgb_scaled_bytes, // Rgb output | |
| 70 kWidth, kHeight, // Dimensions | |
| 71 kScaledWidth, kScaledHeight, // Dimensions | |
| 72 kWidth, // YStride | |
| 73 kWidth / 2, // UvStride | |
| 74 kScaledWidth * kBpp, // RgbStride | |
| 75 media::ROTATE_0); | |
| 76 | |
| 77 unsigned int rgb_hash = hash(rgb_scaled_bytes, size_of_rgb_scaled); | |
| 78 | |
| 79 // To get this hash value, run once and examine the following EXPECT_EQ. | |
| 80 // Then plug new hash value into EXPECT_EQ statements. | |
| 81 | |
| 82 // TODO(fbarchard): Make reference code mimic MMX exactly | |
| 83 #if USE_MMX | |
| 84 EXPECT_EQ(379971680u, rgb_hash); | |
| 85 #else | |
| 86 EXPECT_EQ(197274901u, rgb_hash); | |
| 87 #endif | |
| 88 return; // This is here to allow you to put a break point on this line | |
| 89 } | |
| 90 | |
| 91 TEST(YV16ScaleTest, Basic) { | |
| 92 // Read YV16 reference data from file. | |
| 93 FilePath yuv_url; | |
| 94 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url)); | |
| 95 yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media")) | |
| 96 .Append(FILE_PATH_LITERAL("test")) | |
| 97 .Append(FILE_PATH_LITERAL("data")) | |
| 98 .Append(FILE_PATH_LITERAL("bali.yv16.640_360.yuv")); | |
| 99 const size_t size_of_yuv = kWidth * kHeight * 16 / 8; // 16 bpp. | |
| 100 uint8* yuv_bytes = new uint8[size_of_yuv]; | |
| 101 EXPECT_EQ(static_cast<int>(size_of_yuv), | |
| 102 file_util::ReadFile(yuv_url, | |
| 103 reinterpret_cast<char*>(yuv_bytes), | |
| 104 static_cast<int>(size_of_yuv))); | |
| 105 | |
| 106 // Scale a frame of YUV to 32 bit ARGB. | |
| 107 const size_t size_of_rgb_scaled = kScaledWidth * kScaledHeight * kBpp; | |
| 108 uint8* rgb_scaled_bytes = new uint8[size_of_rgb_scaled]; | |
| 109 | |
| 110 media::ScaleYV16ToRGB32(yuv_bytes, // Y plane | |
| 111 yuv_bytes + kWidth * kHeight, // U plane | |
| 112 yuv_bytes + kWidth * kHeight * 3 / 2, // V plane | |
| 113 rgb_scaled_bytes, // Rgb output | |
| 114 kWidth, kHeight, // Dimensions | |
| 115 kScaledWidth, kScaledHeight, // Dimensions | |
| 116 kWidth, // YStride | |
| 117 kWidth / 2, // UvStride | |
| 118 kScaledWidth * kBpp, // RgbStride | |
| 119 media::ROTATE_0); | |
| 120 | |
| 121 unsigned int rgb_hash = hash(rgb_scaled_bytes, size_of_rgb_scaled); | |
| 122 | |
| 123 // To get this hash value, run once and examine the following EXPECT_EQ. | |
| 124 // Then plug new hash value into EXPECT_EQ statements. | |
| 125 | |
| 126 // TODO(fbarchard): Make reference code mimic MMX exactly | |
| 127 #if USE_MMX | |
| 128 EXPECT_EQ(2317989539u, rgb_hash); | |
| 129 #else | |
| 130 EXPECT_EQ(2946450771u, rgb_hash); | |
| 131 #endif | |
| 132 return; | |
| 133 } | |
| 134 | |
| OLD | NEW |