blob: 8280d13077c903eccb6cbebbc42cb5f38c56b9b4 [file] [log] [blame]
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +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
14#include "common_video/interface/i420_video_frame.h"
15#include "gtest/gtest.h"
16#include "system_wrappers/interface/scoped_ptr.h"
17
18namespace webrtc {
19
20bool EqualFrames(const I420VideoFrame& videoFrame1,
21 const I420VideoFrame& videoFrame2);
22bool EqualFramesExceptSize(const I420VideoFrame& frame1,
23 const I420VideoFrame& frame2);
24
25TEST(TestI420VideoFrame, InitialValues) {
26 I420VideoFrame frame;
27 // Invalid arguments - one call for each variable.
28 EXPECT_EQ(-1, frame.CreateEmptyFrame(0, 10, 10, 14, 14));
29 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, -1, 10, 90, 14));
30 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 0, 14, 18));
31 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 10, -2, 13));
32 EXPECT_EQ(-1, frame.CreateEmptyFrame(10, 10, 10, 14, 0));
33 EXPECT_EQ(0, frame.CreateEmptyFrame(10, 10, 10, 14, 90));
34}
35
36TEST(TestI420VideoFrame, WidthHeightValues) {
37 I420VideoFrame frame;
38 const int valid_value = 10;
39 const int invalid_value = -1;
40 EXPECT_EQ(0, frame.CreateEmptyFrame(10, 10, 10, 14, 90));
41 EXPECT_EQ(valid_value, frame.width());
42 EXPECT_EQ(invalid_value, frame.set_width(invalid_value));
43 EXPECT_EQ(valid_value, frame.height());
44 EXPECT_EQ(valid_value, frame.height());
45 EXPECT_EQ(invalid_value, frame.set_height(0));
46 EXPECT_EQ(valid_value, frame.height());
47 frame.set_timestamp(100u);
48 EXPECT_EQ(100u, frame.timestamp());
49 frame.set_render_time_ms(100);
50 EXPECT_EQ(100, frame.render_time_ms());
51}
52
53TEST(TestI420VideoFrame, SizeAllocation) {
54 I420VideoFrame frame;
55 EXPECT_EQ(0, frame. CreateEmptyFrame(10, 10, 12, 14, 220));
56 int width = frame.width();
57 int height = frame.height();
58 int stride_y = frame.stride(kYPlane);
59 int stride_u = frame.stride(kUPlane);
60 int stride_v = frame.stride(kVPlane);
61 // Verify that allocated size was computed correctly.
62 EXPECT_EQ(width * stride_y, frame.size(kYPlane));
63 EXPECT_EQ((height + 1) * (stride_u + 1) / 4, frame.size(kUPlane));
64 EXPECT_EQ((height + 1) * (stride_v + 1) / 4, frame.size(kVPlane));
65}
66
67TEST(TestI420VideoFrame, CopyFrame) {
68 I420VideoFrame frame1, frame2;
69 uint32_t timestamp = 1;
70 int64_t render_time_ms = 1;
71 int stride_y = 15;
72 int stride_u = 10;
73 int stride_v = 10;
74 int width = 15;
75 int height = 15;
76 // Copy frame.
77 EXPECT_EQ(0, frame1.CreateEmptyFrame(width, height,
78 stride_y, stride_u, stride_v));
79 frame1.set_timestamp(timestamp);
80 frame1.set_render_time_ms(render_time_ms);
81 int size_y = frame1.size(kYPlane);
82 int size_u = frame1.size(kUPlane);
83 int size_v = frame1.size(kVPlane);
84 EXPECT_EQ(0, frame2.CreateEmptyFrame(width + 5, height + 5,
85 stride_y + 5, stride_u, stride_v));
86 // Frame of smaller dimensions - allocated sizes should not vary.
87 EXPECT_EQ(0, frame2.CopyFrame(frame1));
88 EXPECT_TRUE(EqualFramesExceptSize(frame1, frame2));
89 EXPECT_EQ(size_y, frame1.size(kYPlane));
90 EXPECT_EQ(size_u, frame1.size(kUPlane));
91 EXPECT_EQ(size_v, frame1.size(kVPlane));
92 // Verify copy of all parameters.
93 // Frame of larger dimensions - update allocated sizes.
94 EXPECT_EQ(0, frame1.CopyFrame(frame2));
95 EXPECT_TRUE(EqualFrames(frame1, frame2));
96}
97
98TEST(TestI420VideoFrame, CopyBuffer) {
99 I420VideoFrame frame1, frame2;
100 int width = 15;
101 int height = 15;
102 int stride_y = 15;
103 int stride_u = 10;
104 int stride_v = 10;
105 const int kSizeY = 225;
106 const int kSizeUv = 37; // (stride_u + 1) * (height + 1) / 4;
107 EXPECT_EQ(0, frame2.CreateEmptyFrame(width + 5, height + 5,
108 stride_y + 5, stride_u, stride_v));
109 EXPECT_EQ(0, frame2.CreateEmptyFrame(width, height,
110 stride_y, stride_u, stride_v));
111 uint8_t buffer_y[kSizeY];
112 uint8_t buffer_u[kSizeUv];
113 uint8_t buffer_v[kSizeUv];
114 memset(buffer_y, 16, kSizeY);
115 memset(buffer_u, 8, kSizeUv);
116 memset(buffer_v, 4, kSizeUv);
117 frame2.CreateFrame(kSizeY, *buffer_y,
118 kSizeUv, *buffer_u,
119 kSizeUv, *buffer_v,
120 width, height, stride_y, stride_u, stride_v);
121 // Copy memory (at least allocated size).
122 EXPECT_EQ(memcmp(buffer_y, frame2.buffer(kYPlane), kSizeY), 0);
123 EXPECT_EQ(memcmp(buffer_u, frame2.buffer(kUPlane), kSizeUv), 0);
124 EXPECT_EQ(memcmp(buffer_v, frame2.buffer(kVPlane), kSizeUv), 0);
125 // Comapre size.
126 EXPECT_LE(kSizeY, frame2.size(kYPlane));
127 EXPECT_LE(kSizeUv, frame2.size(kUPlane));
128 EXPECT_LE(kSizeUv, frame2.size(kVPlane));
129}
130
131TEST(TestI420VideoFrame, FrameSwap) {
132 I420VideoFrame frame1, frame2;
133 uint32_t timestamp1 = 1;
134 int64_t render_time_ms1 = 1;
135 int stride_y1 = 15;
136 int stride_u1 = 10;
137 int stride_v1 = 10;
138 int width1 = 15;
139 int height1 = 15;
140 const int kSizeY1 = 225;
141 const int kSizeU1 = 37;
142 const int kSizeV1 = 37;
143 uint32_t timestamp2 = 2;
144 int64_t render_time_ms2 = 4;
145 int stride_y2 = 30;
146 int stride_u2 = 20;
147 int stride_v2 = 20;
148 int width2 = 30;
149 int height2 = 30;
150 const int kSizeY2 = 900;
151 const int kSizeU2 = 150;
152 const int kSizeV2 = 150;
153 // Initialize frame1 values.
154 EXPECT_EQ(0, frame1.CreateEmptyFrame(width1, height1,
155 stride_y1, stride_u1, stride_v1));
156 frame1.set_timestamp(timestamp1);
157 frame1.set_render_time_ms(render_time_ms1);
158 // Set memory for frame1.
159 uint8_t buffer_y1[kSizeY1];
160 uint8_t buffer_u1[kSizeU1];
161 uint8_t buffer_v1[kSizeV1];
162 memset(buffer_y1, 2, kSizeY1);
163 memset(buffer_u1, 4, kSizeU1);
164 memset(buffer_v1, 8, kSizeV1);
165 frame1.CreateFrame(kSizeY1, *buffer_y1,
166 kSizeU1, *buffer_u1,
167 kSizeV1, *buffer_v1,
168 width1, height1, stride_y1, stride_u1, stride_v1);
169 // Initialize frame2 values.
170 EXPECT_EQ(0, frame2.CreateEmptyFrame(width2, height2,
171 stride_y2, stride_u2, stride_v2));
172 frame2.set_timestamp(timestamp2);
173 frame2.set_render_time_ms(render_time_ms2);
174 // Set memory for frame2.
175 uint8_t buffer_y2[kSizeY2];
176 uint8_t buffer_u2[kSizeU2];
177 uint8_t buffer_v2[kSizeV2];
178 memset(buffer_y2, 0, kSizeY2);
179 memset(buffer_u2, 1, kSizeU2);
180 memset(buffer_v2, 2, kSizeV2);
181 frame2.CreateFrame(kSizeY2, *buffer_y2,
182 kSizeU2, *buffer_u2,
183 kSizeV2, *buffer_v2,
184 width2, height2, stride_y2, stride_u2, stride_v2);
185 // Copy frames for subsequent comparison.
186 I420VideoFrame frame1_copy, frame2_copy;
187 frame1_copy.CopyFrame(frame1);
188 frame2_copy.CopyFrame(frame2);
189 // Swap frames.
190 frame1.SwapFrame(&frame2);
191 // Verify swap.
192 EXPECT_TRUE(EqualFrames(frame1_copy, frame2));
193 EXPECT_TRUE(EqualFrames(frame2_copy, frame1));
194}
195
196bool EqualFrames(const I420VideoFrame& frame1,
197 const I420VideoFrame& frame2) {
198 if (!EqualFramesExceptSize(frame1, frame2))
199 return false;
200 // Compare allocated memory size.
201 bool ret = true;
202 ret |= (frame1.size(kYPlane) == frame2.size(kYPlane));
203 ret |= (frame1.size(kUPlane) == frame2.size(kUPlane));
204 ret |= (frame1.size(kVPlane) == frame2.size(kVPlane));
205 return ret;
206}
207
208bool EqualFramesExceptSize(const I420VideoFrame& frame1,
209 const I420VideoFrame& frame2) {
210 bool ret = true;
211 ret |= (frame1.width() == frame2.width());
212 ret |= (frame1.height() == frame2.height());
213 ret |= (frame1.stride(kYPlane) == frame2.stride(kYPlane));
214 ret |= (frame1.stride(kUPlane) == frame2.stride(kUPlane));
215 ret |= (frame1.stride(kVPlane) == frame2.stride(kVPlane));
216 ret |= (frame1.timestamp() == frame2.timestamp());
217 ret |= (frame1.render_time_ms() == frame2.render_time_ms());
218 // Memory should be the equal for the minimum of the two sizes.
219 int size_y = std::min(frame1.size(kYPlane), frame2.size(kYPlane));
220 int size_u = std::min(frame1.size(kUPlane), frame1.size(kUPlane));
221 int size_v = std::min(frame1.size(kVPlane), frame1.size(kVPlane));
222 ret |= memcmp(frame1.buffer(kYPlane), frame2.buffer(kYPlane), size_y);
223 ret |= memcmp(frame1.buffer(kUPlane), frame2.buffer(kYPlane), size_u);
224 ret |= memcmp(frame1.buffer(kVPlane), frame2.buffer(kYPlane), size_v);
225 return ret;
226}
227
228} // namespace webrtc