Index: content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc |
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc b/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc |
index 30509a34c75f9c478b6582b7d2d4f76239a420c5..71a86e2b2da901f9c7740846461cd1de0be6bb5d 100644 |
--- a/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc |
+++ b/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc |
@@ -16,27 +16,51 @@ |
namespace content { |
-TEST(VideoCaptureBufferPoolTest, BufferPool) { |
- const gfx::Size size = gfx::Size(640, 480); |
+class VideoCaptureBufferPoolTest : public testing::Test { |
+ protected: |
+ VideoCaptureBufferPoolTest() |
+ : expected_dropped_id_(0), |
+ pool_(new VideoCaptureBufferPool(3)) {} |
+ |
+ void ExpectDroppedId(int expected_dropped_id) { |
+ expected_dropped_id_ = expected_dropped_id; |
+ } |
+ |
+ scoped_refptr<media::VideoFrame> ReserveI420VideoFrame( |
+ const gfx::Size& size) { |
+ int buffer_id_to_drop = ~expected_dropped_id_; |
Ami GONE FROM CHROMIUM
2013/10/04 00:24:15
o rly ~ ?
ncarter (slow)
2013/10/16 02:08:40
It's what I intended. What should I use instead? I
Ami GONE FROM CHROMIUM
2013/10/17 20:31:45
I'm not faulting your MAXIMIZATION, which is indee
|
+ scoped_refptr<media::VideoFrame> frame = |
+ pool_->ReserveI420VideoFrame(size, 0, &buffer_id_to_drop); |
+ EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop) |
+ << "Unexpected buffer reallocation result."; |
+ return frame; |
+ } |
+ |
+ int expected_dropped_id_; |
+ scoped_refptr<VideoCaptureBufferPool> pool_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(VideoCaptureBufferPoolTest); |
+}; |
+ |
+TEST_F(VideoCaptureBufferPoolTest, BufferPool) { |
+ const gfx::Size size_lo = gfx::Size(640, 480); |
+ const gfx::Size size_hi = gfx::Size(1024, 768); |
scoped_refptr<media::VideoFrame> non_pool_frame = |
- media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size, |
- gfx::Rect(size), size, base::TimeDelta()); |
- scoped_refptr<VideoCaptureBufferPool> pool = new VideoCaptureBufferPool( |
- media::VideoFrame::AllocationSize(media::VideoFrame::I420, size), 3); |
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_lo, |
+ gfx::Rect(size_lo), size_lo, |
+ base::TimeDelta()); |
- ASSERT_EQ(460800u, pool->GetMemorySize()); |
- ASSERT_TRUE(pool->Allocate()); |
+ // Reallocation won't happen for the first part of the test. |
+ ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); |
- scoped_refptr<media::VideoFrame> frame1 = |
- pool->ReserveI420VideoFrame(size, 0); |
+ scoped_refptr<media::VideoFrame> frame1 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame1.get()); |
- ASSERT_EQ(size, frame1->coded_size()); |
- scoped_refptr<media::VideoFrame> frame2 = |
- pool->ReserveI420VideoFrame(size, 0); |
+ ASSERT_EQ(size_lo, frame1->coded_size()); |
+ scoped_refptr<media::VideoFrame> frame2 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame2.get()); |
- ASSERT_EQ(size, frame2->coded_size()); |
- scoped_refptr<media::VideoFrame> frame3 = |
- pool->ReserveI420VideoFrame(size, 0); |
+ ASSERT_EQ(size_lo, frame2->coded_size()); |
+ scoped_refptr<media::VideoFrame> frame3 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame3.get()); |
// Touch the memory. |
@@ -45,112 +69,110 @@ TEST(VideoCaptureBufferPoolTest, BufferPool) { |
media::FillYUV(frame3.get(), 0x77, 0x88, 0x99); |
// Fourth frame should fail. |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
// Release 1st frame and retry; this should succeed. |
frame1 = NULL; |
- scoped_refptr<media::VideoFrame> frame4 = |
- pool->ReserveI420VideoFrame(size, 0); |
+ scoped_refptr<media::VideoFrame> frame4 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame4.get()); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty"; |
// Validate the IDs |
int buffer_id2 = |
- pool->RecognizeReservedBuffer(frame2->shared_memory_handle()); |
- ASSERT_LE(0, buffer_id2); |
+ pool_->RecognizeReservedBuffer(frame2->shared_memory_handle()); |
+ ASSERT_EQ(1, buffer_id2); |
int buffer_id3 = |
- pool->RecognizeReservedBuffer(frame3->shared_memory_handle()); |
- ASSERT_LE(0, buffer_id3); |
+ pool_->RecognizeReservedBuffer(frame3->shared_memory_handle()); |
+ base::SharedMemoryHandle memory_handle3 = frame3->shared_memory_handle(); |
+ ASSERT_EQ(2, buffer_id3); |
int buffer_id4 = |
- pool->RecognizeReservedBuffer(frame4->shared_memory_handle()); |
- ASSERT_LE(0, buffer_id4); |
+ pool_->RecognizeReservedBuffer(frame4->shared_memory_handle()); |
+ ASSERT_EQ(0, buffer_id4); |
int buffer_id_non_pool = |
- pool->RecognizeReservedBuffer(non_pool_frame->shared_memory_handle()); |
- ASSERT_GT(0, buffer_id_non_pool); |
- |
- ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers()); |
+ pool_->RecognizeReservedBuffer(non_pool_frame->shared_memory_handle()); |
+ ASSERT_EQ(VideoCaptureBufferPool::kInvalidId, buffer_id_non_pool); |
// Deliver a frame. |
- pool->HoldForConsumers(buffer_id3, 2); |
+ pool_->HoldForConsumers(buffer_id3, 2); |
+ |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
- ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
frame3 = NULL; // Old producer releases frame. Should be a noop. |
- ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_hi)) << "Pool should be empty"; |
+ |
frame2 = NULL; // Active producer releases frame. Should free a frame. |
- buffer_id2 = 0; |
- ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); |
- frame1 = pool->ReserveI420VideoFrame(size, 0); |
+ frame1 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame1.get()); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
- ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
// First consumer finishes. |
- pool->RelinquishConsumerHold(buffer_id3, 1); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
- ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); |
+ pool_->RelinquishConsumerHold(buffer_id3, 1); |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
// Second consumer finishes. This should free that frame. |
- pool->RelinquishConsumerHold(buffer_id3, 1); |
- ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers()); |
- frame3 = pool->ReserveI420VideoFrame(size, 0); |
+ pool_->RelinquishConsumerHold(buffer_id3, 1); |
+ frame3 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame3.get()); |
- ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers()); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ ASSERT_EQ(buffer_id3, |
+ pool_->RecognizeReservedBuffer(frame3->shared_memory_handle())) |
+ << "Buffer ID should be reused."; |
+ ASSERT_EQ(memory_handle3, frame3->shared_memory_handle()); |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
// Now deliver & consume frame1, but don't release the VideoFrame. |
int buffer_id1 = |
- pool->RecognizeReservedBuffer(frame1->shared_memory_handle()); |
- ASSERT_LE(0, buffer_id1); |
- pool->HoldForConsumers(buffer_id1, 5); |
- ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers()); |
- pool->RelinquishConsumerHold(buffer_id1, 5); |
- ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers()); |
+ pool_->RecognizeReservedBuffer(frame1->shared_memory_handle()); |
+ ASSERT_EQ(1, buffer_id1); |
+ pool_->HoldForConsumers(buffer_id1, 5); |
+ pool_->RelinquishConsumerHold(buffer_id1, 5); |
// Even though the consumer is done with the buffer at |buffer_id1|, it cannot |
// be re-allocated to the producer, because |frame1| still references it. But |
// when |frame1| goes away, we should be able to re-reserve the buffer (and |
// the ID ought to be the same). |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
frame1 = NULL; // Should free the frame. |
- frame2 = pool->ReserveI420VideoFrame(size, 0); |
+ frame2 = ReserveI420VideoFrame(size_lo); |
ASSERT_TRUE(NULL != frame2.get()); |
ASSERT_EQ(buffer_id1, |
- pool->RecognizeReservedBuffer(frame2->shared_memory_handle())); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); |
+ buffer_id2 = buffer_id1; |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
- // For good measure, do one more cycle of free/realloc without delivery, now |
- // that this buffer has been through the consumer-hold cycle. |
+ // Now try reallocation with different resolutions. We expect reallocation |
+ // to occur only when the old buffer is too small. |
frame2 = NULL; |
- frame1 = pool->ReserveI420VideoFrame(size, 0); |
- ASSERT_TRUE(NULL != frame1.get()); |
- ASSERT_EQ(buffer_id1, |
- pool->RecognizeReservedBuffer(frame1->shared_memory_handle())); |
- ASSERT_EQ(NULL, pool->ReserveI420VideoFrame(size, 0).get()) |
- << "Pool should be empty"; |
+ ExpectDroppedId(buffer_id2); |
+ frame2 = ReserveI420VideoFrame(size_hi); |
+ ASSERT_TRUE(NULL != frame2.get()); |
+ ASSERT_TRUE(frame2->coded_size() == size_hi); |
+ ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); |
+ base::SharedMemoryHandle memory_handle_hi = frame2->shared_memory_handle(); |
+ frame2 = NULL; // Frees it. |
+ ExpectDroppedId(VideoCaptureBufferPool::kInvalidId); |
+ frame2 = ReserveI420VideoFrame(size_lo); |
+ base::SharedMemoryHandle memory_handle_lo = frame2->shared_memory_handle(); |
+ ASSERT_EQ(memory_handle_hi, memory_handle_lo) |
+ << "Decrease in resolution should not reallocate buffer"; |
+ ASSERT_TRUE(NULL != frame2.get()); |
+ ASSERT_TRUE(frame2->coded_size() == size_lo); |
+ ASSERT_EQ(3, pool_->RecognizeReservedBuffer(frame2->shared_memory_handle())); |
+ ASSERT_FALSE(ReserveI420VideoFrame(size_lo)) << "Pool should be empty"; |
- // Tear down the pool, writing into the frames. The VideoFrame should |
+ // Tear down the pool_, writing into the frames. The VideoFrame should |
// preserve the lifetime of the underlying memory. |
frame3 = NULL; |
- pool = NULL; |
+ pool_ = NULL; |
// Touch the memory. |
- media::FillYUV(frame1.get(), 0x11, 0x22, 0x33); |
+ media::FillYUV(frame2.get(), 0x11, 0x22, 0x33); |
media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); |
- frame1 = NULL; |
+ frame2 = NULL; |
media::FillYUV(frame4.get(), 0x44, 0x55, 0x66); |
frame4 = NULL; |