| 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..bc6e9651a1fb7c04c76d003569c4d9dc290357ee 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,53 @@
|
|
|
| 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) {
|
| + // To verify that ReserveI420VideoFrame always sets |buffer_id_to_drop|,
|
| + // initialize it to something different than the expected value.
|
| + int buffer_id_to_drop = ~expected_dropped_id_;
|
| + 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 +71,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;
|
|
|