OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/video_frame.h" | 5 #include "media/base/video_frame.h" |
6 | 6 |
7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
11 #include "media/base/yuv_convert.h" | 11 #include "media/base/yuv_convert.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace media { | 14 namespace media { |
15 | 15 |
16 using base::MD5DigestToBase16; | 16 using base::MD5DigestToBase16; |
17 | 17 |
18 // Helper function that initializes a YV12 frame with white and black scan | 18 // Helper function that initializes a YV12 frame with white and black scan |
19 // lines based on the |white_to_black| parameter. If 0, then the entire | 19 // lines based on the |white_to_black| parameter. If 0, then the entire |
20 // frame will be black, if 1 then the entire frame will be white. | 20 // frame will be black, if 1 then the entire frame will be white. |
21 void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { | 21 void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { |
22 EXPECT_EQ(VideoFrame::YV12, frame->format()); | 22 EXPECT_EQ(VideoFrame::YV12, frame->format()); |
23 int first_black_row = static_cast<int>(frame->data_size().height() * | 23 int first_black_row = static_cast<int>(frame->coded_size().height() * |
24 white_to_black); | 24 white_to_black); |
25 uint8* y_plane = frame->data(VideoFrame::kYPlane); | 25 uint8* y_plane = frame->data(VideoFrame::kYPlane); |
26 for (int row = 0; row < frame->data_size().height(); ++row) { | 26 for (int row = 0; row < frame->coded_size().height(); ++row) { |
27 int color = (row < first_black_row) ? 0xFF : 0x00; | 27 int color = (row < first_black_row) ? 0xFF : 0x00; |
28 memset(y_plane, color, frame->data_size().width()); | 28 memset(y_plane, color, frame->stride(VideoFrame::kYPlane)); |
29 y_plane += frame->stride(VideoFrame::kYPlane); | 29 y_plane += frame->stride(VideoFrame::kYPlane); |
30 } | 30 } |
31 uint8* u_plane = frame->data(VideoFrame::kUPlane); | 31 uint8* u_plane = frame->data(VideoFrame::kUPlane); |
32 uint8* v_plane = frame->data(VideoFrame::kVPlane); | 32 uint8* v_plane = frame->data(VideoFrame::kVPlane); |
33 for (int row = 0; row < frame->data_size().height(); row += 2) { | 33 for (int row = 0; row < frame->coded_size().height(); row += 2) { |
34 memset(u_plane, 0x80, frame->data_size().width() / 2); | 34 memset(u_plane, 0x80, frame->stride(VideoFrame::kUPlane)); |
35 memset(v_plane, 0x80, frame->data_size().width() / 2); | 35 memset(v_plane, 0x80, frame->stride(VideoFrame::kVPlane)); |
36 u_plane += frame->stride(VideoFrame::kUPlane); | 36 u_plane += frame->stride(VideoFrame::kUPlane); |
37 v_plane += frame->stride(VideoFrame::kVPlane); | 37 v_plane += frame->stride(VideoFrame::kVPlane); |
38 } | 38 } |
39 } | 39 } |
40 | 40 |
41 // Given a |yv12_frame| this method converts the YV12 frame to RGBA and | 41 // Given a |yv12_frame| this method converts the YV12 frame to RGBA and |
42 // makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. | 42 // makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. |
43 void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { | 43 void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { |
44 ASSERT_EQ(VideoFrame::YV12, yv12_frame->format()); | 44 ASSERT_EQ(VideoFrame::YV12, yv12_frame->format()); |
45 ASSERT_EQ(yv12_frame->stride(VideoFrame::kUPlane), | 45 ASSERT_EQ(yv12_frame->stride(VideoFrame::kUPlane), |
46 yv12_frame->stride(VideoFrame::kVPlane)); | 46 yv12_frame->stride(VideoFrame::kVPlane)); |
47 | 47 |
48 scoped_refptr<media::VideoFrame> rgb_frame; | 48 scoped_refptr<media::VideoFrame> rgb_frame; |
49 rgb_frame = media::VideoFrame::CreateFrame(VideoFrame::RGB32, | 49 rgb_frame = media::VideoFrame::CreateFrame(VideoFrame::RGB32, |
50 yv12_frame->data_size(), | 50 yv12_frame->coded_size(), |
| 51 yv12_frame->visible_rect(), |
51 yv12_frame->natural_size(), | 52 yv12_frame->natural_size(), |
52 yv12_frame->GetTimestamp()); | 53 yv12_frame->GetTimestamp()); |
53 | 54 |
54 ASSERT_EQ(yv12_frame->data_size().width(), rgb_frame->data_size().width()); | 55 ASSERT_EQ(yv12_frame->coded_size().width(), |
55 ASSERT_EQ(yv12_frame->data_size().height(), rgb_frame->data_size().height()); | 56 rgb_frame->coded_size().width()); |
| 57 ASSERT_EQ(yv12_frame->coded_size().height(), |
| 58 rgb_frame->coded_size().height()); |
56 | 59 |
57 media::ConvertYUVToRGB32(yv12_frame->data(VideoFrame::kYPlane), | 60 media::ConvertYUVToRGB32(yv12_frame->data(VideoFrame::kYPlane), |
58 yv12_frame->data(VideoFrame::kUPlane), | 61 yv12_frame->data(VideoFrame::kUPlane), |
59 yv12_frame->data(VideoFrame::kVPlane), | 62 yv12_frame->data(VideoFrame::kVPlane), |
60 rgb_frame->data(VideoFrame::kRGBPlane), | 63 rgb_frame->data(VideoFrame::kRGBPlane), |
61 rgb_frame->data_size().width(), | 64 rgb_frame->coded_size().width(), |
62 rgb_frame->data_size().height(), | 65 rgb_frame->coded_size().height(), |
63 yv12_frame->stride(VideoFrame::kYPlane), | 66 yv12_frame->stride(VideoFrame::kYPlane), |
64 yv12_frame->stride(VideoFrame::kUPlane), | 67 yv12_frame->stride(VideoFrame::kUPlane), |
65 rgb_frame->stride(VideoFrame::kRGBPlane), | 68 rgb_frame->stride(VideoFrame::kRGBPlane), |
66 media::YV12); | 69 media::YV12); |
67 | 70 |
68 for (int row = 0; row < rgb_frame->data_size().height(); ++row) { | 71 for (int row = 0; row < rgb_frame->coded_size().height(); ++row) { |
69 uint32* rgb_row_data = reinterpret_cast<uint32*>( | 72 uint32* rgb_row_data = reinterpret_cast<uint32*>( |
70 rgb_frame->data(VideoFrame::kRGBPlane) + | 73 rgb_frame->data(VideoFrame::kRGBPlane) + |
71 (rgb_frame->stride(VideoFrame::kRGBPlane) * row)); | 74 (rgb_frame->stride(VideoFrame::kRGBPlane) * row)); |
72 for (int col = 0; col < rgb_frame->data_size().width(); ++col) { | 75 for (int col = 0; col < rgb_frame->coded_size().width(); ++col) { |
73 SCOPED_TRACE( | 76 SCOPED_TRACE( |
74 base::StringPrintf("Checking (%d, %d)", row, col)); | 77 base::StringPrintf("Checking (%d, %d)", row, col)); |
75 EXPECT_EQ(expect_rgb_color, rgb_row_data[col]); | 78 EXPECT_EQ(expect_rgb_color, rgb_row_data[col]); |
76 } | 79 } |
77 } | 80 } |
78 } | 81 } |
79 | 82 |
80 // Fill each plane to its reported extents and verify accessors report non | 83 // Fill each plane to its reported extents and verify accessors report non |
81 // zero values. Additionally, for the first plane verify the rows and | 84 // zero values. Additionally, for the first plane verify the rows and |
82 // row_bytes values are correct. | 85 // row_bytes values are correct. |
83 void ExpectFrameExtents(VideoFrame::Format format, int planes, | 86 void ExpectFrameExtents(VideoFrame::Format format, int planes, |
84 int bytes_per_pixel, const char* expected_hash) { | 87 int bytes_per_pixel, const char* expected_hash) { |
85 const unsigned char kFillByte = 0x80; | 88 const unsigned char kFillByte = 0x80; |
86 const int kWidth = 61; | 89 const int kWidth = 61; |
87 const int kHeight = 31; | 90 const int kHeight = 31; |
88 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(1337); | 91 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(1337); |
89 | 92 |
90 gfx::Size size(kWidth, kHeight); | 93 gfx::Size size(kWidth, kHeight); |
91 scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( | 94 scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( |
92 format, size, size, kTimestamp); | 95 format, size, gfx::Rect(size), size, kTimestamp); |
93 ASSERT_TRUE(frame); | 96 ASSERT_TRUE(frame); |
94 | 97 |
95 for(int plane = 0; plane < planes; plane++) { | 98 for(int plane = 0; plane < planes; plane++) { |
96 SCOPED_TRACE(base::StringPrintf("Checking plane %d", plane)); | 99 SCOPED_TRACE(base::StringPrintf("Checking plane %d", plane)); |
97 EXPECT_TRUE(frame->data(plane)); | 100 EXPECT_TRUE(frame->data(plane)); |
98 EXPECT_TRUE(frame->stride(plane)); | 101 EXPECT_TRUE(frame->stride(plane)); |
99 EXPECT_TRUE(frame->rows(plane)); | 102 EXPECT_TRUE(frame->rows(plane)); |
100 EXPECT_TRUE(frame->row_bytes(plane)); | 103 EXPECT_TRUE(frame->row_bytes(plane)); |
101 | 104 |
102 if (plane == 0) { | 105 if (plane == 0) { |
(...skipping 14 matching lines...) Expand all Loading... |
117 } | 120 } |
118 | 121 |
119 TEST(VideoFrame, CreateFrame) { | 122 TEST(VideoFrame, CreateFrame) { |
120 const int kWidth = 64; | 123 const int kWidth = 64; |
121 const int kHeight = 48; | 124 const int kHeight = 48; |
122 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(1337); | 125 const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(1337); |
123 | 126 |
124 // Create a YV12 Video Frame. | 127 // Create a YV12 Video Frame. |
125 gfx::Size size(kWidth, kHeight); | 128 gfx::Size size(kWidth, kHeight); |
126 scoped_refptr<media::VideoFrame> frame = | 129 scoped_refptr<media::VideoFrame> frame = |
127 VideoFrame::CreateFrame(media::VideoFrame::YV12, size, size, kTimestamp); | 130 VideoFrame::CreateFrame(media::VideoFrame::YV12, size, gfx::Rect(size), |
| 131 size, kTimestamp); |
128 ASSERT_TRUE(frame); | 132 ASSERT_TRUE(frame); |
129 | 133 |
130 // Test VideoFrame implementation. | 134 // Test VideoFrame implementation. |
131 EXPECT_EQ(media::VideoFrame::YV12, frame->format()); | 135 EXPECT_EQ(media::VideoFrame::YV12, frame->format()); |
132 { | 136 { |
133 SCOPED_TRACE(""); | 137 SCOPED_TRACE(""); |
134 InitializeYV12Frame(frame, 0.0f); | 138 InitializeYV12Frame(frame, 0.0f); |
135 ExpectFrameColor(frame, 0xFF000000); | 139 ExpectFrameColor(frame, 0xFF000000); |
136 } | 140 } |
137 base::MD5Digest digest; | 141 base::MD5Digest digest; |
(...skipping 26 matching lines...) Expand all Loading... |
164 scoped_refptr<media::VideoFrame> frame = | 168 scoped_refptr<media::VideoFrame> frame = |
165 VideoFrame::CreateBlackFrame(gfx::Size(kWidth, kHeight)); | 169 VideoFrame::CreateBlackFrame(gfx::Size(kWidth, kHeight)); |
166 ASSERT_TRUE(frame); | 170 ASSERT_TRUE(frame); |
167 | 171 |
168 // Test basic properties. | 172 // Test basic properties. |
169 EXPECT_EQ(0, frame->GetTimestamp().InMicroseconds()); | 173 EXPECT_EQ(0, frame->GetTimestamp().InMicroseconds()); |
170 EXPECT_FALSE(frame->IsEndOfStream()); | 174 EXPECT_FALSE(frame->IsEndOfStream()); |
171 | 175 |
172 // Test |frame| properties. | 176 // Test |frame| properties. |
173 EXPECT_EQ(VideoFrame::YV12, frame->format()); | 177 EXPECT_EQ(VideoFrame::YV12, frame->format()); |
174 EXPECT_EQ(kWidth, frame->data_size().width()); | 178 EXPECT_EQ(kWidth, frame->coded_size().width()); |
175 EXPECT_EQ(kHeight, frame->data_size().height()); | 179 EXPECT_EQ(kHeight, frame->coded_size().height()); |
176 | 180 |
177 // Test frames themselves. | 181 // Test frames themselves. |
178 uint8* y_plane = frame->data(VideoFrame::kYPlane); | 182 uint8* y_plane = frame->data(VideoFrame::kYPlane); |
179 for (int y = 0; y < frame->data_size().height(); ++y) { | 183 for (int y = 0; y < frame->coded_size().height(); ++y) { |
180 EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, arraysize(kExpectedYRow))); | 184 EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, arraysize(kExpectedYRow))); |
181 y_plane += frame->stride(VideoFrame::kYPlane); | 185 y_plane += frame->stride(VideoFrame::kYPlane); |
182 } | 186 } |
183 | 187 |
184 uint8* u_plane = frame->data(VideoFrame::kUPlane); | 188 uint8* u_plane = frame->data(VideoFrame::kUPlane); |
185 uint8* v_plane = frame->data(VideoFrame::kVPlane); | 189 uint8* v_plane = frame->data(VideoFrame::kVPlane); |
186 for (int y = 0; y < frame->data_size().height() / 2; ++y) { | 190 for (int y = 0; y < frame->coded_size().height() / 2; ++y) { |
187 EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, arraysize(kExpectedUVRow))); | 191 EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, arraysize(kExpectedUVRow))); |
188 EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, arraysize(kExpectedUVRow))); | 192 EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, arraysize(kExpectedUVRow))); |
189 u_plane += frame->stride(VideoFrame::kUPlane); | 193 u_plane += frame->stride(VideoFrame::kUPlane); |
190 v_plane += frame->stride(VideoFrame::kVPlane); | 194 v_plane += frame->stride(VideoFrame::kVPlane); |
191 } | 195 } |
192 } | 196 } |
193 | 197 |
194 // Ensure each frame is properly sized and allocated. Will trigger OOB reads | 198 // Ensure each frame is properly sized and allocated. Will trigger OOB reads |
195 // and writes as well as incorrect frame hashes otherwise. | 199 // and writes as well as incorrect frame hashes otherwise. |
196 TEST(VideoFrame, CheckFrameExtents) { | 200 TEST(VideoFrame, CheckFrameExtents) { |
197 // Each call consists of a VideoFrame::Format, # of planes, bytes per pixel, | 201 // Each call consists of a VideoFrame::Format, # of planes, bytes per pixel, |
198 // and the expected hash of all planes if filled with kFillByte (defined in | 202 // and the expected hash of all planes if filled with kFillByte (defined in |
199 // ExpectFrameExtents). | 203 // ExpectFrameExtents). |
200 ExpectFrameExtents( | 204 ExpectFrameExtents( |
201 VideoFrame::RGB32, 1, 4, "de6d3d567e282f6a38d478f04fc81fb0"); | 205 VideoFrame::RGB32, 1, 4, "de6d3d567e282f6a38d478f04fc81fb0"); |
202 ExpectFrameExtents( | 206 ExpectFrameExtents( |
203 VideoFrame::YV12, 3, 1, "71113bdfd4c0de6cf62f48fb74f7a0b1"); | 207 VideoFrame::YV12, 3, 1, "71113bdfd4c0de6cf62f48fb74f7a0b1"); |
204 ExpectFrameExtents( | 208 ExpectFrameExtents( |
205 VideoFrame::YV16, 3, 1, "9bb99ac3ff350644ebff4d28dc01b461"); | 209 VideoFrame::YV16, 3, 1, "9bb99ac3ff350644ebff4d28dc01b461"); |
206 } | 210 } |
207 | 211 |
208 } // namespace media | 212 } // namespace media |
OLD | NEW |