|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "base/memory/scoped_ptr.h" | 
|  | #include "base/memory/shared_memory.h" | 
|  | #include "ppapi/c/pp_errors.h" | 
|  | #include "ppapi/shared_impl/media_stream_buffer_manager.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | using base::SharedMemory; | 
|  | using base::SharedMemoryCreateOptions; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | scoped_ptr<SharedMemory> CreateSharedMemory(int32_t buffer_size, | 
|  | int32_t number_of_buffers) { | 
|  | scoped_ptr<SharedMemory> shared_memory(new SharedMemory()); | 
|  | SharedMemoryCreateOptions options; | 
|  | options.size = buffer_size * number_of_buffers; | 
|  | options.executable = false; | 
|  | EXPECT_TRUE(shared_memory->Create(options)); | 
|  | return shared_memory.Pass(); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | namespace ppapi { | 
|  |  | 
|  | class MockDelegate : public MediaStreamBufferManager::Delegate { | 
|  | public: | 
|  | MockDelegate() : new_buffer_enqueue_counter_(0) {} | 
|  | void OnNewBufferEnqueued() override { | 
|  | new_buffer_enqueue_counter_++; | 
|  | } | 
|  |  | 
|  | int32_t new_buffer_enqueue_counter_; | 
|  | }; | 
|  |  | 
|  | TEST(MediaStreamBufferManager, General) { | 
|  | { | 
|  | const int32_t kNumberOfBuffers = 5; | 
|  | const int32_t kBufferSize = 128; | 
|  | MockDelegate delegate; | 
|  | MediaStreamBufferManager manager(&delegate); | 
|  | scoped_ptr<SharedMemory> shared_memory = | 
|  | CreateSharedMemory(kBufferSize, kNumberOfBuffers); | 
|  | // SetBuffers with enqueue_all_buffers = true; | 
|  | EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers, | 
|  | kBufferSize, | 
|  | shared_memory.Pass(), | 
|  | true)); | 
|  |  | 
|  | int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0)); | 
|  | EXPECT_NE(static_cast<int8_t*>(NULL), memory); | 
|  |  | 
|  | EXPECT_EQ(kNumberOfBuffers, manager.number_of_buffers()); | 
|  | EXPECT_EQ(kBufferSize, manager.buffer_size()); | 
|  |  | 
|  | // Test DequeueBuffer() and GetBufferPointer() | 
|  | for (int32_t i = 0; i < kNumberOfBuffers; ++i) { | 
|  | EXPECT_EQ(i, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize), | 
|  | manager.GetBufferPointer(i)); | 
|  | } | 
|  |  | 
|  | manager.EnqueueBuffer(0); | 
|  | manager.EnqueueBuffer(4); | 
|  | manager.EnqueueBuffer(3); | 
|  | manager.EnqueueBuffer(1); | 
|  | manager.EnqueueBuffer(2); | 
|  | EXPECT_EQ(5, delegate.new_buffer_enqueue_counter_); | 
|  |  | 
|  | EXPECT_EQ(0, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(4, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(3, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(1, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(2, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer()); | 
|  |  | 
|  | // Returns NULL for invalid index to GetBufferPointer() | 
|  | EXPECT_EQ(NULL, manager.GetBufferPointer(-1)); | 
|  | EXPECT_EQ(NULL, manager.GetBufferPointer(kNumberOfBuffers)); | 
|  |  | 
|  | // Test crash for passing invalid index to EnqueueBuffer(). | 
|  | // String arguments aren't passed to CHECK() in official builds. | 
|  | #if defined(OFFICIAL_BUILD) && defined(NDEBUG) | 
|  | EXPECT_DEATH(manager.EnqueueBuffer(-1), ""); | 
|  | EXPECT_DEATH(manager.EnqueueBuffer(kNumberOfBuffers), ""); | 
|  | #else | 
|  | EXPECT_DEATH(manager.EnqueueBuffer(-1), ".*Check failed: index >= 0.*"); | 
|  | EXPECT_DEATH(manager.EnqueueBuffer(kNumberOfBuffers), | 
|  | ".*Check failed: index < number_of_buffers_.*"); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | { | 
|  | const int32_t kNumberOfBuffers = 5; | 
|  | const int32_t kBufferSize = 128; | 
|  | MockDelegate delegate; | 
|  | MediaStreamBufferManager manager(&delegate); | 
|  | scoped_ptr<SharedMemory> shared_memory = | 
|  | CreateSharedMemory(kBufferSize, kNumberOfBuffers); | 
|  | // SetBuffers with enqueue_all_buffers = false; | 
|  | EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers, | 
|  | kBufferSize, | 
|  | shared_memory.Pass(), | 
|  | false)); | 
|  |  | 
|  | int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0)); | 
|  | EXPECT_NE(static_cast<int8_t*>(NULL), memory); | 
|  |  | 
|  | EXPECT_EQ(kNumberOfBuffers, manager.number_of_buffers()); | 
|  | EXPECT_EQ(kBufferSize, manager.buffer_size()); | 
|  |  | 
|  | // Test DequeueBuffer() and GetBufferPointer() | 
|  | for (int32_t i = 0; i < kNumberOfBuffers; ++i) { | 
|  | EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize), | 
|  | manager.GetBufferPointer(i)); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(MediaStreamBufferManager, ResetBuffers) { | 
|  | const int32_t kNumberOfBuffers1 = 5; | 
|  | const int32_t kBufferSize1 = 128; | 
|  | const int32_t kNumberOfBuffers2 = 8; | 
|  | const int32_t kBufferSize2 = 256; | 
|  | MockDelegate delegate; | 
|  | MediaStreamBufferManager manager(&delegate); | 
|  | { | 
|  | scoped_ptr<SharedMemory> shared_memory(new SharedMemory()); | 
|  | SharedMemoryCreateOptions options; | 
|  | options.size = kBufferSize1 * kNumberOfBuffers1; | 
|  | options.executable = false; | 
|  |  | 
|  | EXPECT_TRUE(shared_memory->Create(options)); | 
|  |  | 
|  | // SetBuffers with enqueue_all_buffers = true; | 
|  | EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers1, | 
|  | kBufferSize1, | 
|  | shared_memory.Pass(), | 
|  | true)); | 
|  |  | 
|  | int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0)); | 
|  | EXPECT_NE(static_cast<int8_t*>(NULL), memory); | 
|  |  | 
|  | EXPECT_EQ(kNumberOfBuffers1, manager.number_of_buffers()); | 
|  | EXPECT_EQ(kBufferSize1, manager.buffer_size()); | 
|  |  | 
|  | // Test DequeueBuffer() and GetBufferPointer() | 
|  | for (int32_t i = 0; i < kNumberOfBuffers1; ++i) { | 
|  | EXPECT_EQ(i, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize1), | 
|  | manager.GetBufferPointer(i)); | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | scoped_ptr<SharedMemory> shared_memory = | 
|  | CreateSharedMemory(kBufferSize2, kNumberOfBuffers2); | 
|  | // SetBuffers with enqueue_all_buffers = true; | 
|  | EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers2, | 
|  | kBufferSize2, | 
|  | shared_memory.Pass(), | 
|  | true)); | 
|  |  | 
|  | int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0)); | 
|  | EXPECT_NE(static_cast<int8_t*>(NULL), memory); | 
|  |  | 
|  | EXPECT_EQ(kNumberOfBuffers2, manager.number_of_buffers()); | 
|  | EXPECT_EQ(kBufferSize2, manager.buffer_size()); | 
|  |  | 
|  | // Test DequeueBuffer() and GetBufferPointer() | 
|  | for (int32_t i = 0; i < kNumberOfBuffers2; ++i) { | 
|  | EXPECT_EQ(i, manager.DequeueBuffer()); | 
|  | EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize2), | 
|  | manager.GetBufferPointer(i)); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | }  // namespace ppapi |