blob: 8368436446a261b0fd2d3cb65778e93fa974e368 [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
pbos@webrtc.orgc69ae692013-06-04 09:02:37 +000014#include "testing/gtest/include/gtest/gtest.h"
Per9b3f56e2015-04-09 13:44:16 +020015#include "webrtc/base/bind.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020016#include "webrtc/test/fake_texture_frame.h"
Niels Möller739fcb92016-02-29 13:11:45 +010017#include "webrtc/test/frame_utils.h"
jbauch0f2e9392015-12-10 03:11:42 -080018#include "webrtc/video_frame.h"
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000019
20namespace webrtc {
21
mikhal@webrtc.org6a9d7f82012-09-19 22:42:51 +000022int ExpectedSize(int plane_stride, int image_height, PlaneType type);
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000023
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070024TEST(TestVideoFrame, InitialValues) {
25 VideoFrame frame;
mikhal@webrtc.orgdfc6b572012-10-15 16:12:09 +000026 EXPECT_TRUE(frame.IsZeroSize());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +000027 EXPECT_EQ(kVideoRotation_0, frame.rotation());
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000028}
29
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070030TEST(TestVideoFrame, CopiesInitialFrameWithoutCrashing) {
31 VideoFrame frame;
32 VideoFrame frame2;
pbos@webrtc.org6231fb62015-03-20 07:33:02 +000033 frame2.CopyFrame(frame);
34}
35
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070036TEST(TestVideoFrame, WidthHeightValues) {
37 VideoFrame frame;
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000038 const int valid_value = 10;
Niels Möller739fcb92016-02-29 13:11:45 +010039 frame.CreateEmptyFrame(10, 10, 10, 14, 90);
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000040 EXPECT_EQ(valid_value, frame.width());
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000041 EXPECT_EQ(valid_value, frame.height());
wu@webrtc.org6c75c982014-04-15 17:46:33 +000042 frame.set_timestamp(123u);
43 EXPECT_EQ(123u, frame.timestamp());
44 frame.set_ntp_time_ms(456);
45 EXPECT_EQ(456, frame.ntp_time_ms());
46 frame.set_render_time_ms(789);
47 EXPECT_EQ(789, frame.render_time_ms());
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000048}
49
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070050TEST(TestVideoFrame, SizeAllocation) {
51 VideoFrame frame;
Niels Möller739fcb92016-02-29 13:11:45 +010052 frame. CreateEmptyFrame(10, 10, 12, 14, 220);
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000053 int height = frame.height();
54 int stride_y = frame.stride(kYPlane);
55 int stride_u = frame.stride(kUPlane);
56 int stride_v = frame.stride(kVPlane);
57 // Verify that allocated size was computed correctly.
mikhal@webrtc.orgdfc6b572012-10-15 16:12:09 +000058 EXPECT_EQ(ExpectedSize(stride_y, height, kYPlane),
59 frame.allocated_size(kYPlane));
60 EXPECT_EQ(ExpectedSize(stride_u, height, kUPlane),
61 frame.allocated_size(kUPlane));
62 EXPECT_EQ(ExpectedSize(stride_v, height, kVPlane),
63 frame.allocated_size(kVPlane));
64}
65
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070066TEST(TestVideoFrame, CopyFrame) {
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000067 uint32_t timestamp = 1;
wu@webrtc.org6c75c982014-04-15 17:46:33 +000068 int64_t ntp_time_ms = 2;
69 int64_t render_time_ms = 3;
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +000070 int stride_y = 15;
71 int stride_u = 10;
72 int stride_v = 10;
73 int width = 15;
74 int height = 15;
75 // Copy frame.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070076 VideoFrame small_frame;
Niels Möller739fcb92016-02-29 13:11:45 +010077 small_frame.CreateEmptyFrame(width, height,
78 stride_y, stride_u, stride_v);
magjed@webrtc.org88828e72015-02-18 15:53:39 +000079 small_frame.set_timestamp(timestamp);
80 small_frame.set_ntp_time_ms(ntp_time_ms);
81 small_frame.set_render_time_ms(render_time_ms);
82 const int kSizeY = 400;
83 const int kSizeU = 100;
84 const int kSizeV = 100;
guoweis@webrtc.org1226e922015-02-11 18:37:54 +000085 const VideoRotation kRotation = kVideoRotation_270;
mikhal@webrtc.org6a9d7f82012-09-19 22:42:51 +000086 uint8_t buffer_y[kSizeY];
87 uint8_t buffer_u[kSizeU];
88 uint8_t buffer_v[kSizeV];
89 memset(buffer_y, 16, kSizeY);
90 memset(buffer_u, 8, kSizeU);
91 memset(buffer_v, 4, kSizeV);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070092 VideoFrame big_frame;
Niels Möller739fcb92016-02-29 13:11:45 +010093 big_frame.CreateFrame(buffer_y, buffer_u, buffer_v,
94 width + 5, height + 5, stride_y + 5,
95 stride_u, stride_v, kRotation);
magjed@webrtc.org88828e72015-02-18 15:53:39 +000096 // Frame of smaller dimensions.
Niels Möller739fcb92016-02-29 13:11:45 +010097 small_frame.CopyFrame(big_frame);
98 EXPECT_TRUE(test::FramesEqual(small_frame, big_frame));
magjed@webrtc.org88828e72015-02-18 15:53:39 +000099 EXPECT_EQ(kRotation, small_frame.rotation());
100
101 // Frame of larger dimensions.
Niels Möller739fcb92016-02-29 13:11:45 +0100102 small_frame.CreateEmptyFrame(width, height,
103 stride_y, stride_u, stride_v);
magjed@webrtc.orgf82109c2015-03-04 11:30:29 +0000104 memset(small_frame.buffer(kYPlane), 1, small_frame.allocated_size(kYPlane));
105 memset(small_frame.buffer(kUPlane), 2, small_frame.allocated_size(kUPlane));
106 memset(small_frame.buffer(kVPlane), 3, small_frame.allocated_size(kVPlane));
Niels Möller739fcb92016-02-29 13:11:45 +0100107 big_frame.CopyFrame(small_frame);
108 EXPECT_TRUE(test::FramesEqual(small_frame, big_frame));
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +0000109}
110
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700111TEST(TestVideoFrame, ShallowCopy) {
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000112 uint32_t timestamp = 1;
113 int64_t ntp_time_ms = 2;
114 int64_t render_time_ms = 3;
115 int stride_y = 15;
116 int stride_u = 10;
117 int stride_v = 10;
118 int width = 15;
119 int height = 15;
120
121 const int kSizeY = 400;
122 const int kSizeU = 100;
123 const int kSizeV = 100;
124 const VideoRotation kRotation = kVideoRotation_270;
125 uint8_t buffer_y[kSizeY];
126 uint8_t buffer_u[kSizeU];
127 uint8_t buffer_v[kSizeV];
128 memset(buffer_y, 16, kSizeY);
129 memset(buffer_u, 8, kSizeU);
130 memset(buffer_v, 4, kSizeV);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700131 VideoFrame frame1;
Niels Möller739fcb92016-02-29 13:11:45 +0100132 frame1.CreateFrame(buffer_y, buffer_u, buffer_v, width, height,
133 stride_y, stride_u, stride_v, kRotation);
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000134 frame1.set_timestamp(timestamp);
135 frame1.set_ntp_time_ms(ntp_time_ms);
136 frame1.set_render_time_ms(render_time_ms);
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700137 VideoFrame frame2;
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000138 frame2.ShallowCopy(frame1);
139
140 // To be able to access the buffers, we need const pointers to the frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700141 const VideoFrame* const_frame1_ptr = &frame1;
142 const VideoFrame* const_frame2_ptr = &frame2;
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000143
144 EXPECT_TRUE(const_frame1_ptr->buffer(kYPlane) ==
145 const_frame2_ptr->buffer(kYPlane));
146 EXPECT_TRUE(const_frame1_ptr->buffer(kUPlane) ==
147 const_frame2_ptr->buffer(kUPlane));
148 EXPECT_TRUE(const_frame1_ptr->buffer(kVPlane) ==
149 const_frame2_ptr->buffer(kVPlane));
150
151 EXPECT_EQ(frame2.timestamp(), frame1.timestamp());
152 EXPECT_EQ(frame2.ntp_time_ms(), frame1.ntp_time_ms());
153 EXPECT_EQ(frame2.render_time_ms(), frame1.render_time_ms());
154 EXPECT_EQ(frame2.rotation(), frame1.rotation());
155
156 frame2.set_timestamp(timestamp + 1);
157 frame2.set_ntp_time_ms(ntp_time_ms + 1);
158 frame2.set_render_time_ms(render_time_ms + 1);
159 frame2.set_rotation(kVideoRotation_90);
160
161 EXPECT_NE(frame2.timestamp(), frame1.timestamp());
162 EXPECT_NE(frame2.ntp_time_ms(), frame1.ntp_time_ms());
163 EXPECT_NE(frame2.render_time_ms(), frame1.render_time_ms());
164 EXPECT_NE(frame2.rotation(), frame1.rotation());
165}
166
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700167TEST(TestVideoFrame, Reset) {
168 VideoFrame frame;
Niels Möller739fcb92016-02-29 13:11:45 +0100169 frame.CreateEmptyFrame(5, 5, 5, 5, 5);
magjed@webrtc.org0d9bb8e2015-03-11 10:06:58 +0000170 frame.set_ntp_time_ms(1);
171 frame.set_timestamp(2);
172 frame.set_render_time_ms(3);
173 ASSERT_TRUE(frame.video_frame_buffer() != NULL);
174
175 frame.Reset();
176 EXPECT_EQ(0u, frame.ntp_time_ms());
177 EXPECT_EQ(0u, frame.render_time_ms());
178 EXPECT_EQ(0u, frame.timestamp());
179 EXPECT_TRUE(frame.video_frame_buffer() == NULL);
180}
181
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700182TEST(TestVideoFrame, CopyBuffer) {
183 VideoFrame frame1, frame2;
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +0000184 int width = 15;
185 int height = 15;
186 int stride_y = 15;
mikhal@webrtc.org6a9d7f82012-09-19 22:42:51 +0000187 int stride_uv = 10;
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +0000188 const int kSizeY = 225;
mikhal@webrtc.org6a9d7f82012-09-19 22:42:51 +0000189 const int kSizeUv = 80;
Niels Möller739fcb92016-02-29 13:11:45 +0100190 frame2.CreateEmptyFrame(width, height,
191 stride_y, stride_uv, stride_uv);
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +0000192 uint8_t buffer_y[kSizeY];
193 uint8_t buffer_u[kSizeUv];
194 uint8_t buffer_v[kSizeUv];
195 memset(buffer_y, 16, kSizeY);
196 memset(buffer_u, 8, kSizeUv);
197 memset(buffer_v, 4, kSizeUv);
hbos@webrtc.org93d9d652015-03-16 13:26:00 +0000198 frame2.CreateFrame(buffer_y, buffer_u, buffer_v,
Niels Möller739fcb92016-02-29 13:11:45 +0100199 width, height, stride_y, stride_uv, stride_uv,
200 kVideoRotation_0);
magjed@webrtc.org88828e72015-02-18 15:53:39 +0000201 // Expect exactly the same pixel data.
Niels Möller739fcb92016-02-29 13:11:45 +0100202 EXPECT_TRUE(
203 test::EqualPlane(buffer_y, frame2.buffer(kYPlane), stride_y, 15, 15));
204 EXPECT_TRUE(
205 test::EqualPlane(buffer_u, frame2.buffer(kUPlane), stride_uv, 8, 8));
206 EXPECT_TRUE(
207 test::EqualPlane(buffer_v, frame2.buffer(kVPlane), stride_uv, 8, 8));
magjed@webrtc.org88828e72015-02-18 15:53:39 +0000208
209 // Compare size.
mikhal@webrtc.orgdfc6b572012-10-15 16:12:09 +0000210 EXPECT_LE(kSizeY, frame2.allocated_size(kYPlane));
211 EXPECT_LE(kSizeUv, frame2.allocated_size(kUPlane));
212 EXPECT_LE(kSizeUv, frame2.allocated_size(kVPlane));
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +0000213}
214
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700215TEST(TestVideoFrame, ReuseAllocation) {
216 VideoFrame frame;
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000217 frame.CreateEmptyFrame(640, 320, 640, 320, 320);
218 const uint8_t* y = frame.buffer(kYPlane);
219 const uint8_t* u = frame.buffer(kUPlane);
220 const uint8_t* v = frame.buffer(kVPlane);
221 frame.CreateEmptyFrame(640, 320, 640, 320, 320);
222 EXPECT_EQ(y, frame.buffer(kYPlane));
223 EXPECT_EQ(u, frame.buffer(kUPlane));
224 EXPECT_EQ(v, frame.buffer(kVPlane));
225}
226
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700227TEST(TestVideoFrame, FailToReuseAllocation) {
228 VideoFrame frame1;
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000229 frame1.CreateEmptyFrame(640, 320, 640, 320, 320);
230 const uint8_t* y = frame1.buffer(kYPlane);
231 const uint8_t* u = frame1.buffer(kUPlane);
232 const uint8_t* v = frame1.buffer(kVPlane);
233 // Make a shallow copy of |frame1|.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700234 VideoFrame frame2(frame1.video_frame_buffer(), 0, 0, kVideoRotation_0);
magjed@webrtc.org2386d6d2015-03-05 14:03:08 +0000235 frame1.CreateEmptyFrame(640, 320, 640, 320, 320);
236 EXPECT_NE(y, frame1.buffer(kYPlane));
237 EXPECT_NE(u, frame1.buffer(kUPlane));
238 EXPECT_NE(v, frame1.buffer(kVPlane));
mikhal@webrtc.orge239bf02012-12-19 00:07:57 +0000239}
240
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700241TEST(TestVideoFrame, TextureInitialValues) {
Peter Boströmeb66e802015-06-05 11:08:03 +0200242 test::FakeNativeHandle* handle = new test::FakeNativeHandle();
Peter Boström13f61df2016-01-04 22:36:38 +0100243 VideoFrame frame = test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +0200244 handle, 640, 480, 100, 10, webrtc::kVideoRotation_0);
magjed@webrtc.org45cdcce2015-03-06 10:41:00 +0000245 EXPECT_EQ(640, frame.width());
246 EXPECT_EQ(480, frame.height());
247 EXPECT_EQ(100u, frame.timestamp());
248 EXPECT_EQ(10, frame.render_time_ms());
nisse26acec42016-04-15 03:43:39 -0700249 ASSERT_TRUE(frame.video_frame_buffer() != nullptr);
250 EXPECT_EQ(handle, frame.video_frame_buffer()->native_handle());
magjed@webrtc.org45cdcce2015-03-06 10:41:00 +0000251
252 frame.set_timestamp(200);
253 EXPECT_EQ(200u, frame.timestamp());
254 frame.set_render_time_ms(20);
255 EXPECT_EQ(20, frame.render_time_ms());
256}
257
nisse7cc9cc02016-03-29 23:44:19 -0700258TEST(TestI420FrameBuffer, Copy) {
259 rtc::scoped_refptr<I420Buffer> buf1(
260 new rtc::RefCountedObject<I420Buffer>(20, 10));
nisse06176e42016-04-18 05:34:40 -0700261 memset(buf1->MutableDataY(), 1, 200);
262 memset(buf1->MutableDataU(), 2, 50);
263 memset(buf1->MutableDataV(), 3, 50);
nisse7cc9cc02016-03-29 23:44:19 -0700264 rtc::scoped_refptr<I420Buffer> buf2 = I420Buffer::Copy(buf1);
265 EXPECT_TRUE(test::FrameBufsEqual(buf1, buf2));
266}
267
mikhal@webrtc.org043ed9e2012-09-18 16:14:26 +0000268} // namespace webrtc