blob: 5c738bd791ef9febcf4d4f690a391585d72fefc8 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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.
9 */
10
11#include <math.h>
12#include <string.h>
13
pbos@webrtc.org026d1ce2013-06-04 09:02:37 +000014#include "testing/gtest/include/gtest/gtest.h"
mikhal@webrtc.org42fde562012-12-19 00:07:57 +000015#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"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000019
20namespace webrtc {
21
22bool EqualFrames(const I420VideoFrame& videoFrame1,
23 const I420VideoFrame& videoFrame2);
24bool EqualFramesExceptSize(const I420VideoFrame& frame1,
25 const I420VideoFrame& frame2);
26int ExpectedSize(int plane_stride, int image_height, PlaneType type);
27
28TEST(TestI420VideoFrame, InitialValues) {
29 I420VideoFrame frame;
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());
39}
40
41TEST(TestI420VideoFrame, WidthHeightValues) {
42 I420VideoFrame frame;
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(100u);
53 EXPECT_EQ(100u, frame.timestamp());
54 frame.set_render_time_ms(100);
55 EXPECT_EQ(100, frame.render_time_ms());
56}
57
58TEST(TestI420VideoFrame, SizeAllocation) {
59 I420VideoFrame frame;
60 EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
61 int height = frame.height();
62 int stride_y = frame.stride(kYPlane);
63 int stride_u = frame.stride(kUPlane);
64 int stride_v = frame.stride(kVPlane);
65 // Verify that allocated size was computed correctly.
66 EXPECT_EQ(ExpectedSize(stride_y, height, kYPlane),
67 frame.allocated_size(kYPlane));
68 EXPECT_EQ(ExpectedSize(stride_u, height, kUPlane),
69 frame.allocated_size(kUPlane));
70 EXPECT_EQ(ExpectedSize(stride_v, height, kVPlane),
71 frame.allocated_size(kVPlane));
72}
73
74TEST(TestI420VideoFrame, ResetSize) {
75 I420VideoFrame frame;
76 EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
77 EXPECT_FALSE(frame.IsZeroSize());
78 frame.ResetSize();
79 EXPECT_TRUE(frame.IsZeroSize());
80}
81
82TEST(TestI420VideoFrame, CopyFrame) {
83 I420VideoFrame frame1, frame2;
84 uint32_t timestamp = 1;
85 int64_t render_time_ms = 1;
86 int stride_y = 15;
87 int stride_u = 10;
88 int stride_v = 10;
89 int width = 15;
90 int height = 15;
91 // Copy frame.
92 EXPECT_EQ(0, frame1.CreateEmptyFrame(width, height,
93 stride_y, stride_u, stride_v));
94 frame1.set_timestamp(timestamp);
95 frame1.set_render_time_ms(render_time_ms);
96 const int kSizeY = 225;
97 const int kSizeU = 80;
98 const int kSizeV = 80;
99 uint8_t buffer_y[kSizeY];
100 uint8_t buffer_u[kSizeU];
101 uint8_t buffer_v[kSizeV];
102 memset(buffer_y, 16, kSizeY);
103 memset(buffer_u, 8, kSizeU);
104 memset(buffer_v, 4, kSizeV);
105 frame2.CreateFrame(kSizeY, buffer_y,
106 kSizeU, buffer_u,
107 kSizeV, buffer_v,
108 width + 5, height + 5, stride_y + 5, stride_u, stride_v);
109 // Frame of smaller dimensions - allocated sizes should not vary.
110 EXPECT_EQ(0, frame1.CopyFrame(frame2));
111 EXPECT_TRUE(EqualFramesExceptSize(frame1, frame2));
112 EXPECT_EQ(kSizeY, frame1.allocated_size(kYPlane));
113 EXPECT_EQ(kSizeU, frame1.allocated_size(kUPlane));
114 EXPECT_EQ(kSizeV, frame1.allocated_size(kVPlane));
115 // Verify copy of all parameters.
116 // Frame of larger dimensions - update allocated sizes.
117 EXPECT_EQ(0, frame2.CopyFrame(frame1));
118 EXPECT_TRUE(EqualFrames(frame1, frame2));
119}
120
121TEST(TestI420VideoFrame, CopyBuffer) {
122 I420VideoFrame frame1, frame2;
123 int width = 15;
124 int height = 15;
125 int stride_y = 15;
126 int stride_uv = 10;
127 const int kSizeY = 225;
128 const int kSizeUv = 80;
129 EXPECT_EQ(0, frame2.CreateEmptyFrame(width, height,
130 stride_y, stride_uv, stride_uv));
131 uint8_t buffer_y[kSizeY];
132 uint8_t buffer_u[kSizeUv];
133 uint8_t buffer_v[kSizeUv];
134 memset(buffer_y, 16, kSizeY);
135 memset(buffer_u, 8, kSizeUv);
136 memset(buffer_v, 4, kSizeUv);
137 frame2.CreateFrame(kSizeY, buffer_y,
138 kSizeUv, buffer_u,
139 kSizeUv, buffer_v,
140 width, height, stride_y, stride_uv, stride_uv);
141 // Copy memory (at least allocated size).
142 EXPECT_EQ(memcmp(buffer_y, frame2.buffer(kYPlane), kSizeY), 0);
143 EXPECT_EQ(memcmp(buffer_u, frame2.buffer(kUPlane), kSizeUv), 0);
144 EXPECT_EQ(memcmp(buffer_v, frame2.buffer(kVPlane), kSizeUv), 0);
145 // Comapre size.
146 EXPECT_LE(kSizeY, frame2.allocated_size(kYPlane));
147 EXPECT_LE(kSizeUv, frame2.allocated_size(kUPlane));
148 EXPECT_LE(kSizeUv, frame2.allocated_size(kVPlane));
149}
150
151TEST(TestI420VideoFrame, FrameSwap) {
152 I420VideoFrame frame1, frame2;
153 uint32_t timestamp1 = 1;
154 int64_t render_time_ms1 = 1;
155 int stride_y1 = 15;
156 int stride_u1 = 10;
157 int stride_v1 = 10;
158 int width1 = 15;
159 int height1 = 15;
160 const int kSizeY1 = 225;
161 const int kSizeU1 = 80;
162 const int kSizeV1 = 80;
163 uint32_t timestamp2 = 2;
164 int64_t render_time_ms2 = 4;
165 int stride_y2 = 30;
166 int stride_u2 = 20;
167 int stride_v2 = 20;
168 int width2 = 30;
169 int height2 = 30;
170 const int kSizeY2 = 900;
171 const int kSizeU2 = 300;
172 const int kSizeV2 = 300;
173 // Initialize frame1 values.
174 EXPECT_EQ(0, frame1.CreateEmptyFrame(width1, height1,
175 stride_y1, stride_u1, stride_v1));
176 frame1.set_timestamp(timestamp1);
177 frame1.set_render_time_ms(render_time_ms1);
178 // Set memory for frame1.
179 uint8_t buffer_y1[kSizeY1];
180 uint8_t buffer_u1[kSizeU1];
181 uint8_t buffer_v1[kSizeV1];
182 memset(buffer_y1, 2, kSizeY1);
183 memset(buffer_u1, 4, kSizeU1);
184 memset(buffer_v1, 8, kSizeV1);
185 frame1.CreateFrame(kSizeY1, buffer_y1,
186 kSizeU1, buffer_u1,
187 kSizeV1, buffer_v1,
188 width1, height1, stride_y1, stride_u1, stride_v1);
189 // Initialize frame2 values.
190 EXPECT_EQ(0, frame2.CreateEmptyFrame(width2, height2,
191 stride_y2, stride_u2, stride_v2));
192 frame2.set_timestamp(timestamp2);
193 frame2.set_render_time_ms(render_time_ms2);
194 // Set memory for frame2.
195 uint8_t buffer_y2[kSizeY2];
196 uint8_t buffer_u2[kSizeU2];
197 uint8_t buffer_v2[kSizeV2];
198 memset(buffer_y2, 0, kSizeY2);
199 memset(buffer_u2, 1, kSizeU2);
200 memset(buffer_v2, 2, kSizeV2);
201 frame2.CreateFrame(kSizeY2, buffer_y2,
202 kSizeU2, buffer_u2,
203 kSizeV2, buffer_v2,
204 width2, height2, stride_y2, stride_u2, stride_v2);
205 // Copy frames for subsequent comparison.
206 I420VideoFrame frame1_copy, frame2_copy;
207 frame1_copy.CopyFrame(frame1);
208 frame2_copy.CopyFrame(frame2);
209 // Swap frames.
210 frame1.SwapFrame(&frame2);
211 // Verify swap.
212 EXPECT_TRUE(EqualFrames(frame1_copy, frame2));
213 EXPECT_TRUE(EqualFrames(frame2_copy, frame1));
214}
215
mikhal@webrtc.org42fde562012-12-19 00:07:57 +0000216TEST(TestI420VideoFrame, RefCountedInstantiation) {
217 // Refcounted instantiation - ref_count should correspond to the number of
218 // instances.
219 scoped_refptr<I420VideoFrame> ref_count_frame(
220 new RefCountImpl<I420VideoFrame>());
221 EXPECT_EQ(2, ref_count_frame->AddRef());
222 EXPECT_EQ(3, ref_count_frame->AddRef());
223 EXPECT_EQ(2, ref_count_frame->Release());
224 EXPECT_EQ(1, ref_count_frame->Release());
225}
226
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000227bool EqualFrames(const I420VideoFrame& frame1,
228 const I420VideoFrame& frame2) {
229 if (!EqualFramesExceptSize(frame1, frame2))
230 return false;
231 // Compare allocated memory size.
232 bool ret = true;
233 ret |= (frame1.allocated_size(kYPlane) == frame2.allocated_size(kYPlane));
234 ret |= (frame1.allocated_size(kUPlane) == frame2.allocated_size(kUPlane));
235 ret |= (frame1.allocated_size(kVPlane) == frame2.allocated_size(kVPlane));
236 return ret;
237}
238
239bool EqualFramesExceptSize(const I420VideoFrame& frame1,
240 const I420VideoFrame& frame2) {
241 bool ret = true;
242 ret |= (frame1.width() == frame2.width());
243 ret |= (frame1.height() == frame2.height());
244 ret |= (frame1.stride(kYPlane) == frame2.stride(kYPlane));
245 ret |= (frame1.stride(kUPlane) == frame2.stride(kUPlane));
246 ret |= (frame1.stride(kVPlane) == frame2.stride(kVPlane));
247 ret |= (frame1.timestamp() == frame2.timestamp());
248 ret |= (frame1.render_time_ms() == frame2.render_time_ms());
249 if (!ret)
250 return false;
251 // Memory should be the equal for the minimum of the two sizes.
252 int size_y = std::min(frame1.allocated_size(kYPlane),
253 frame2.allocated_size(kYPlane));
254 int size_u = std::min(frame1.allocated_size(kUPlane),
255 frame2.allocated_size(kUPlane));
256 int size_v = std::min(frame1.allocated_size(kVPlane),
257 frame2.allocated_size(kVPlane));
258 int ret_val = 0;
259 ret_val += memcmp(frame1.buffer(kYPlane), frame2.buffer(kYPlane), size_y);
260 ret_val += memcmp(frame1.buffer(kUPlane), frame2.buffer(kUPlane), size_u);
261 ret_val += memcmp(frame1.buffer(kVPlane), frame2.buffer(kVPlane), size_v);
262 if (ret_val == 0)
263 return true;
264 return false;
265}
266
267int ExpectedSize(int plane_stride, int image_height, PlaneType type) {
mikhal@webrtc.org42fde562012-12-19 00:07:57 +0000268 if (type == kYPlane) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000269 return (plane_stride * image_height);
mikhal@webrtc.org42fde562012-12-19 00:07:57 +0000270 } else {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000271 int half_height = (image_height + 1) / 2;
272 return (plane_stride * half_height);
273 }
274}
275
276} // namespace webrtc