1// Copyright 2014 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.
4
5#include "base/memory/scoped_ptr.h"
6#include "base/memory/shared_memory.h"
7#include "ppapi/c/pp_errors.h"
8#include "ppapi/shared_impl/media_stream_buffer_manager.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11using base::SharedMemory;
12using base::SharedMemoryCreateOptions;
13
14namespace {
15
16scoped_ptr<SharedMemory> CreateSharedMemory(int32_t buffer_size,
17                                            int32_t number_of_buffers) {
18  scoped_ptr<SharedMemory> shared_memory(new SharedMemory());
19  SharedMemoryCreateOptions options;
20  options.size = buffer_size * number_of_buffers;
21  options.executable = false;
22  EXPECT_TRUE(shared_memory->Create(options));
23  return shared_memory.Pass();
24}
25
26}  // namespace
27
28namespace ppapi {
29
30class MockDelegate : public MediaStreamBufferManager::Delegate {
31 public:
32  MockDelegate() : new_buffer_enqueue_counter_(0) {}
33  virtual void OnNewBufferEnqueued() OVERRIDE {
34    new_buffer_enqueue_counter_++;
35  }
36
37  int32_t new_buffer_enqueue_counter_;
38};
39
40TEST(MediaStreamBufferManager, General) {
41  {
42    const int32_t kNumberOfBuffers = 5;
43    const int32_t kBufferSize = 128;
44    MockDelegate delegate;
45    MediaStreamBufferManager manager(&delegate);
46    scoped_ptr<SharedMemory> shared_memory =
47        CreateSharedMemory(kBufferSize, kNumberOfBuffers);
48    // SetBuffers with enqueue_all_buffers = true;
49    EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers,
50                                   kBufferSize,
51                                   shared_memory.Pass(),
52                                   true));
53
54    int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0));
55    EXPECT_NE(static_cast<int8_t*>(NULL), memory);
56
57    EXPECT_EQ(kNumberOfBuffers, manager.number_of_buffers());
58    EXPECT_EQ(kBufferSize, manager.buffer_size());
59
60    // Test DequeueBuffer() and GetBufferPointer()
61    for (int32_t i = 0; i < kNumberOfBuffers; ++i) {
62      EXPECT_EQ(i, manager.DequeueBuffer());
63      EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize),
64                manager.GetBufferPointer(i));
65    }
66
67    manager.EnqueueBuffer(0);
68    manager.EnqueueBuffer(4);
69    manager.EnqueueBuffer(3);
70    manager.EnqueueBuffer(1);
71    manager.EnqueueBuffer(2);
72    EXPECT_EQ(5, delegate.new_buffer_enqueue_counter_);
73
74    EXPECT_EQ(0, manager.DequeueBuffer());
75    EXPECT_EQ(4, manager.DequeueBuffer());
76    EXPECT_EQ(3, manager.DequeueBuffer());
77    EXPECT_EQ(1, manager.DequeueBuffer());
78    EXPECT_EQ(2, manager.DequeueBuffer());
79    EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer());
80    EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer());
81
82    // Returns NULL for invalid index to GetBufferPointer()
83    EXPECT_EQ(NULL, manager.GetBufferPointer(-1));
84    EXPECT_EQ(NULL, manager.GetBufferPointer(kNumberOfBuffers));
85
86    // Test crash for passing invalid index to EnqueueBuffer().
87    EXPECT_DEATH(manager.EnqueueBuffer(-1),
88                 ".*Check failed: index >= 0.*");
89    EXPECT_DEATH(manager.EnqueueBuffer(kNumberOfBuffers),
90                 ".*Check failed: index < number_of_buffers_.*");
91  }
92
93  {
94    const int32_t kNumberOfBuffers = 5;
95    const int32_t kBufferSize = 128;
96    MockDelegate delegate;
97    MediaStreamBufferManager manager(&delegate);
98    scoped_ptr<SharedMemory> shared_memory =
99        CreateSharedMemory(kBufferSize, kNumberOfBuffers);
100    // SetBuffers with enqueue_all_buffers = false;
101    EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers,
102                                   kBufferSize,
103                                   shared_memory.Pass(),
104                                   false));
105
106    int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0));
107    EXPECT_NE(static_cast<int8_t*>(NULL), memory);
108
109    EXPECT_EQ(kNumberOfBuffers, manager.number_of_buffers());
110    EXPECT_EQ(kBufferSize, manager.buffer_size());
111
112    // Test DequeueBuffer() and GetBufferPointer()
113    for (int32_t i = 0; i < kNumberOfBuffers; ++i) {
114      EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer());
115      EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize),
116                manager.GetBufferPointer(i));
117    }
118  }
119}
120
121TEST(MediaStreamBufferManager, ResetBuffers) {
122  const int32_t kNumberOfBuffers1 = 5;
123  const int32_t kBufferSize1 = 128;
124  const int32_t kNumberOfBuffers2 = 8;
125  const int32_t kBufferSize2 = 256;
126  MockDelegate delegate;
127  MediaStreamBufferManager manager(&delegate);
128  {
129    scoped_ptr<SharedMemory> shared_memory(new SharedMemory());
130    SharedMemoryCreateOptions options;
131    options.size = kBufferSize1 * kNumberOfBuffers1;
132    options.executable = false;
133
134    EXPECT_TRUE(shared_memory->Create(options));
135
136    // SetBuffers with enqueue_all_buffers = true;
137    EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers1,
138                                   kBufferSize1,
139                                   shared_memory.Pass(),
140                                   true));
141
142    int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0));
143    EXPECT_NE(static_cast<int8_t*>(NULL), memory);
144
145    EXPECT_EQ(kNumberOfBuffers1, manager.number_of_buffers());
146    EXPECT_EQ(kBufferSize1, manager.buffer_size());
147
148    // Test DequeueBuffer() and GetBufferPointer()
149    for (int32_t i = 0; i < kNumberOfBuffers1; ++i) {
150      EXPECT_EQ(i, manager.DequeueBuffer());
151      EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize1),
152                manager.GetBufferPointer(i));
153    }
154  }
155
156  {
157    scoped_ptr<SharedMemory> shared_memory =
158        CreateSharedMemory(kBufferSize2, kNumberOfBuffers2);
159    // SetBuffers with enqueue_all_buffers = true;
160    EXPECT_TRUE(manager.SetBuffers(kNumberOfBuffers2,
161                                   kBufferSize2,
162                                   shared_memory.Pass(),
163                                   true));
164
165    int8_t* memory = reinterpret_cast<int8_t*>(manager.GetBufferPointer(0));
166    EXPECT_NE(static_cast<int8_t*>(NULL), memory);
167
168    EXPECT_EQ(kNumberOfBuffers2, manager.number_of_buffers());
169    EXPECT_EQ(kBufferSize2, manager.buffer_size());
170
171    // Test DequeueBuffer() and GetBufferPointer()
172    for (int32_t i = 0; i < kNumberOfBuffers2; ++i) {
173      EXPECT_EQ(i, manager.DequeueBuffer());
174      EXPECT_EQ(reinterpret_cast<MediaStreamBuffer*>(memory + i * kBufferSize2),
175                manager.GetBufferPointer(i));
176    }
177  }
178}
179
180}  // namespace ppapi
181