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 |