2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webrtc/common_video/interface/i420_video_frame.h"
16 #include "webrtc/system_wrappers/interface/ref_count.h"
17 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
18 #include "webrtc/system_wrappers/interface/scoped_refptr.h"
22 bool EqualFrames(const I420VideoFrame& videoFrame1,
23 const I420VideoFrame& videoFrame2);
24 bool EqualFramesExceptSize(const I420VideoFrame& frame1,
25 const I420VideoFrame& frame2);
26 int ExpectedSize(int plane_stride, int image_height, PlaneType type);
28 TEST(TestI420VideoFrame, InitialValues) {
30 // Invalid arguments - one call for each variable.
31 EXPECT_TRUE(frame.IsZeroSize());
32 EXPECT_EQ(-1, frame.CreateEmptyFrame(0, 10, 10, 14, 14));
33 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, -1, 10, 90, 14));
34 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 0, 14, 18));
35 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 10, -2, 13));
36 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 10, 14, 0));
37 EXPECT_EQ(0, frame.CreateEmptyFrame(10, 10, 10, 14, 90));
38 EXPECT_FALSE(frame.IsZeroSize());
41 TEST(TestI420VideoFrame, WidthHeightValues) {
43 const int valid_value = 10;
44 const int invalid_value = -1;
45 EXPECT_EQ(0, frame.CreateEmptyFrame(10, 10, 10, 14, 90));
46 EXPECT_EQ(valid_value, frame.width());
47 EXPECT_EQ(invalid_value, frame.set_width(invalid_value));
48 EXPECT_EQ(valid_value, frame.height());
49 EXPECT_EQ(valid_value, frame.height());
50 EXPECT_EQ(invalid_value, frame.set_height(0));
51 EXPECT_EQ(valid_value, frame.height());
52 frame.set_timestamp(123u);
53 EXPECT_EQ(123u, frame.timestamp());
54 frame.set_ntp_time_ms(456);
55 EXPECT_EQ(456, frame.ntp_time_ms());
56 frame.set_render_time_ms(789);
57 EXPECT_EQ(789, frame.render_time_ms());
60 TEST(TestI420VideoFrame, SizeAllocation) {
62 EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
63 int height = frame.height();
64 int stride_y = frame.stride(kYPlane);
65 int stride_u = frame.stride(kUPlane);
66 int stride_v = frame.stride(kVPlane);
67 // Verify that allocated size was computed correctly.
68 EXPECT_EQ(ExpectedSize(stride_y, height, kYPlane),
69 frame.allocated_size(kYPlane));
70 EXPECT_EQ(ExpectedSize(stride_u, height, kUPlane),
71 frame.allocated_size(kUPlane));
72 EXPECT_EQ(ExpectedSize(stride_v, height, kVPlane),
73 frame.allocated_size(kVPlane));
76 TEST(TestI420VideoFrame, ResetSize) {
78 EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
79 EXPECT_FALSE(frame.IsZeroSize());
81 EXPECT_TRUE(frame.IsZeroSize());
84 TEST(TestI420VideoFrame, CopyFrame) {
85 I420VideoFrame frame1, frame2;
86 uint32_t timestamp = 1;
87 int64_t ntp_time_ms = 2;
88 int64_t render_time_ms = 3;
95 EXPECT_EQ(0, frame1.CreateEmptyFrame(width, height,
96 stride_y, stride_u, stride_v));
97 frame1.set_timestamp(timestamp);
98 frame1.set_ntp_time_ms(ntp_time_ms);
99 frame1.set_render_time_ms(render_time_ms);
100 const int kSizeY = 225;
101 const int kSizeU = 80;
102 const int kSizeV = 80;
103 uint8_t buffer_y[kSizeY];
104 uint8_t buffer_u[kSizeU];
105 uint8_t buffer_v[kSizeV];
106 memset(buffer_y, 16, kSizeY);
107 memset(buffer_u, 8, kSizeU);
108 memset(buffer_v, 4, kSizeV);
109 frame2.CreateFrame(kSizeY, buffer_y,
112 width + 5, height + 5, stride_y + 5, stride_u, stride_v);
113 // Frame of smaller dimensions - allocated sizes should not vary.
114 EXPECT_EQ(0, frame1.CopyFrame(frame2));
115 EXPECT_TRUE(EqualFramesExceptSize(frame1, frame2));
116 EXPECT_EQ(kSizeY, frame1.allocated_size(kYPlane));
117 EXPECT_EQ(kSizeU, frame1.allocated_size(kUPlane));
118 EXPECT_EQ(kSizeV, frame1.allocated_size(kVPlane));
119 // Verify copy of all parameters.
120 // Frame of larger dimensions - update allocated sizes.
121 EXPECT_EQ(0, frame2.CopyFrame(frame1));
122 EXPECT_TRUE(EqualFrames(frame1, frame2));
125 TEST(TestI420VideoFrame, CopyBuffer) {
126 I420VideoFrame frame1, frame2;
131 const int kSizeY = 225;
132 const int kSizeUv = 80;
133 EXPECT_EQ(0, frame2.CreateEmptyFrame(width, height,
134 stride_y, stride_uv, stride_uv));
135 uint8_t buffer_y[kSizeY];
136 uint8_t buffer_u[kSizeUv];
137 uint8_t buffer_v[kSizeUv];
138 memset(buffer_y, 16, kSizeY);
139 memset(buffer_u, 8, kSizeUv);
140 memset(buffer_v, 4, kSizeUv);
141 frame2.CreateFrame(kSizeY, buffer_y,
144 width, height, stride_y, stride_uv, stride_uv);
145 // Copy memory (at least allocated size).
146 EXPECT_EQ(memcmp(buffer_y, frame2.buffer(kYPlane), kSizeY), 0);
147 EXPECT_EQ(memcmp(buffer_u, frame2.buffer(kUPlane), kSizeUv), 0);
148 EXPECT_EQ(memcmp(buffer_v, frame2.buffer(kVPlane), kSizeUv), 0);
150 EXPECT_LE(kSizeY, frame2.allocated_size(kYPlane));
151 EXPECT_LE(kSizeUv, frame2.allocated_size(kUPlane));
152 EXPECT_LE(kSizeUv, frame2.allocated_size(kVPlane));
155 TEST(TestI420VideoFrame, FrameSwap) {
156 I420VideoFrame frame1, frame2;
157 uint32_t timestamp1 = 1;
158 int64_t ntp_time_ms1 = 2;
159 int64_t render_time_ms1 = 3;
165 const int kSizeY1 = 225;
166 const int kSizeU1 = 80;
167 const int kSizeV1 = 80;
168 uint32_t timestamp2 = 4;
169 int64_t ntp_time_ms2 = 5;
170 int64_t render_time_ms2 = 6;
176 const int kSizeY2 = 900;
177 const int kSizeU2 = 300;
178 const int kSizeV2 = 300;
179 // Initialize frame1 values.
180 EXPECT_EQ(0, frame1.CreateEmptyFrame(width1, height1,
181 stride_y1, stride_u1, stride_v1));
182 frame1.set_timestamp(timestamp1);
183 frame1.set_ntp_time_ms(ntp_time_ms1);
184 frame1.set_render_time_ms(render_time_ms1);
185 // Set memory for frame1.
186 uint8_t buffer_y1[kSizeY1];
187 uint8_t buffer_u1[kSizeU1];
188 uint8_t buffer_v1[kSizeV1];
189 memset(buffer_y1, 2, kSizeY1);
190 memset(buffer_u1, 4, kSizeU1);
191 memset(buffer_v1, 8, kSizeV1);
192 frame1.CreateFrame(kSizeY1, buffer_y1,
195 width1, height1, stride_y1, stride_u1, stride_v1);
196 // Initialize frame2 values.
197 EXPECT_EQ(0, frame2.CreateEmptyFrame(width2, height2,
198 stride_y2, stride_u2, stride_v2));
199 frame2.set_timestamp(timestamp2);
200 frame1.set_ntp_time_ms(ntp_time_ms2);
201 frame2.set_render_time_ms(render_time_ms2);
202 // Set memory for frame2.
203 uint8_t buffer_y2[kSizeY2];
204 uint8_t buffer_u2[kSizeU2];
205 uint8_t buffer_v2[kSizeV2];
206 memset(buffer_y2, 0, kSizeY2);
207 memset(buffer_u2, 1, kSizeU2);
208 memset(buffer_v2, 2, kSizeV2);
209 frame2.CreateFrame(kSizeY2, buffer_y2,
212 width2, height2, stride_y2, stride_u2, stride_v2);
213 // Copy frames for subsequent comparison.
214 I420VideoFrame frame1_copy, frame2_copy;
215 frame1_copy.CopyFrame(frame1);
216 frame2_copy.CopyFrame(frame2);
218 frame1.SwapFrame(&frame2);
220 EXPECT_TRUE(EqualFrames(frame1_copy, frame2));
221 EXPECT_TRUE(EqualFrames(frame2_copy, frame1));
224 TEST(TestI420VideoFrame, RefCountedInstantiation) {
225 // Refcounted instantiation - ref_count should correspond to the number of
227 scoped_refptr<I420VideoFrame> ref_count_frame(
228 new RefCountImpl<I420VideoFrame>());
229 EXPECT_EQ(2, ref_count_frame->AddRef());
230 EXPECT_EQ(3, ref_count_frame->AddRef());
231 EXPECT_EQ(2, ref_count_frame->Release());
232 EXPECT_EQ(1, ref_count_frame->Release());
235 bool EqualFrames(const I420VideoFrame& frame1,
236 const I420VideoFrame& frame2) {
237 if (!EqualFramesExceptSize(frame1, frame2))
239 // Compare allocated memory size.
241 ret |= (frame1.allocated_size(kYPlane) == frame2.allocated_size(kYPlane));
242 ret |= (frame1.allocated_size(kUPlane) == frame2.allocated_size(kUPlane));
243 ret |= (frame1.allocated_size(kVPlane) == frame2.allocated_size(kVPlane));
247 bool EqualFramesExceptSize(const I420VideoFrame& frame1,
248 const I420VideoFrame& frame2) {
250 ret |= (frame1.width() == frame2.width());
251 ret |= (frame1.height() == frame2.height());
252 ret |= (frame1.stride(kYPlane) == frame2.stride(kYPlane));
253 ret |= (frame1.stride(kUPlane) == frame2.stride(kUPlane));
254 ret |= (frame1.stride(kVPlane) == frame2.stride(kVPlane));
255 ret |= (frame1.timestamp() == frame2.timestamp());
256 ret |= (frame1.ntp_time_ms() == frame2.ntp_time_ms());
257 ret |= (frame1.render_time_ms() == frame2.render_time_ms());
260 // Memory should be the equal for the minimum of the two sizes.
261 int size_y = std::min(frame1.allocated_size(kYPlane),
262 frame2.allocated_size(kYPlane));
263 int size_u = std::min(frame1.allocated_size(kUPlane),
264 frame2.allocated_size(kUPlane));
265 int size_v = std::min(frame1.allocated_size(kVPlane),
266 frame2.allocated_size(kVPlane));
268 ret_val += memcmp(frame1.buffer(kYPlane), frame2.buffer(kYPlane), size_y);
269 ret_val += memcmp(frame1.buffer(kUPlane), frame2.buffer(kUPlane), size_u);
270 ret_val += memcmp(frame1.buffer(kVPlane), frame2.buffer(kVPlane), size_v);
276 int ExpectedSize(int plane_stride, int image_height, PlaneType type) {
277 if (type == kYPlane) {
278 return (plane_stride * image_height);
280 int half_height = (image_height + 1) / 2;
281 return (plane_stride * half_height);
285 } // namespace webrtc