blob: 27503e5b8aa6aad7379f8e3ac43e61190148d17e [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "common_video/include/i420_buffer_pool.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stdint.h>
14#include <string.h>
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000015
Mirko Bonadeid9708072019-01-25 20:26:48 +010016#include "api/scoped_refptr.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "api/video/i420_buffer.h"
18#include "api/video/video_frame_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "test/gtest.h"
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000020
21namespace webrtc {
22
23TEST(TestI420BufferPool, SimpleFrameReuse) {
24 I420BufferPool pool;
Noah Richards408a3c62019-04-01 10:14:47 -070025 auto buffer = pool.CreateBuffer(16, 16);
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000026 EXPECT_EQ(16, buffer->width());
27 EXPECT_EQ(16, buffer->height());
28 // Extract non-refcounted pointers for testing.
nisse06176e42016-04-18 05:34:40 -070029 const uint8_t* y_ptr = buffer->DataY();
30 const uint8_t* u_ptr = buffer->DataU();
31 const uint8_t* v_ptr = buffer->DataV();
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000032 // Release buffer so that it is returned to the pool.
33 buffer = nullptr;
34 // Check that the memory is resued.
35 buffer = pool.CreateBuffer(16, 16);
nisse06176e42016-04-18 05:34:40 -070036 EXPECT_EQ(y_ptr, buffer->DataY());
37 EXPECT_EQ(u_ptr, buffer->DataU());
38 EXPECT_EQ(v_ptr, buffer->DataV());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000039}
40
Noah Richards408a3c62019-04-01 10:14:47 -070041TEST(TestI420BufferPool, FrameReuseWithDefaultThenExplicitStride) {
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000042 I420BufferPool pool;
Noah Richards408a3c62019-04-01 10:14:47 -070043 auto buffer = pool.CreateBuffer(15, 16);
44 EXPECT_EQ(15, buffer->width());
45 EXPECT_EQ(16, buffer->height());
46 // The default Y stride is width and UV stride is halfwidth (rounded up).
47 ASSERT_EQ(15, buffer->StrideY());
48 ASSERT_EQ(8, buffer->StrideU());
49 ASSERT_EQ(8, buffer->StrideV());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000050 // Extract non-refcounted pointers for testing.
Noah Richards408a3c62019-04-01 10:14:47 -070051 const uint8_t* y_ptr = buffer->DataY();
nisse06176e42016-04-18 05:34:40 -070052 const uint8_t* u_ptr = buffer->DataU();
53 const uint8_t* v_ptr = buffer->DataV();
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000054 // Release buffer so that it is returned to the pool.
55 buffer = nullptr;
Noah Richards408a3c62019-04-01 10:14:47 -070056 // Check that the memory is resued with explicit strides if they match the
57 // assumed default above.
58 buffer = pool.CreateBuffer(15, 16, 15, 8, 8);
59 EXPECT_EQ(y_ptr, buffer->DataY());
60 EXPECT_EQ(u_ptr, buffer->DataU());
61 EXPECT_EQ(v_ptr, buffer->DataV());
62 EXPECT_EQ(15, buffer->width());
63 EXPECT_EQ(16, buffer->height());
64 EXPECT_EQ(15, buffer->StrideY());
65 EXPECT_EQ(8, buffer->StrideU());
66 EXPECT_EQ(8, buffer->StrideV());
67}
68
69TEST(TestI420BufferPool, FailToReuseWrongSize) {
70 // Set max frames to 1, just to make sure the first buffer is being released.
71 I420BufferPool pool(/*zero_initialize=*/false, 1);
72 auto buffer = pool.CreateBuffer(16, 16);
73 EXPECT_EQ(16, buffer->width());
74 EXPECT_EQ(16, buffer->height());
75 // Release buffer so that it is returned to the pool.
76 buffer = nullptr;
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000077 // Check that the pool doesn't try to reuse buffers of incorrect size.
78 buffer = pool.CreateBuffer(32, 16);
Noah Richards408a3c62019-04-01 10:14:47 -070079 ASSERT_TRUE(buffer);
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000080 EXPECT_EQ(32, buffer->width());
81 EXPECT_EQ(16, buffer->height());
Noah Richards408a3c62019-04-01 10:14:47 -070082}
83
84TEST(TestI420BufferPool, FailToReuseWrongStride) {
85 // Set max frames to 1, just to make sure the first buffer is being released.
86 I420BufferPool pool(/*zero_initialize=*/false, 1);
87 auto buffer = pool.CreateBuffer(32, 32, 32, 16, 16);
88 // Make sure the stride was read correctly, for the rest of the test.
89 ASSERT_EQ(16, buffer->StrideU());
90 ASSERT_EQ(16, buffer->StrideV());
91 buffer = pool.CreateBuffer(32, 32, 32, 20, 20);
92 ASSERT_TRUE(buffer);
93 EXPECT_EQ(32, buffer->StrideY());
94 EXPECT_EQ(20, buffer->StrideU());
95 EXPECT_EQ(20, buffer->StrideV());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000096}
97
magjed@webrtc.org73d763e2015-03-17 11:40:45 +000098TEST(TestI420BufferPool, FrameValidAfterPoolDestruction) {
nisse64ec8f82016-09-27 00:17:25 -070099 rtc::scoped_refptr<I420Buffer> buffer;
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000100 {
101 I420BufferPool pool;
102 buffer = pool.CreateBuffer(16, 16);
103 }
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000104 EXPECT_EQ(16, buffer->width());
105 EXPECT_EQ(16, buffer->height());
106 // Try to trigger use-after-free errors by writing to y-plane.
nisse06176e42016-04-18 05:34:40 -0700107 memset(buffer->MutableDataY(), 0xA5, 16 * buffer->StrideY());
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000108}
109
Per00983572016-11-04 08:57:26 +0100110TEST(TestI420BufferPool, MaxNumberOfBuffers) {
111 I420BufferPool pool(false, 1);
Noah Richards408a3c62019-04-01 10:14:47 -0700112 auto buffer1 = pool.CreateBuffer(16, 16);
Per00983572016-11-04 08:57:26 +0100113 EXPECT_NE(nullptr, buffer1.get());
114 EXPECT_EQ(nullptr, pool.CreateBuffer(16, 16).get());
115}
116
magjed@webrtc.org73d763e2015-03-17 11:40:45 +0000117} // namespace webrtc