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

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

Issue 23551011: From Video Capture, abolish OnFrameInfo and enable resolution changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes from bbudge Created 7 years, 2 months 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 | Annotate | Revision Log
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 TEST(VideoCaptureBufferPoolTest, BufferPool) { 19 class VideoCaptureBufferPoolTest : public testing::Test {
20 const gfx::Size size = gfx::Size(640, 480); 20 protected:
21 VideoCaptureBufferPoolTest()
22 : expected_dropped_id_(0),
23 pool_(new VideoCaptureBufferPool(3)) {}
24
25 void ExpectDroppedId(int expected_dropped_id) {
26 expected_dropped_id_ = expected_dropped_id;
27 }
28
29 scoped_refptr<media::VideoFrame> ReserveI420VideoFrame(
30 const gfx::Size& size) {
31 // To verify that ReserveI420VideoFrame always sets |buffer_id_to_drop|,
32 // initialize it to something different than the expected value.
33 int buffer_id_to_drop = ~expected_dropped_id_;
34 scoped_refptr<media::VideoFrame> frame =
35 pool_->ReserveI420VideoFrame(size, 0, &buffer_id_to_drop);
36 EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop)
37 << "Unexpected buffer reallocation result.";
38 return frame;
39 }
40
41 int expected_dropped_id_;
42 scoped_refptr<VideoCaptureBufferPool> pool_;
43
44 private:
45 DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest);
46 };
47
48 TEST_F(VideoCaptureBufferPoolTest, BufferPool) {
49 const gfx::Size size_lo = gfx::Size(640, 480);
50 const gfx::Size size_hi = gfx::Size(1024, 768);
21 scoped_refptr<media::VideoFrame> non_pool_frame = 51 scoped_refptr<media::VideoFrame> non_pool_frame =
22 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size, 52 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo,
23 gfx::Rect(size), size, base::TimeDelta()); 53 gfx::Rect(size_lo), size_lo,
24 scoped_refptr<VideoCaptureBufferPool> pool = new VideoCaptureBufferPool( 54 base::TimeDelta());
25 media::VideoFrame::AllocationSize(media::VideoFrame::I420, size), 3);
26 55
27 ASSERT_EQ(460800u, pool->GetMemorySize()); 56 // Reallocation won't happen for the first part of the test.
28 ASSERT_TRUE(pool->Allocate()); 57 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
29 58
30 scoped_refptr<media::VideoFrame> frame1 = 59 scoped_refptr<media::VideoFrame> frame1 = ReserveI420VideoFrame(size_lo);
31 pool->ReserveI420VideoFrame(size, 0);
32 ASSERT_TRUE(NULL != frame1.get()); 60 ASSERT_TRUE(NULL != frame1.get());
33 ASSERT_EQ(size, frame1->coded_size()); 61 ASSERT_EQ(size_lo, frame1->coded_size());
34 scoped_refptr<media::VideoFrame> frame2 = 62 scoped_refptr<media::VideoFrame> frame2 = ReserveI420VideoFrame(size_lo);
35 pool->ReserveI420VideoFrame(size, 0);
36 ASSERT_TRUE(NULL != frame2.get()); 63 ASSERT_TRUE(NULL != frame2.get());
37 ASSERT_EQ(size, frame2->coded_size()); 64 ASSERT_EQ(size_lo, frame2->coded_size());
38 scoped_refptr<media::VideoFrame> frame3 = 65 scoped_refptr<media::VideoFrame> frame3 = ReserveI420VideoFrame(size_lo);
39 pool->ReserveI420VideoFrame(size, 0);
40 ASSERT_TRUE(NULL != frame3.get()); 66 ASSERT_TRUE(NULL != frame3.get());
41 67
42 // Touch the memory. 68 // Touch the memory.
43 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33); 69 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33);
44 media::FillYUV(frame2.get(), 0x44, 0x55, 0x66); 70 media::FillYUV(frame2.get(), 0x44, 0x55, 0x66);
45 media::FillYUV(frame3.get(), 0x77, 0x88, 0x99); 71 media::FillYUV(frame3.get(), 0x77, 0x88, 0x99);
46 72
47 // Fourth frame should fail. 73 // Fourth frame should fail.
48 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 74 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
49 << "Pool should be empty";
50 75
51 // Release 1st frame and retry; this should succeed. 76 // Release 1st frame and retry; this should succeed.
52 frame1 = NULL; 77 frame1 = NULL;
53 scoped_refptr<media::VideoFrame> frame4 = 78 scoped_refptr<media::VideoFrame> frame4 = ReserveI420VideoFrame(size_lo);
54 pool->ReserveI420VideoFrame(size, 0);
55 ASSERT_TRUE(NULL != frame4.get()); 79 ASSERT_TRUE(NULL != frame4.get());
56 80
57 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 81 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
58 << "Pool should be empty"; 82 ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty";
59 83
60 // Validate the IDs 84 // Validate the IDs
61 int buffer_id2 = 85 int buffer_id2 =
62 pool->RecognizeReservedBuffer(frame2->shared_memory_handle()); 86 pool_->RecognizeReservedBuffer(frame2->shared_memory_handle());
63 ASSERT_LE(0, buffer_id2); 87 ASSERT_EQ(1, buffer_id2);
64 int buffer_id3 = 88 int buffer_id3 =
65 pool->RecognizeReservedBuffer(frame3->shared_memory_handle()); 89 pool_->RecognizeReservedBuffer(frame3->shared_memory_handle());
66 ASSERT_LE(0, buffer_id3); 90 base::SharedMemoryHandle memory_handle3 = frame3->shared_memory_handle();
91 ASSERT_EQ(2, buffer_id3);
67 int buffer_id4 = 92 int buffer_id4 =
68 pool->RecognizeReservedBuffer(frame4->shared_memory_handle()); 93 pool_->RecognizeReservedBuffer(frame4->shared_memory_handle());
69 ASSERT_LE(0, buffer_id4); 94 ASSERT_EQ(0, buffer_id4);
70 int buffer_id_non_pool = 95 int buffer_id_non_pool =
71 pool->RecognizeReservedBuffer(non_pool_frame->shared_memory_handle()); 96 pool_->RecognizeReservedBuffer(non_pool_frame->shared_memory_handle());
72 ASSERT_GT(0, buffer_id_non_pool); 97 ASSERT_EQ(VideoCaptureBufferPool::kInvalidId, buffer_id_non_pool);
73
74 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers());
75 98
76 // Deliver a frame. 99 // Deliver a frame.
77 pool->HoldForConsumers(buffer_id3, 2); 100 pool_->HoldForConsumers(buffer_id3, 2);
78 101
79 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); 102 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
80 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 103
81 << "Pool should be empty";
82 frame3 = NULL; // Old producer releases frame. Should be a noop. 104 frame3 = NULL; // Old producer releases frame. Should be a noop.
83 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); 105 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
84 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 106 ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty";
85 << "Pool should be empty"; 107
86 frame2 = NULL; // Active producer releases frame. Should free a frame. 108 frame2 = NULL; // Active producer releases frame. Should free a frame.
87 buffer_id2 = 0;
88 109
89 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); 110 frame1 = ReserveI420VideoFrame(size_lo);
90 frame1 = pool->ReserveI420VideoFrame(size, 0);
91 ASSERT_TRUE(NULL != frame1.get()); 111 ASSERT_TRUE(NULL != frame1.get());
92 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 112 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
93 << "Pool should be empty";
94 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
95 113
96 // First consumer finishes. 114 // First consumer finishes.
97 pool->RelinquishConsumerHold(buffer_id3, 1); 115 pool_->RelinquishConsumerHold(buffer_id3, 1);
98 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 116 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
99 << "Pool should be empty";
100 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
101 117
102 // Second consumer finishes. This should free that frame. 118 // Second consumer finishes. This should free that frame.
103 pool->RelinquishConsumerHold(buffer_id3, 1); 119 pool_->RelinquishConsumerHold(buffer_id3, 1);
104 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers()); 120 frame3 = ReserveI420VideoFrame(size_lo);
105 frame3 = pool->ReserveI420VideoFrame(size, 0);
106 ASSERT_TRUE(NULL != frame3.get()); 121 ASSERT_TRUE(NULL != frame3.get());
107 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers()); 122 ASSERT_EQ(buffer_id3,
108 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 123 pool_->RecognizeReservedBuffer(frame3->shared_memory_handle()))
109 << "Pool should be empty"; 124 << "Buffer ID should be reused.";
125 ASSERT_EQ(memory_handle3, frame3->shared_memory_handle());
126 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
110 127
111 // Now deliver & consume frame1, but don't release the VideoFrame. 128 // Now deliver & consume frame1, but don't release the VideoFrame.
112 int buffer_id1 = 129 int buffer_id1 =
113 pool->RecognizeReservedBuffer(frame1->shared_memory_handle()); 130 pool_->RecognizeReservedBuffer(frame1->shared_memory_handle());
114 ASSERT_LE(0, buffer_id1); 131 ASSERT_EQ(1, buffer_id1);
115 pool->HoldForConsumers(buffer_id1, 5); 132 pool_->HoldForConsumers(buffer_id1, 5);
116 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); 133 pool_->RelinquishConsumerHold(buffer_id1, 5);
117 pool->RelinquishConsumerHold(buffer_id1, 5);
118 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers());
119 134
120 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot 135 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot
121 // be re-allocated to the producer, because |frame1| still references it. But 136 // be re-allocated to the producer, because |frame1| still references it. But
122 // when |frame1| goes away, we should be able to re-reserve the buffer (and 137 // when |frame1| goes away, we should be able to re-reserve the buffer (and
123 // the ID ought to be the same). 138 // the ID ought to be the same).
124 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 139 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
125 << "Pool should be empty";
126 frame1 = NULL; // Should free the frame. 140 frame1 = NULL; // Should free the frame.
127 frame2 = pool->ReserveI420VideoFrame(size, 0); 141 frame2 = ReserveI420VideoFrame(size_lo);
128 ASSERT_TRUE(NULL != frame2.get()); 142 ASSERT_TRUE(NULL != frame2.get());
129 ASSERT_EQ(buffer_id1, 143 ASSERT_EQ(buffer_id1,
130 pool->RecognizeReservedBuffer(frame2->shared_memory_handle())); 144 pool_->RecognizeReservedBuffer(frame2->shared_memory_handle()));
131 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 145 buffer_id2 = buffer_id1;
132 << "Pool should be empty"; 146 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
133 147
134 // For good measure, do one more cycle of free/realloc without delivery, now 148 // Now try reallocation with different resolutions. We expect reallocation
135 // that this buffer has been through the consumer-hold cycle. 149 // to occur only when the old buffer is too small.
136 frame2 = NULL; 150 frame2 = NULL;
137 frame1 = pool->ReserveI420VideoFrame(size, 0); 151 ExpectDroppedId(buffer_id2);
138 ASSERT_TRUE(NULL != frame1.get()); 152 frame2 = ReserveI420VideoFrame(size_hi);
139 ASSERT_EQ(buffer_id1, 153 ASSERT_TRUE(NULL != frame2.get());
140 pool->RecognizeReservedBuffer(frame1->shared_memory_handle())); 154 ASSERT_TRUE(frame2->coded_size() == size_hi);
141 ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) 155 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle()));
142 << "Pool should be empty"; 156 base::SharedMemoryHandle memory_handle_hi = frame2->shared_memory_handle();
157 frame2 = NULL; // Frees it.
158 ExpectDroppedId(VideoCaptureBufferPool::kInvalidId);
159 frame2 = ReserveI420VideoFrame(size_lo);
160 base::SharedMemoryHandle memory_handle_lo = frame2->shared_memory_handle();
161 ASSERT_EQ(memory_handle_hi, memory_handle_lo)
162 << "Decrease in resolution should not reallocate buffer";
163 ASSERT_TRUE(NULL != frame2.get());
164 ASSERT_TRUE(frame2->coded_size() == size_lo);
165 ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle()));
166 ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty";
143 167
144 // Tear down the pool, writing into the frames. The VideoFrame should 168 // Tear down the pool_, writing into the frames. The VideoFrame should
145 // preserve the lifetime of the underlying memory. 169 // preserve the lifetime of the underlying memory.
146 frame3 = NULL; 170 frame3 = NULL;
147 pool = NULL; 171 pool_ = NULL;
148 172
149 // Touch the memory. 173 // Touch the memory.
150 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33); 174 media::FillYUV(frame2.get(), 0x11, 0x22, 0x33);
151 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); 175 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66);
152 176
153 frame1 = NULL; 177 frame2 = NULL;
154 178
155 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); 179 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66);
156 frame4 = NULL; 180 frame4 = NULL;
157 } 181 }
158 182
159 } // namespace content 183 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698