Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_buffer_pool_unittest.cc
blob60d5881809b6e42f2cce6c8d88a2356793d9ed74
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
3 // found in the LICENSE file.
5 // Unit test for VideoCaptureBufferPool.
7 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "media/base/video_frame.h"
12 #include "media/base/video_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace content {
17 TEST(VideoCaptureBufferPoolTest, BufferPool) {
18 const gfx::Size size = gfx::Size(640, 480);
19 scoped_refptr<media::VideoFrame> non_pool_frame =
20 media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size,
21 gfx::Rect(size), size, base::TimeDelta());
22 scoped_refptr<VideoCaptureBufferPool> pool =
23 new VideoCaptureBufferPool(size, 3);
25 ASSERT_EQ(460800u, pool->GetMemorySize());
27 ASSERT_TRUE(pool->Allocate());
28 scoped_refptr<media::VideoFrame> frame1 = pool->ReserveForProducer(0);
29 ASSERT_TRUE(NULL != frame1.get());
30 ASSERT_EQ(size, frame1->coded_size());
31 scoped_refptr<media::VideoFrame> frame2 = pool->ReserveForProducer(0);
32 ASSERT_TRUE(NULL != frame2.get());
33 ASSERT_EQ(size, frame2->coded_size());
34 scoped_refptr<media::VideoFrame> frame3 = pool->ReserveForProducer(0);
35 ASSERT_TRUE(NULL != frame3.get());
37 // Touch the memory.
38 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33);
39 media::FillYUV(frame2.get(), 0x44, 0x55, 0x66);
40 media::FillYUV(frame3.get(), 0x77, 0x88, 0x99);
42 // Fourth frame should fail.
43 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
45 // Release 1st frame and retry; this should succeed.
46 frame1 = NULL;
47 scoped_refptr<media::VideoFrame> frame4 = pool->ReserveForProducer(0);
48 ASSERT_TRUE(NULL != frame4.get());
50 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
52 // Validate the IDs
53 int buffer_id2 = pool->RecognizeReservedBuffer(frame2);
54 ASSERT_NE(0, buffer_id2);
55 int buffer_id3 = pool->RecognizeReservedBuffer(frame3);
56 ASSERT_NE(0, buffer_id3);
57 int buffer_id4 = pool->RecognizeReservedBuffer(frame4);
58 ASSERT_NE(0, buffer_id4);
59 int buffer_id_non_pool = pool->RecognizeReservedBuffer(non_pool_frame);
60 ASSERT_EQ(0, buffer_id_non_pool);
62 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers());
64 // Deliver a frame.
65 pool->HoldForConsumers(frame3, buffer_id3, 2);
67 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
68 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
69 frame3 = NULL; // Old producer releases frame. Should be a noop.
70 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
71 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
72 frame2 = NULL; // Active producer releases frame. Should free a frame.
73 buffer_id2 = 0;
75 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
76 frame1 = pool->ReserveForProducer(0);
77 ASSERT_TRUE(NULL != frame1.get());
78 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
79 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
81 // First consumer finishes.
82 pool->RelinquishConsumerHold(buffer_id3, 1);
83 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
84 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
86 // Second consumer finishes. This should free that frame.
87 pool->RelinquishConsumerHold(buffer_id3, 1);
88 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers());
89 frame3 = pool->ReserveForProducer(0);
90 ASSERT_TRUE(NULL != frame3.get());
91 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers());
92 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
94 // Now deliver & consume frame1, but don't release the VideoFrame.
95 int buffer_id1 = pool->RecognizeReservedBuffer(frame1);
96 ASSERT_NE(0, buffer_id1);
97 pool->HoldForConsumers(frame1, buffer_id1, 5);
98 ASSERT_TRUE(pool->IsAnyBufferHeldForConsumers());
99 pool->RelinquishConsumerHold(buffer_id1, 5);
100 ASSERT_FALSE(pool->IsAnyBufferHeldForConsumers());
102 // Even though the consumer is done with the buffer at |buffer_id1|, it cannot
103 // be re-allocated to the producer, because |frame1| still references it. But
104 // when |frame1| goes away, we should be able to re-reserve the buffer (and
105 // the ID ought to be the same).
106 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
107 frame1 = NULL; // Should free the frame.
108 frame2 = pool->ReserveForProducer(0);
109 ASSERT_TRUE(NULL != frame2.get());
110 ASSERT_EQ(buffer_id1, pool->RecognizeReservedBuffer(frame2));
111 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
113 // For good measure, do one more cycle of free/realloc without delivery, now
114 // that this buffer has been through the consumer-hold cycle.
115 frame2 = NULL;
116 frame1 = pool->ReserveForProducer(0);
117 ASSERT_TRUE(NULL != frame1.get());
118 ASSERT_EQ(buffer_id1, pool->RecognizeReservedBuffer(frame1));
119 ASSERT_EQ(NULL, pool->ReserveForProducer(0).get()) << "Pool should be empty";
121 // Tear down the pool, writing into the frames. The VideoFrame should
122 // preserve the lifetime of the underlying memory.
123 frame3 = NULL;
124 pool = NULL;
126 // Touch the memory.
127 media::FillYUV(frame1.get(), 0x11, 0x22, 0x33);
128 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66);
130 frame1 = NULL;
132 media::FillYUV(frame4.get(), 0x44, 0x55, 0x66);
133 frame4 = NULL;
136 } // namespace content