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

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: 5b80a5e9 scoped_refptr-ization. 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 buffer_id,
25 void* data,
26 size_t size)
27 : pool_(pool), buffer_id_(buffer_id), data_(data), size_(size) {}
28 ~Buffer() { pool_->RelinquishProducerReservation(buffer_id_); }
29 void* data() const { return data_; }
30 size_t size() const { return size_; }
31
32 private:
33 const scoped_refptr<VideoCaptureBufferPool> pool_;
34 const int buffer_id_;
35 void* const data_;
36 const size_t size_;
37 };
21 VideoCaptureBufferPoolTest() 38 VideoCaptureBufferPoolTest()
22 : expected_dropped_id_(0), 39 : expected_dropped_id_(0),
23 pool_(new VideoCaptureBufferPool(3)) {} 40 pool_(new VideoCaptureBufferPool(3)) {}
24 41
25 void ExpectDroppedId(int expected_dropped_id) { 42 void ExpectDroppedId(int expected_dropped_id) {
26 expected_dropped_id_ = expected_dropped_id; 43 expected_dropped_id_ = expected_dropped_id;
27 } 44 }
28 45
29 scoped_refptr<media::VideoFrame> ReserveI420VideoFrame( 46 scoped_ptr<Buffer> ReserveI420Buffer(const gfx::Size& dimensions) {
30 const gfx::Size& size) { 47 const size_t frame_bytes =
31 // To verify that ReserveI420VideoFrame always sets |buffer_id_to_drop|, 48 media::VideoFrame::AllocationSize(media::VideoFrame::I420, dimensions);
49 // To verify that ReserveI420Buffer always sets |buffer_id_to_drop|,
32 // initialize it to something different than the expected value. 50 // initialize it to something different than the expected value.
33 int buffer_id_to_drop = ~expected_dropped_id_; 51 int buffer_id_to_drop = ~expected_dropped_id_;
34 scoped_refptr<media::VideoFrame> frame = 52 int buffer_id = pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop);
35 pool_->ReserveI420VideoFrame(size, 0, &buffer_id_to_drop); 53 if (buffer_id == VideoCaptureBufferPool::kInvalidId)
36 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop) 54 return scoped_ptr<Buffer>();
37 << "Unexpected buffer reallocation result."; 55
38 return frame; 56 void* memory;
57 size_t size;
58 pool_->GetBufferInfo(buffer_id, &memory, &size);
59 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop);
60 return scoped_ptr<Buffer>(new Buffer(pool_, buffer_id, memory, size));
39 } 61 }
40 62
41 int expected_dropped_id_; 63 int expected_dropped_id_;
42 scoped_refptr<VideoCaptureBufferPool> pool_; 64 scoped_refptr<VideoCaptureBufferPool> pool_;
43 65
44 private: 66 private:
45 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest); 67 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest);
46 }; 68 };
47 69
48 TEST_F(VideoCaptureBufferPoolTest, BufferPool) { 70 TEST_F(VideoCaptureBufferPoolTest, BufferPool) {
49 const gfx::Size size_lo = gfx::Size(640, 480); 71 const gfx::Size size_lo = gfx::Size(640, 480);
50 const gfx::Size size_hi = gfx::Size(1024, 768); 72 const gfx::Size size_hi = gfx::Size(1024, 768);
51 scoped_refptr<media::VideoFrame> non_pool_frame = 73 scoped_refptr<media::VideoFrame> non_pool_frame =
52 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo, 74 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo,
53 gfx::Rect(size_lo), size_lo, 75 gfx::Rect(size_lo), size_lo,
54 base::TimeDelta()); 76 base::TimeDelta());
55 77
56 // Reallocation won't happen for the first part of the test. 78 // Reallocation won't happen for the first part of the test.
57 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); 79 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
58 80
59 scoped_refptr<media::VideoFrame> frame1 = ReserveI420VideoFrame(size_lo); 81 scoped_ptr<Buffer> buffer1 = ReserveI420Buffer(size_lo);
60 ASSERT_TRUE(NULL != frame1.get()); 82 ASSERT_TRUE(NULL != buffer1.get());
61 ASSERT_EQ(size_lo, frame1->coded_size()); 83 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
62 scoped_refptr<media::VideoFrame> frame2 = ReserveI420VideoFrame(size_lo); 84 buffer1->size());
63 ASSERT_TRUE(NULL != frame2.get()); 85 scoped_ptr<Buffer> buffer2 = ReserveI420Buffer(size_lo);
64 ASSERT_EQ(size_lo, frame2->coded_size()); 86 ASSERT_TRUE(NULL != buffer2.get());
65 scoped_refptr<media::VideoFrame> frame3 = ReserveI420VideoFrame(size_lo); 87 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
66 ASSERT_TRUE(NULL != frame3.get()); 88 buffer2->size());
89 scoped_ptr<Buffer> buffer3 = ReserveI420Buffer(size_lo);
90 ASSERT_TRUE(NULL != buffer3.get());
91 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
92 buffer3->size());
67 93
68 // Touch the memory. 94 // Touch the memory.
69 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33); 95 memset(buffer1->data(), 0x11, buffer1->size());
70 media::FillYUV(frame2.get(), 0x44, 0x55, 0x66); 96 memset(buffer2->data(), 0x44, buffer2->size());
71 media::FillYUV(frame3.get(), 0x77, 0x88, 0x99); 97 memset(buffer3->data(), 0x77, buffer3->size());
72 98
73 // Fourth frame should fail. 99 // Fourth buffer should fail.
74 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 100 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
75 101
76 // Release 1st frame and retry; this should succeed. 102 // Release 1st buffer and retry; this should succeed.
77 frame1 = NULL; 103 buffer1.reset();
78 scoped_refptr<media::VideoFrame> frame4 = ReserveI420VideoFrame(size_lo); 104 scoped_ptr<Buffer> buffer4 = ReserveI420Buffer(size_lo);
79 ASSERT_TRUE(NULL != frame4.get()); 105 ASSERT_TRUE(NULL != buffer4.get());
80 106
81 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 107 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
82 ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty"; 108 ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty";
83 109
84 // Validate the IDs 110 // Validate the IDs
85 int buffer_id2 = 111 int buffer_id2 = pool_->RecognizeReservedBuffer(buffer2->data());
86 pool_->RecognizeReservedBuffer(frame2->shared_memory_handle());
87 ASSERT_EQ(1, buffer_id2); 112 ASSERT_EQ(1, buffer_id2);
88 int buffer_id3 = 113 int buffer_id3 = pool_->RecognizeReservedBuffer(buffer3->data());
89 pool_->RecognizeReservedBuffer(frame3->shared_memory_handle());
90 base::SharedMemoryHandle memory_handle3 = frame3->shared_memory_handle();
91 ASSERT_EQ(2, buffer_id3); 114 ASSERT_EQ(2, buffer_id3);
92 int buffer_id4 = 115 void* const memory_pointer3 = buffer3->data();
93 pool_->RecognizeReservedBuffer(frame4->shared_memory_handle()); 116 int buffer_id4 = pool_->RecognizeReservedBuffer(buffer4->data());
94 ASSERT_EQ(0, buffer_id4); 117 ASSERT_EQ(0, buffer_id4);
95 int buffer_id_non_pool = 118 int buffer_id_non_pool =
96 pool_->RecognizeReservedBuffer(non_pool_frame->shared_memory_handle()); 119 pool_->RecognizeReservedBuffer(non_pool_frame->data(0));
97 ASSERT_EQ(VideoCaptureBufferPool::kInvalidId, buffer_id_non_pool); 120 ASSERT_EQ(VideoCaptureBufferPool::kInvalidId, buffer_id_non_pool);
98 121
99 // Deliver a frame. 122 // Deliver a buffer.
100 pool_->HoldForConsumers(buffer_id3, 2); 123 pool_->HoldForConsumers(buffer_id3, 2);
101 124
102 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 125 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
103 126
104 frame3 = NULL; // Old producer releases frame. Should be a noop. 127 buffer3.reset(); // Old producer releases buffer. Should be a noop.
105 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 128 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
106 ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty"; 129 ASSERT_FALSE(ReserveI420Buffer(size_hi)) << "Pool should be empty";
107 130
108 frame2 = NULL; // Active producer releases frame. Should free a frame. 131 buffer2.reset(); // Active producer releases buffer. Should free a buffer.
109 132
110 frame1 = ReserveI420VideoFrame(size_lo); 133 buffer1 = ReserveI420Buffer(size_lo);
111 ASSERT_TRUE(NULL != frame1.get()); 134 ASSERT_TRUE(NULL != buffer1.get());
112 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 135 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
113 136
114 // First consumer finishes. 137 // First consumer finishes.
115 pool_->RelinquishConsumerHold(buffer_id3, 1); 138 pool_->RelinquishConsumerHold(buffer_id3, 1);
116 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 139 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
117 140
118 // Second consumer finishes. This should free that frame. 141 // Second consumer finishes. This should free that buffer.
119 pool_->RelinquishConsumerHold(buffer_id3, 1); 142 pool_->RelinquishConsumerHold(buffer_id3, 1);
120 frame3 = ReserveI420VideoFrame(size_lo); 143 buffer3 = ReserveI420Buffer(size_lo);
121 ASSERT_TRUE(NULL != frame3.get()); 144 ASSERT_TRUE(NULL != buffer3.get());
122 ASSERT_EQ(buffer_id3, 145 ASSERT_EQ(buffer_id3, pool_->RecognizeReservedBuffer(buffer3->data()))
123 pool_->RecognizeReservedBuffer(frame3->shared_memory_handle()))
124 << "Buffer ID should be reused."; 146 << "Buffer ID should be reused.";
125 ASSERT_EQ(memory_handle3, frame3->shared_memory_handle()); 147 ASSERT_EQ(memory_pointer3, buffer3->data());
126 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 148 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
127 149
128 // Now deliver & consume frame1, but don't release the VideoFrame. 150 // Now deliver & consume buffer1, but don't release the buffer.
129 int buffer_id1 = 151 int buffer_id1 = pool_->RecognizeReservedBuffer(buffer1->data());
130 pool_->RecognizeReservedBuffer(frame1->shared_memory_handle());
131 ASSERT_EQ(1, buffer_id1); 152 ASSERT_EQ(1, buffer_id1);
132 pool_->HoldForConsumers(buffer_id1, 5); 153 pool_->HoldForConsumers(buffer_id1, 5);
133 pool_->RelinquishConsumerHold(buffer_id1, 5); 154 pool_->RelinquishConsumerHold(buffer_id1, 5);
134 155
135 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot 156 // 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 157 // 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 158 // when |buffer1| goes away, we should be able to re-reserve the buffer (and
138 // the ID ought to be the same). 159 // the ID ought to be the same).
139 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 160 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
140 frame1 = NULL; // Should free the frame. 161 buffer1.reset(); // Should free the buffer.
141 frame2 = ReserveI420VideoFrame(size_lo); 162 buffer2 = ReserveI420Buffer(size_lo);
142 ASSERT_TRUE(NULL != frame2.get()); 163 ASSERT_TRUE(NULL != buffer2.get());
143 ASSERT_EQ(buffer_id1, 164 ASSERT_EQ(buffer_id1, pool_->RecognizeReservedBuffer(buffer2->data()));
144 pool_->RecognizeReservedBuffer(frame2->shared_memory_handle()));
145 buffer_id2 = buffer_id1; 165 buffer_id2 = buffer_id1;
146 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 166 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
147 167
148 // Now try reallocation with different resolutions. We expect reallocation 168 // Now try reallocation with different resolutions. We expect reallocation
149 // to occur only when the old buffer is too small. 169 // to occur only when the old buffer is too small.
150 frame2 = NULL; 170 buffer2.reset();
151 ExpectDroppedId(buffer_id2); 171 ExpectDroppedId(buffer_id2);
152 frame2 = ReserveI420VideoFrame(size_hi); 172 buffer2 = ReserveI420Buffer(size_hi);
153 ASSERT_TRUE(NULL != frame2.get()); 173 ASSERT_TRUE(NULL != buffer2.get());
154 ASSERT_TRUE(frame2->coded_size() == size_hi); 174 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_hi),
155 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); 175 buffer2->size());
156 base::SharedMemoryHandle memory_handle_hi = frame2->shared_memory_handle(); 176 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(buffer2->data()));
157 frame2 = NULL; // Frees it. 177 void* const memory_pointer_hi = buffer2->data();
178 buffer2.reset(); // Frees it.
158 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); 179 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
159 frame2 = ReserveI420VideoFrame(size_lo); 180 buffer2 = ReserveI420Buffer(size_lo);
160 base::SharedMemoryHandle memory_handle_lo = frame2->shared_memory_handle(); 181 void* const memory_pointer_lo = buffer2->data();
161 ASSERT_EQ(memory_handle_hi, memory_handle_lo) 182 ASSERT_EQ(memory_pointer_hi, memory_pointer_lo)
162 << "Decrease in resolution should not reallocate buffer"; 183 << "Decrease in resolution should not reallocate buffer";
163 ASSERT_TRUE(NULL != frame2.get()); 184 ASSERT_TRUE(NULL != buffer2.get());
164 ASSERT_TRUE(frame2->coded_size() == size_lo); 185 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(buffer2->data()));
165 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); 186 ASSERT_LE(media::VideoFrame::AllocationSize(media::VideoFrame::I420, size_lo),
166 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; 187 buffer2->size());
188 ASSERT_FALSE(ReserveI420Buffer(size_lo)) << "Pool should be empty";
167 189
168 // Tear down the pool_, writing into the frames. The VideoFrame should 190 // Tear down the pool_, writing into the buffers. The buffer should preserve
169 // preserve the lifetime of the underlying memory. 191 // the lifetime of the underlying memory.
170 frame3 = NULL; 192 buffer3.reset();
171 pool_ = NULL; 193 pool_ = NULL;
172 194
173 // Touch the memory. 195 // Touch the memory.
174 media::FillYUV(frame2.get(), 0x11, 0x22, 0x33); 196 memset(buffer2->data(), 0x22, buffer2->size());
175 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); 197 memset(buffer4->data(), 0x55, buffer4->size());
176 198
177 frame2 = NULL; 199 buffer2.reset();
178 200
179 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); 201 memset(buffer4->data(), 0x77, buffer4->size());
180 frame4 = NULL; 202 buffer4.reset();
181 } 203 }
182 204
183 } // namespace content 205 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698