blob: 230f340365a0a13d81c1500570e97d02e38e0137 [file] [log] [blame]
magjed@webrtc.org73d763e2015-03-17 11:40:45 +00001/*
2 * Copyright (c) 2015 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
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <stdint.h>
12#include <string.h>
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000013
Mirko Bonadeid9708072019-01-25 20:26:48 +010014#include "api/scoped_refptr.h"
Yves Gerey3e707812018-11-28 16:47:49 +010015#include "api/video/i420_buffer.h"
16#include "api/video/video_frame_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "common_video/include/i420_buffer_pool.h"
18#include "test/gtest.h"
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000019
20namespace webrtc {
21
22TEST(TestI420BufferPool, SimpleFrameReuse) {
23 I420BufferPool pool;
Noah Richards408a3c62019-04-01 10:14:47 -070024 auto buffer = pool.CreateBuffer(16, 16);
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000025 EXPECT_EQ(16, buffer->width());
26 EXPECT_EQ(16, buffer->height());
27 // Extract non-refcounted pointers for testing.
nisse06176e42016-04-18 05:34:40 -070028 const uint8_t* y_ptr = buffer->DataY();
29 const uint8_t* u_ptr = buffer->DataU();
30 const uint8_t* v_ptr = buffer->DataV();
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000031 // Release buffer so that it is returned to the pool.
32 buffer = nullptr;
33 // Check that the memory is resued.
34 buffer = pool.CreateBuffer(16, 16);
nisse06176e42016-04-18 05:34:40 -070035 EXPECT_EQ(y_ptr, buffer->DataY());
36 EXPECT_EQ(u_ptr, buffer->DataU());
37 EXPECT_EQ(v_ptr, buffer->DataV());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000038}
39
Noah Richards408a3c62019-04-01 10:14:47 -070040TEST(TestI420BufferPool, FrameReuseWithDefaultThenExplicitStride) {
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000041 I420BufferPool pool;
Noah Richards408a3c62019-04-01 10:14:47 -070042 auto buffer = pool.CreateBuffer(15, 16);
43 EXPECT_EQ(15, buffer->width());
44 EXPECT_EQ(16, buffer->height());
45 // The default Y stride is width and UV stride is halfwidth (rounded up).
46 ASSERT_EQ(15, buffer->StrideY());
47 ASSERT_EQ(8, buffer->StrideU());
48 ASSERT_EQ(8, buffer->StrideV());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000049 // Extract non-refcounted pointers for testing.
Noah Richards408a3c62019-04-01 10:14:47 -070050 const uint8_t* y_ptr = buffer->DataY();
nisse06176e42016-04-18 05:34:40 -070051 const uint8_t* u_ptr = buffer->DataU();
52 const uint8_t* v_ptr = buffer->DataV();
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000053 // Release buffer so that it is returned to the pool.
54 buffer = nullptr;
Noah Richards408a3c62019-04-01 10:14:47 -070055 // Check that the memory is resued with explicit strides if they match the
56 // assumed default above.
57 buffer = pool.CreateBuffer(15, 16, 15, 8, 8);
58 EXPECT_EQ(y_ptr, buffer->DataY());
59 EXPECT_EQ(u_ptr, buffer->DataU());
60 EXPECT_EQ(v_ptr, buffer->DataV());
61 EXPECT_EQ(15, buffer->width());
62 EXPECT_EQ(16, buffer->height());
63 EXPECT_EQ(15, buffer->StrideY());
64 EXPECT_EQ(8, buffer->StrideU());
65 EXPECT_EQ(8, buffer->StrideV());
66}
67
68TEST(TestI420BufferPool, FailToReuseWrongSize) {
69 // Set max frames to 1, just to make sure the first buffer is being released.
70 I420BufferPool pool(/*zero_initialize=*/false, 1);
71 auto buffer = pool.CreateBuffer(16, 16);
72 EXPECT_EQ(16, buffer->width());
73 EXPECT_EQ(16, buffer->height());
74 // Release buffer so that it is returned to the pool.
75 buffer = nullptr;
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000076 // Check that the pool doesn't try to reuse buffers of incorrect size.
77 buffer = pool.CreateBuffer(32, 16);
Noah Richards408a3c62019-04-01 10:14:47 -070078 ASSERT_TRUE(buffer);
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000079 EXPECT_EQ(32, buffer->width());
80 EXPECT_EQ(16, buffer->height());
Noah Richards408a3c62019-04-01 10:14:47 -070081}
82
83TEST(TestI420BufferPool, FailToReuseWrongStride) {
84 // Set max frames to 1, just to make sure the first buffer is being released.
85 I420BufferPool pool(/*zero_initialize=*/false, 1);
86 auto buffer = pool.CreateBuffer(32, 32, 32, 16, 16);
87 // Make sure the stride was read correctly, for the rest of the test.
88 ASSERT_EQ(16, buffer->StrideU());
89 ASSERT_EQ(16, buffer->StrideV());
90 buffer = pool.CreateBuffer(32, 32, 32, 20, 20);
91 ASSERT_TRUE(buffer);
92 EXPECT_EQ(32, buffer->StrideY());
93 EXPECT_EQ(20, buffer->StrideU());
94 EXPECT_EQ(20, buffer->StrideV());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000095}
96
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000097TEST(TestI420BufferPool, FrameValidAfterPoolDestruction) {
nisse64ec8f82016-09-27 00:17:25 -070098 rtc::scoped_refptr<I420Buffer> buffer;
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000099 {
100 I420BufferPool pool;
101 buffer = pool.CreateBuffer(16, 16);
102 }
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000103 EXPECT_EQ(16, buffer->width());
104 EXPECT_EQ(16, buffer->height());
105 // Try to trigger use-after-free errors by writing to y-plane.
nisse06176e42016-04-18 05:34:40 -0700106 memset(buffer->MutableDataY(), 0xA5, 16 * buffer->StrideY());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000107}
108
Per00983572016-11-04 08:57:26 +0100109TEST(TestI420BufferPool, MaxNumberOfBuffers) {
110 I420BufferPool pool(false, 1);
Noah Richards408a3c62019-04-01 10:14:47 -0700111 auto buffer1 = pool.CreateBuffer(16, 16);
Per00983572016-11-04 08:57:26 +0100112 EXPECT_NE(nullptr, buffer1.get());
113 EXPECT_EQ(nullptr, pool.CreateBuffer(16, 16).get());
114}
115
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000116} // namespace webrtc