Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc

Issue 48113011: Remove media::VideoFrame from media::VideoCaptureDevice::Client interface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: ffdbaeb83 Trybot failures. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Unit test for VideoCaptureBufferPool. 5 // Unit test for VideoCaptureBufferPool.
6 6
7 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" 7 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "content/browser/renderer_host/media/video_capture_controller.h" 12 #include "content/browser/renderer_host/media/video_capture_controller.h"
13 #include "media/base/video_frame.h" 13 #include "media/base/video_frame.h"
14 #include "media/base/video_util.h" 14 #include "media/base/video_util.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 16
17 namespace content { 17 namespace content {
18 18
19 class VideoCaptureBufferPoolTest : public testing::Test { 19 class VideoCaptureBufferPoolTest : public testing::Test {
20 protected: 20 protected:
21 class Buffer {
22 public:
23 Buffer(const scoped_refptr<VideoCaptureBufferPool> pool,
24 int id,
25 void* data,
26 size_t size)
27 : pool_(pool), id_(id), data_(data), size_(size) {}
28 ~Buffer() { pool_->RelinquishProducerReservation(id()); }
29 int id() const { return id_; }
30 void* data() const { return data_; }
31 size_t size() const { return size_; }
32
33 private:
34 const scoped_refptr<VideoCaptureBufferPool> pool_;
35 const int id_;
36 void* const data_;
37 const size_t size_;
38 };
21 VideoCaptureBufferPoolTest() 39 VideoCaptureBufferPoolTest()
22 : expected_dropped_id_(0), 40 : expected_dropped_id_(0),
23 pool_(new VideoCaptureBufferPool(3)) {} 41 pool_(new VideoCaptureBufferPool(3)) {}
24 42
25 void ExpectDroppedId(int expected_dropped_id) { 43 void ExpectDroppedId(int expected_dropped_id) {
26 expected_dropped_id_ = expected_dropped_id; 44 expected_dropped_id_ = expected_dropped_id;
27 } 45 }
28 46
29 scoped_refptr<media::VideoFrame> ReserveI420VideoFrame( 47 scoped_ptr<Buffer> ReserveI420Buffer(const gfx::Size& dimensions) {
30 const gfx::Size& size) { 48 const size_t frame_bytes =
31 // To verify that ReserveI420VideoFrame always sets |buffer_id_to_drop|, 49 media::VideoFrame::AllocationSize(media::VideoFrame::I420, dimensions);
50 // To verify that ReserveI420Buffer always sets |buffer_id_to_drop|,
32 // initialize it to something different than the expected value. 51 // initialize it to something different than the expected value.
33 int buffer_id_to_drop = ~expected_dropped_id_; 52 int buffer_id_to_drop = ~expected_dropped_id_;
34 scoped_refptr<media::VideoFrame> frame = 53 int buffer_id = pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop);
35 pool_->ReserveI420VideoFrame(size, 0, &buffer_id_to_drop); 54 if (buffer_id == VideoCaptureBufferPool::kInvalidId)
36 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop) 55 return scoped_ptr<Buffer>();
37 << "Unexpected buffer reallocation result."; 56
38 return frame; 57 void* memory;
58 size_t size;
59 pool_->GetBufferInfo(buffer_id, &memory, &size);
60 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop);
61 return scoped_ptr<Buffer>(new Buffer(pool_, buffer_id, memory, size));
39 } 62 }
40 63
41 int expected_dropped_id_; 64 int expected_dropped_id_;
42 scoped_refptr<VideoCaptureBufferPool> pool_; 65 scoped_refptr<VideoCaptureBufferPool> pool_;
43 66
44 private: 67 private:
45 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest); 68 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest);
46 }; 69 };
47 70
48 TEST_F(VideoCaptureBufferPoolTest, BufferPool) { 71 TEST_F(VideoCaptureBufferPoolTest, BufferPool) {
49 const gfx::Size size_lo = gfx::Size(640, 480); 72 const gfx::Size size_lo = gfx::Size(640, 480);
50 const gfx::Size size_hi = gfx::Size(1024, 768); 73 const gfx::Size size_hi = gfx::Size(1024, 768);
51 scoped_refptr<media::VideoFrame> non_pool_frame = 74 scoped_refptr<media::VideoFrame> non_pool_frame =
52 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo, 75 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo,
53 gfx::Rect(size_lo), size_lo, 76 gfx::Rect(size_lo), size_lo,
54 base::TimeDelta()); 77 base::TimeDelta());
55 78
56 // Reallocation won't happen for the first part of the test. 79 // Reallocation won't happen for the first part of the test.
57 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); 80 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
58 81
59 scoped_refptr<media::VideoFrame> frame1 = ReserveI420VideoFrame(size_lo); 82 scoped_ptr<Buffer> buffer1 = ReserveI420Buffer(size_lo);
60 ASSERT_TRUE(NULL != frame1.get()); 83 ASSERT_TRUE(NULL != buffer1.get());
61 ASSERT_EQ(size_lo, frame1->coded_size()); 84 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
62 scoped_refptr<media::VideoFrame> frame2 = ReserveI420VideoFrame(size_lo); 85 buffer1->size());
63 ASSERT_TRUE(NULL != frame2.get()); 86 scoped_ptr<Buffer> buffer2 = ReserveI420Buffer(size_lo);
64 ASSERT_EQ(size_lo, frame2->coded_size()); 87 ASSERT_TRUE(NULL != buffer2.get());
65 scoped_refptr<media::VideoFrame> frame3 = ReserveI420VideoFrame(size_lo); 88 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
66 ASSERT_TRUE(NULL != frame3.get()); 89 buffer2->size());
90 scoped_ptr<Buffer> buffer3 = ReserveI420Buffer(size_lo);
91 ASSERT_TRUE(NULL != buffer3.get());
92 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
93 buffer3->size());
67 94
68 // Touch the memory. 95 // Touch the memory.
69 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33); 96 memset(buffer1->data(), 0x11, buffer1->size());
70 media::FillYUV(frame2.get(), 0x44, 0x55, 0x66); 97 memset(buffer2->data(), 0x44, buffer2->size());
71 media::FillYUV(frame3.get(), 0x77, 0x88, 0x99); 98 memset(buffer3->data(), 0x77, buffer3->size());
72 99
73 // Fourth frame should fail. 100 // Fourth buffer should fail.
74 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 101 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
75 102
76 // Release 1st frame and retry; this should succeed. 103 // Release 1st buffer and retry; this should succeed.
77 frame1 = NULL; 104 buffer1.reset();
78 scoped_refptr<media::VideoFrame> frame4 = ReserveI420VideoFrame(size_lo); 105 scoped_ptr<Buffer> buffer4 = ReserveI420Buffer(size_lo);
79 ASSERT_TRUE(NULL != frame4.get()); 106 ASSERT_TRUE(NULL != buffer4.get());
80 107
81 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 108 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
82 ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty"; 109 ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty";
83 110
84 // Validate the IDs 111 // Validate the IDs
85 int buffer_id2 = 112 int buffer_id2 = buffer2->id();
86 pool_->RecognizeReservedBuffer(frame2->shared_memory_handle());
87 ASSERT_EQ(1, buffer_id2); 113 ASSERT_EQ(1, buffer_id2);
88 int buffer_id3 = 114 int buffer_id3 = buffer3->id();
89 pool_->RecognizeReservedBuffer(frame3->shared_memory_handle());
90 base::SharedMemoryHandle memory_handle3 = frame3->shared_memory_handle();
91 ASSERT_EQ(2, buffer_id3); 115 ASSERT_EQ(2, buffer_id3);
92 int buffer_id4 = 116 void* const memory_pointer3 = buffer3->data();
93 pool_->RecognizeReservedBuffer(frame4->shared_memory_handle()); 117 int buffer_id4 = buffer4->id();
94 ASSERT_EQ(0, buffer_id4); 118 ASSERT_EQ(0, buffer_id4);
95 int buffer_id_non_pool =
96 pool_->RecognizeReservedBuffer(non_pool_frame->shared_memory_handle());
97 ASSERT_EQ(VideoCaptureBufferPool::kInvalidId, buffer_id_non_pool);
98 119
99 // Deliver a frame. 120 // Deliver a buffer.
100 pool_->HoldForConsumers(buffer_id3, 2); 121 pool_->HoldForConsumers(buffer_id3, 2);
101 122
102 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 123 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
103 124
104 frame3 = NULL; // Old producer releases frame. Should be a noop. 125 buffer3.reset(); // Old producer releases buffer. Should be a noop.
105 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 126 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
106 ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty"; 127 ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty";
107 128
108 frame2 = NULL; // Active producer releases frame. Should free a frame. 129 buffer2.reset(); // Active producer releases buffer. Should free a buffer.
109 130
110 frame1 = ReserveI420VideoFrame(size_lo); 131 buffer1 = ReserveI420Buffer(size_lo);
111 ASSERT_TRUE(NULL != frame1.get()); 132 ASSERT_TRUE(NULL != buffer1.get());
112 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 133 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
113 134
114 // First consumer finishes. 135 // First consumer finishes.
115 pool_->RelinquishConsumerHold(buffer_id3, 1); 136 pool_->RelinquishConsumerHold(buffer_id3, 1);
116 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 137 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
117 138
118 // Second consumer finishes. This should free that frame. 139 // Second consumer finishes. This should free that buffer.
119 pool_->RelinquishConsumerHold(buffer_id3, 1); 140 pool_->RelinquishConsumerHold(buffer_id3, 1);
120 frame3 = ReserveI420VideoFrame(size_lo); 141 buffer3 = ReserveI420Buffer(size_lo);
121 ASSERT_TRUE(NULL != frame3.get()); 142 ASSERT_TRUE(NULL != buffer3.get());
122 ASSERT_EQ(buffer_id3, 143 ASSERT_EQ(buffer_id3, buffer3->id()) << "Buffer ID should be reused.";
123 pool_->RecognizeReservedBuffer(frame3->shared_memory_handle())) 144 ASSERT_EQ(memory_pointer3, buffer3->data());
124 << "Buffer ID should be reused."; 145 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
125 ASSERT_EQ(memory_handle3, frame3->shared_memory_handle());
126 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
127 146
128 // Now deliver & consume frame1, but don't release the VideoFrame. 147 // Now deliver & consume buffer1, but don't release the buffer.
129 int buffer_id1 = 148 int buffer_id1 = buffer1->id();
130 pool_->RecognizeReservedBuffer(frame1->shared_memory_handle());
131 ASSERT_EQ(1, buffer_id1); 149 ASSERT_EQ(1, buffer_id1);
132 pool_->HoldForConsumers(buffer_id1, 5); 150 pool_->HoldForConsumers(buffer_id1, 5);
133 pool_->RelinquishConsumerHold(buffer_id1, 5); 151 pool_->RelinquishConsumerHold(buffer_id1, 5);
134 152
135 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot 153 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot
136 // be re-allocated to the producer, because |frame1| still references it. But 154 // be re-allocated to the producer, because |buffer1| still references it. But
137 // when |frame1| goes away, we should be able to re-reserve the buffer (and 155 // when |buffer1| goes away, we should be able to re-reserve the buffer (and
138 // the ID ought to be the same). 156 // the ID ought to be the same).
139 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 157 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
140 frame1 = NULL; // Should free the frame. 158 buffer1.reset(); // Should free the buffer.
141 frame2 = ReserveI420VideoFrame(size_lo); 159 buffer2 = ReserveI420Buffer(size_lo);
142 ASSERT_TRUE(NULL != frame2.get()); 160 ASSERT_TRUE(NULL != buffer2.get());
143 ASSERT_EQ(buffer_id1, 161 ASSERT_EQ(buffer_id1, buffer2->id());
144 pool_->RecognizeReservedBuffer(frame2->shared_memory_handle()));
145 buffer_id2 = buffer_id1; 162 buffer_id2 = buffer_id1;
146 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 163 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
147 164
148 // Now try reallocation with different resolutions. We expect reallocation 165 // Now try reallocation with different resolutions. We expect reallocation
149 // to occur only when the old buffer is too small. 166 // to occur only when the old buffer is too small.
150 frame2 = NULL; 167 buffer2.reset();
151 ExpectDroppedId(buffer_id2); 168 ExpectDroppedId(buffer_id2);
152 frame2 = ReserveI420VideoFrame(size_hi); 169 buffer2 = ReserveI420Buffer(size_hi);
153 ASSERT_TRUE(NULL != frame2.get()); 170 ASSERT_TRUE(NULL != buffer2.get());
154 ASSERT_TRUE(frame2->coded_size() == size_hi); 171 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_hi),
155 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); 172 buffer2->size());
156 base::SharedMemoryHandle memory_handle_hi = frame2->shared_memory_handle(); 173 ASSERT_EQ(3, buffer2->id());
157 frame2 = NULL; // Frees it. 174 void* const memory_pointer_hi = buffer2->data();
175 buffer2.reset(); // Frees it.
158 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); 176 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
159 frame2 = ReserveI420VideoFrame(size_lo); 177 buffer2 = ReserveI420Buffer(size_lo);
160 base::SharedMemoryHandle memory_handle_lo = frame2->shared_memory_handle(); 178 void* const memory_pointer_lo = buffer2->data();
161 ASSERT_EQ(memory_handle_hi, memory_handle_lo) 179 ASSERT_EQ(memory_pointer_hi, memory_pointer_lo)
162 << "Decrease in resolution should not reallocate buffer"; 180 << "Decrease in resolution should not reallocate buffer";
163 ASSERT_TRUE(NULL != frame2.get()); 181 ASSERT_TRUE(NULL != buffer2.get());
164 ASSERT_TRUE(frame2->coded_size() == size_lo); 182 ASSERT_EQ(3, buffer2->id());
165 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); 183 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
166 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 184 buffer2->size());
185 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
167 186
168 // Tear down the pool_, writing into the frames. The VideoFrame should 187 // Tear down the pool_, writing into the buffers. The buffer should preserve
169 // preserve the lifetime of the underlying memory. 188 // the lifetime of the underlying memory.
170 frame3 = NULL; 189 buffer3.reset();
171 pool_ = NULL; 190 pool_ = NULL;
172 191
173 // Touch the memory. 192 // Touch the memory.
174 media::FillYUV(frame2.get(), 0x11, 0x22, 0x33); 193 memset(buffer2->data(), 0x22, buffer2->size());
175 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); 194 memset(buffer4->data(), 0x55, buffer4->size());
176 195
177 frame2 = NULL; 196 buffer2.reset();
178 197
179 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); 198 memset(buffer4->data(), 0x77, buffer4->size());
180 frame4 = NULL; 199 buffer4.reset();
181 } 200 }
182 201
183 } // namespace content 202 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698