Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: media/omx/omx_codec_unittest.cc

Issue 2397001: enable omx_codec_unittest based on new omx engine (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: more codereview Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #define _CRT_SECURE_NO_WARNINGS 5 #define _CRT_SECURE_NO_WARNINGS
6 6
7 #include <deque> 7 #include <deque>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/task.h"
12 #include "media/base/buffers.h"
11 #include "media/base/mock_filters.h" 13 #include "media/base/mock_filters.h"
14 #include "media/base/mock_task.h"
15 #include "media/ffmpeg/ffmpeg_common.h"
16 #include "media/filters/omx_video_decode_engine.h"
17 #include "media/filters/video_decode_engine.h"
12 #include "media/omx/mock_omx.h" 18 #include "media/omx/mock_omx.h"
13 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
14 20
15 using ::testing::_; 21 using ::testing::_;
16 using ::testing::DoAll; 22 using ::testing::DoAll;
17 using ::testing::InSequence; 23 using ::testing::InSequence;
18 using ::testing::IsNull; 24 using ::testing::IsNull;
19 using ::testing::NotNull; 25 using ::testing::NotNull;
20 using ::testing::Return; 26 using ::testing::Return;
21 using ::testing::SaveArg; 27 using ::testing::SaveArg;
22 using ::testing::SetArgumentPointee; 28 using ::testing::SetArgumentPointee;
23 using ::testing::StrEq; 29 using ::testing::StrEq;
24 using ::testing::StrictMock; 30 using ::testing::StrictMock;
25 31
26 // Temporarily disable omx_codec_unittests during heavy refactoring.
27 #if 0
28 namespace { 32 namespace {
29 33
30 const int kBufferCount = 3; 34 const int kBufferCount = 3;
31 const int kBufferSize = 4096; 35 const int kBufferSize = 4096;
32 const char* kRoleName = "awsome"; 36 const char* kComponentName = "OMX.google.video_decoder.avc";
33 const char* kComponentName = "OMX.google.mock.awsome";
34 37
35 } // namespace 38 } // namespace
36 39
37 namespace media { 40 namespace media {
38
39 ACTION(ReturnComponentName) { 41 ACTION(ReturnComponentName) {
40 strcpy(((char**)arg2)[0], kComponentName); 42 strcpy(((char**)arg2)[0], kComponentName);
41 } 43 }
42 44
43 ACTION(GetHandle) { 45 ACTION(GetHandle) {
44 *arg0 = MockOmx::get()->component(); 46 *arg0 = MockOmx::get()->component();
45 MockOmx::get()->component()->pApplicationPrivate = arg2; 47 MockOmx::get()->component()->pApplicationPrivate = arg2;
46 memcpy(MockOmx::get()->callbacks(), arg3, sizeof(OMX_CALLBACKTYPE)); 48 memcpy(MockOmx::get()->callbacks(), arg3, sizeof(OMX_CALLBACKTYPE));
47 } 49 }
48 50
49 ACTION(GetParameterVideoInit) { 51 ACTION(GetParameterVideoInit) {
50 ((OMX_PORT_PARAM_TYPE*)arg1)->nStartPortNumber = 0; 52 ((OMX_PORT_PARAM_TYPE*)arg1)->nStartPortNumber = 0;
51 } 53 }
52 54
53 ACTION(GetParameterPortDefinition) { 55 ACTION(GetParameterPortDefinition) {
54 OMX_PARAM_PORTDEFINITIONTYPE* port_format = 56 OMX_PARAM_PORTDEFINITIONTYPE* port_format =
55 (OMX_PARAM_PORTDEFINITIONTYPE*)arg1; 57 (OMX_PARAM_PORTDEFINITIONTYPE*)arg1;
56 CHECK(port_format->nPortIndex == 0 || port_format->nPortIndex == 1); 58 CHECK(port_format->nPortIndex == 0 || port_format->nPortIndex == 1);
57 if (port_format->nPortIndex == 0) 59 if (port_format->nPortIndex == 0)
58 port_format->eDir = OMX_DirInput; 60 port_format->eDir = OMX_DirInput;
59 else 61 else
60 port_format->eDir = OMX_DirOutput; 62 port_format->eDir = OMX_DirOutput;
61 port_format->nBufferCountMin = kBufferCount; 63 port_format->nBufferCountMin = kBufferCount;
64 port_format->nBufferCountActual = kBufferCount;
62 port_format->nBufferSize = kBufferSize; 65 port_format->nBufferSize = kBufferSize;
63 } 66 }
64 67
65 ACTION(AllocateBuffer) { 68 ACTION(AllocateBuffer) {
66 *arg0 = new OMX_BUFFERHEADERTYPE(); 69 *arg0 = new OMX_BUFFERHEADERTYPE();
67 memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE)); 70 memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE));
68 (*arg0)->pBuffer = new uint8[kBufferSize]; 71 (*arg0)->nAllocLen = arg3;
72 (*arg0)->pBuffer = new uint8[arg3];
73 (*arg0)->nOutputPortIndex = 1;
74 (*arg0)->nInputPortIndex = OMX_ALL;
69 } 75 }
70 76
71 ACTION(UseBuffer) { 77 ACTION(UseBuffer) {
72 *arg0 = new OMX_BUFFERHEADERTYPE(); 78 *arg0 = new OMX_BUFFERHEADERTYPE();
73 memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE)); 79 memset(*arg0, 0, sizeof(OMX_BUFFERHEADERTYPE));
80 (*arg0)->nOutputPortIndex = OMX_ALL;
81 (*arg0)->nInputPortIndex = 0;
74 } 82 }
75 83
76 ACTION(FreeBuffer) { 84 ACTION(FreeBuffer) {
77 delete [] arg1->pBuffer; 85 if (1 == arg1->nOutputPortIndex)
86 delete [] arg1->pBuffer;
78 delete arg1; 87 delete arg1;
79 } 88 }
80 89
81 ACTION_P2(SendEvent, event, data1) { 90 ACTION_P3(SendEvent, event, data1, data2) {
82 // TODO(hclam): pass data2 and event data.
83 (*MockOmx::get()->callbacks()->EventHandler)( 91 (*MockOmx::get()->callbacks()->EventHandler)(
84 MockOmx::get()->component(), 92 MockOmx::get()->component(),
85 MockOmx::get()->component()->pApplicationPrivate, 93 MockOmx::get()->component()->pApplicationPrivate,
86 event, static_cast<OMX_U32>(data1), 0, NULL); 94 event, static_cast<OMX_U32>(data1), static_cast<OMX_U32>(data2), NULL);
87 } 95 }
88 96
89 ACTION(FillBuffer) { 97 ACTION_P(EmptyBufferDone, output_pool_ptr) {
90 arg0->nFlags = 0; 98 (*MockOmx::get()->callbacks()->EmptyBufferDone)(
91 arg0->nFilledLen = kBufferSize; 99 MockOmx::get()->component(),
100 MockOmx::get()->component()->pApplicationPrivate,
101 arg0);
102 OMX_BUFFERHEADERTYPE* out_buffer = output_pool_ptr->front();
103 output_pool_ptr->pop_front();
104 if (arg0->nFlags & OMX_BUFFERFLAG_EOS)
105 out_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
106 out_buffer->nFilledLen = kBufferSize;
92 (*MockOmx::get()->callbacks()->FillBufferDone)( 107 (*MockOmx::get()->callbacks()->FillBufferDone)(
93 MockOmx::get()->component(), 108 MockOmx::get()->component(),
94 MockOmx::get()->component()->pApplicationPrivate, 109 MockOmx::get()->component()->pApplicationPrivate,
95 arg0); 110 out_buffer);
111 }
112
113 ACTION_P(EnqueueOutputBuffer, output_pool_ptr) {
114 output_pool_ptr->push_back(arg0);
96 } 115 }
97 116
98 ACTION(FillEosBuffer) { 117 ACTION(FillEosBuffer) {
99 arg0->nFlags = OMX_BUFFERFLAG_EOS; 118 arg0->nFlags = OMX_BUFFERFLAG_EOS;
100 arg0->nFilledLen = 0; 119 arg0->nFilledLen = 0;
101 (*MockOmx::get()->callbacks()->FillBufferDone)( 120 (*MockOmx::get()->callbacks()->FillBufferDone)(
102 MockOmx::get()->component(), 121 MockOmx::get()->component(),
103 MockOmx::get()->component()->pApplicationPrivate, 122 MockOmx::get()->component()->pApplicationPrivate,
104 arg0); 123 arg0);
105 } 124 }
106 125
107 class MockOmxConfigurator : public OmxConfigurator { 126 class TestBuffer : public media::Buffer {
108 public: 127 public:
109 MockOmxConfigurator() 128 TestBuffer() : size_(0), data_(NULL) { }
110 : OmxConfigurator(MediaFormat(), MediaFormat()) {} 129 explicit TestBuffer(int size) : size_(size) {
130 if (size)
131 data_.reset(new uint8[size]);
132 else
133 data_.reset(NULL);
134 }
135 virtual const uint8* GetData() const {
136 return data_.get();
137 }
138 virtual size_t GetDataSize() const {
139 return size_;
140 }
141 private:
142 virtual ~TestBuffer() { }
111 143
112 MOCK_CONST_METHOD0(GetRoleName, std::string()); 144 int size_;
113 MOCK_CONST_METHOD3(ConfigureIOPorts, 145 scoped_array<uint8> data_;
114 bool(OMX_COMPONENTTYPE* component, 146 DISALLOW_COPY_AND_ASSIGN(TestBuffer);
115 OMX_PARAM_PORTDEFINITIONTYPE* input_fef,
116 OMX_PARAM_PORTDEFINITIONTYPE* output_def));
117 }; 147 };
118 148
119 class OmxCodecTest : public testing::Test { 149 class OmxCodecTest : public testing::Test {
120 public: 150 public:
121 OmxCodecTest () 151 OmxCodecTest ()
122 : omx_codec_(new OmxCodec(&message_loop_)) { 152 : got_eos_(false),
123 omx_codec_->Setup(&mock_configurator_); 153 omx_engine_(new OmxVideoDecodeEngine()) {
154 av_stream_.codec = &av_codec_context_;
155 av_codec_context_.width = 16;
156 av_codec_context_.height = 16;
157 feed_done_cb_ =
158 NewCallback(this, &OmxCodecTest::EmptyBufferDoneCallback);
159 decode_done_cb_ =
160 NewCallback(this, &OmxCodecTest::FillBufferDoneCallback);
124 } 161 }
125 162
126 ~OmxCodecTest() { 163 ~OmxCodecTest() {
127 CHECK(output_units_.size() == 0);
128 } 164 }
129 165
130 protected: 166 protected:
131 void ExpectSettings() { 167 void ExpectSettings() {
132 // Return the component name. 168 // Return the component name.
133 EXPECT_CALL(*MockOmx::get(), GetComponentsOfRole(_, _, IsNull())) 169 EXPECT_CALL(*MockOmx::get(), GetComponentsOfRole(_, _, IsNull()))
134 .WillOnce(DoAll(SetArgumentPointee<1>(1), 170 .WillOnce(DoAll(SetArgumentPointee<1>(1),
135 Return(OMX_ErrorNone))); 171 Return(OMX_ErrorNone)));
136 EXPECT_CALL(*MockOmx::get(), GetComponentsOfRole(_, _, NotNull())) 172 EXPECT_CALL(*MockOmx::get(), GetComponentsOfRole(_, _, NotNull()))
137 .WillOnce(DoAll(SetArgumentPointee<1>(1), 173 .WillOnce(DoAll(SetArgumentPointee<1>(1),
138 ReturnComponentName(), 174 ReturnComponentName(),
139 Return(OMX_ErrorNone))); 175 Return(OMX_ErrorNone)));
140 176
141 // Handle get parameter calls. 177 // Handle get parameter calls.
142 EXPECT_CALL(*MockOmx::get(), 178 EXPECT_CALL(*MockOmx::get(),
143 GetParameter(OMX_IndexParamVideoInit, NotNull())) 179 GetParameter(OMX_IndexParamVideoInit, NotNull()))
144 .WillRepeatedly(DoAll(GetParameterVideoInit(), Return(OMX_ErrorNone))); 180 .WillRepeatedly(DoAll(GetParameterVideoInit(), Return(OMX_ErrorNone)));
145 EXPECT_CALL(*MockOmx::get(), 181 EXPECT_CALL(*MockOmx::get(),
146 GetParameter(OMX_IndexParamPortDefinition, NotNull())) 182 GetParameter(OMX_IndexParamPortDefinition, NotNull()))
147 .WillRepeatedly(DoAll(GetParameterPortDefinition(), 183 .WillRepeatedly(DoAll(GetParameterPortDefinition(),
148 Return(OMX_ErrorNone))); 184 Return(OMX_ErrorNone)));
149 185
150 // Ignore all set parameter calls. 186 // Ignore all set parameter calls.
151 EXPECT_CALL(*MockOmx::get(), SetParameter(_, _)) 187 EXPECT_CALL(*MockOmx::get(), SetParameter(_, _))
152 .WillRepeatedly(Return(OMX_ErrorNone)); 188 .WillRepeatedly(Return(OMX_ErrorNone));
153
154 // Expect calling to configurator once.
155 EXPECT_CALL(mock_configurator_,
156 ConfigureIOPorts(MockOmx::get()->component(), _, _))
157 .WillOnce(Return(true));
158
159 EXPECT_CALL(mock_configurator_, GetRoleName())
160 .WillRepeatedly(Return(kRoleName));
161 } 189 }
162 190
163 void ExpectToLoaded() { 191 void ExpectToLoaded() {
164 InSequence s; 192 InSequence s;
165 193
166 // Expect initialization. 194 // Expect initialization.
167 EXPECT_CALL(*MockOmx::get(), Init()) 195 EXPECT_CALL(*MockOmx::get(), Init())
168 .WillOnce(Return(OMX_ErrorNone)); 196 .WillOnce(Return(OMX_ErrorNone));
169 197
170 // Return the handle. 198 // Return the handle.
171 EXPECT_CALL(*MockOmx::get(), 199 EXPECT_CALL(*MockOmx::get(),
172 GetHandle(NotNull(), StrEq(kComponentName), 200 GetHandle(NotNull(), StrEq(kComponentName),
173 NotNull(), NotNull())) 201 NotNull(), NotNull()))
174 .WillOnce(DoAll(GetHandle(), 202 .WillOnce(DoAll(GetHandle(),
175 Return(OMX_ErrorNone))); 203 Return(OMX_ErrorNone)));
176 } 204 }
177 205
178 void ExpectLoadedToIdle() { 206 void ExpectLoadedToIdle() {
179 InSequence s; 207 InSequence s;
180 208
181 // Expect transition to idle. 209 // Expect transition to idle.
182 EXPECT_CALL(*MockOmx::get(), 210 EXPECT_CALL(*MockOmx::get(),
183 SendCommand(OMX_CommandStateSet, OMX_StateIdle, _)) 211 SendCommand(OMX_CommandStateSet, OMX_StateIdle, _))
184 .WillOnce( 212 .WillOnce(
185 DoAll( 213 DoAll(
186 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet), 214 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
215 OMX_StateIdle),
187 Return(OMX_ErrorNone))); 216 Return(OMX_ErrorNone)));
188 217
189 // Expect allocation of buffers. 218 // Expect allocation of buffers.
190 EXPECT_CALL(*MockOmx::get(), 219 EXPECT_CALL(*MockOmx::get(),
191 UseBuffer(NotNull(), 0, IsNull(), kBufferSize, _)) 220 UseBuffer(NotNull(), 0, NotNull(), kBufferSize, _))
192 .Times(kBufferCount) 221 .Times(kBufferCount)
193 .WillRepeatedly(DoAll(UseBuffer(), Return(OMX_ErrorNone))); 222 .WillRepeatedly(DoAll(UseBuffer(), Return(OMX_ErrorNone)));
194 223
195 // Expect allocation of output buffers and send command complete. 224 // Expect allocation of output buffers and send command complete.
196 EXPECT_CALL(*MockOmx::get(), 225 EXPECT_CALL(*MockOmx::get(),
197 AllocateBuffer(NotNull(), 1, IsNull(), kBufferSize)) 226 AllocateBuffer(NotNull(), 1, IsNull(), kBufferSize))
198 .Times(kBufferCount) 227 .Times(kBufferCount)
199 .WillRepeatedly(DoAll(AllocateBuffer(), Return(OMX_ErrorNone))); 228 .WillRepeatedly(DoAll(AllocateBuffer(), Return(OMX_ErrorNone)));
200 } 229 }
201 230
202 void ExpectToExecuting() { 231 void ExpectToExecuting() {
203 InSequence s; 232 InSequence s;
204 233
205 // Expect transition to executing. 234 // Expect transition to executing.
206 EXPECT_CALL(*MockOmx::get(), 235 EXPECT_CALL(*MockOmx::get(),
207 SendCommand(OMX_CommandStateSet, OMX_StateExecuting, _)) 236 SendCommand(OMX_CommandStateSet, OMX_StateExecuting, _))
208 .WillOnce(DoAll( 237 .WillOnce(DoAll(
209 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet), 238 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
239 OMX_StateExecuting),
210 Return(OMX_ErrorNone))); 240 Return(OMX_ErrorNone)));
211 241
212 // Expect initial FillThisBuffer() calls. 242 // Expect initial FillThisBuffer() calls.
213 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull())) 243 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
214 .Times(kBufferCount) 244 .Times(kBufferCount)
215 .WillRepeatedly(DoAll(FillBuffer(), Return(OMX_ErrorNone))); 245 .WillRepeatedly(DoAll(EnqueueOutputBuffer(&output_pool_),
246 Return(OMX_ErrorNone)));
216 } 247 }
217 248
218 void ExpectToIdle() { 249 void ExpectToIdle() {
219 // Expect going to idle 250 // Expect going to idle
220 EXPECT_CALL(*MockOmx::get(), 251 EXPECT_CALL(*MockOmx::get(),
221 SendCommand(OMX_CommandStateSet, OMX_StateIdle, _)) 252 SendCommand(OMX_CommandStateSet, OMX_StateIdle, _))
222 .WillOnce(DoAll( 253 .WillOnce(DoAll(
223 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet), 254 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet, OMX_StateIdle),
224 Return(OMX_ErrorNone))); 255 Return(OMX_ErrorNone)));
225 } 256 }
226 257
227 void ExpectIdleToLoaded() { 258 void ExpectIdleToLoaded() {
228 InSequence s; 259 InSequence s;
229 260
230 // Expect transition to loaded. 261 // Expect transition to loaded.
231 EXPECT_CALL(*MockOmx::get(), 262 EXPECT_CALL(*MockOmx::get(),
232 SendCommand(OMX_CommandStateSet, OMX_StateLoaded, _)) 263 SendCommand(OMX_CommandStateSet, OMX_StateLoaded, _))
233 .WillOnce(DoAll( 264 .WillOnce(DoAll(
234 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet), 265 SendEvent(OMX_EventCmdComplete, OMX_CommandStateSet,
266 OMX_StateLoaded),
235 Return(OMX_ErrorNone))); 267 Return(OMX_ErrorNone)));
236 268
237 // Expect free buffer for input port. 269 // Expect free buffer for input port.
238 EXPECT_CALL(*MockOmx::get(), FreeBuffer(0, NotNull())) 270 EXPECT_CALL(*MockOmx::get(), FreeBuffer(0, NotNull()))
239 .Times(kBufferCount) 271 .Times(kBufferCount)
240 .WillRepeatedly(DoAll(FreeBuffer(), Return(OMX_ErrorNone))); 272 .WillRepeatedly(DoAll(FreeBuffer(), Return(OMX_ErrorNone)));
241 273
242 EXPECT_CALL(*MockOmx::get(), FreeBuffer(1, NotNull())) 274 EXPECT_CALL(*MockOmx::get(), FreeBuffer(1, NotNull()))
243 .Times(kBufferCount) 275 .Times(kBufferCount)
244 .WillRepeatedly(DoAll(FreeBuffer(), Return(OMX_ErrorNone))); 276 .WillRepeatedly(DoAll(FreeBuffer(), Return(OMX_ErrorNone)));
245 } 277 }
246 278
247 void ExpectToEmpty() { 279 void ExpectToEmpty() {
248 InSequence s; 280 InSequence s;
249 281
250 EXPECT_CALL(*MockOmx::get(), FreeHandle(MockOmx::get()->component())) 282 EXPECT_CALL(*MockOmx::get(), FreeHandle(MockOmx::get()->component()))
251 .WillOnce(Return(OMX_ErrorNone)); 283 .WillOnce(Return(OMX_ErrorNone));
252 EXPECT_CALL(*MockOmx::get(), Deinit()) 284 EXPECT_CALL(*MockOmx::get(), Deinit())
253 .WillOnce(Return(OMX_ErrorNone)); 285 .WillOnce(Return(OMX_ErrorNone));
254 } 286 }
255 287
256 // TODO(hclam): Make a more generic about when to stop. 288 // TODO(hclam): Make a more generic about when to stop.
257 void ExpectStart() { 289 void ExpectStart() {
258 ExpectToLoaded(); 290 ExpectToLoaded();
259 ExpectLoadedToIdle(); 291 ExpectLoadedToIdle();
260 ExpectToExecuting(); 292 ExpectToExecuting();
293 EXPECT_CALL(init_done_cb_task_, Run());
261 } 294 }
262 295
263 void ExpectStop() { 296 void ExpectStop() {
297 EXPECT_CALL(stop_callback_, OnFilterCallback());
298 EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
264 ExpectToIdle(); 299 ExpectToIdle();
265 ExpectIdleToLoaded(); 300 ExpectIdleToLoaded();
266 ExpectToEmpty(); 301 ExpectToEmpty();
267 } 302 }
268 303
269 void ReadCallback(OMX_BUFFERHEADERTYPE* buffer) { 304 void EmptyBufferDoneCallback(scoped_refptr<Buffer> buffer) {
270 output_units_.push_back(buffer); 305 input_units_.push_back(buffer);
271 } 306 }
272 307
273 void MakeReadRequest() { 308 void FillBufferDoneCallback(scoped_refptr<VideoFrame> frame) {
274 omx_codec_->Read(NewCallback(this, &OmxCodecTest::ReadCallback)); 309 output_units_.push_back(frame);
310 if (frame.get() == NULL)
311 got_eos_ = true;
275 } 312 }
276 313
277 void SaveFillThisBuffer(OMX_BUFFERHEADERTYPE* buffer) { 314 void InitializeInputBuffers(int count) {
278 fill_this_buffer_received_.push_back(buffer); 315 for (int i = 0; i < count; ++i) {
316 scoped_refptr<Buffer> buffer_ref = new TestBuffer(i + 1);
317 input_units_.push_back(buffer_ref);
318 }
279 } 319 }
280 320
281 void ExpectAndSaveFillThisBuffer() { 321 void MakeEmptyBufferRequest() {
282 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull())) 322 scoped_refptr<Buffer> buffer = input_units_.front();
283 .WillOnce(DoAll(Invoke(this, &OmxCodecTest::SaveFillThisBuffer), 323 input_units_.pop_front();
284 Return(OMX_ErrorNone))) 324 omx_engine_->EmptyThisBuffer(buffer);
285 .RetiresOnSaturation();
286 } 325 }
287 326
288 std::deque<OMX_BUFFERHEADERTYPE*> output_units_; 327 void SendEOSInputBuffer() {
328 input_units_.pop_front();
329 scoped_refptr<Buffer> buffer_ref = new TestBuffer();
330 input_units_.push_front(buffer_ref);
331 EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
332 .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
333 .RetiresOnSaturation();
334 MakeEmptyBufferRequest();
335 message_loop_.RunAllPending();
336 }
337
338 std::deque<scoped_refptr<Buffer> > input_units_;
339 std::deque<scoped_refptr<VideoFrame> > output_units_;
289 std::deque<OMX_BUFFERHEADERTYPE*> fill_this_buffer_received_; 340 std::deque<OMX_BUFFERHEADERTYPE*> fill_this_buffer_received_;
341 std::deque<OMX_BUFFERHEADERTYPE*> output_pool_;
290 342
291 MockOmx mock_omx_; 343 MockOmx mock_omx_;
292 MockOmxConfigurator mock_configurator_;
293 344
345 bool got_eos_;
294 MessageLoop message_loop_; 346 MessageLoop message_loop_;
295 scoped_refptr<OmxCodec> omx_codec_; 347 scoped_refptr<OmxVideoDecodeEngine> omx_engine_;
348
349 AVStream av_stream_;
350 AVCodecContext av_codec_context_;
351
352 VideoDecodeEngine::EmptyThisBufferCallback* feed_done_cb_;
353 VideoDecodeEngine::FillThisBufferCallback* decode_done_cb_;
354 TaskMocker init_done_cb_task_;
296 355
297 MockFilterCallback stop_callback_; 356 MockFilterCallback stop_callback_;
298 357
299 private: 358 private:
300 DISALLOW_COPY_AND_ASSIGN(OmxCodecTest); 359 DISALLOW_COPY_AND_ASSIGN(OmxCodecTest);
301 }; 360 };
302 361
303 TEST_F(OmxCodecTest, SimpleStartAndStop) { 362 TEST_F(OmxCodecTest, SimpleStartAndStop) {
304 ExpectSettings(); 363 ExpectSettings();
305 ExpectStart(); 364 ExpectStart();
306 omx_codec_->Start(); 365 omx_engine_->Initialize(&message_loop_,
366 &av_stream_,
367 feed_done_cb_,
368 decode_done_cb_,
369 init_done_cb_task_.CreateTask());
307 message_loop_.RunAllPending(); 370 message_loop_.RunAllPending();
308 371
309 EXPECT_CALL(stop_callback_, OnFilterCallback()); 372 EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
310 EXPECT_CALL(stop_callback_, OnCallbackDestroyed()); 373
311 ExpectStop(); 374 ExpectStop();
312 omx_codec_->Stop(stop_callback_.NewCallback()); 375 omx_engine_->Stop(stop_callback_.NewCallback());
313 message_loop_.RunAllPending(); 376 message_loop_.RunAllPending();
314 } 377 }
315 378
316 TEST_F(OmxCodecTest, EndOfStream) { 379 TEST_F(OmxCodecTest, NormalFlow) {
317 ExpectSettings(); 380 ExpectSettings();
318 ExpectStart(); 381 ExpectStart();
319 omx_codec_->Start(); 382 omx_engine_->Initialize(&message_loop_,
383 &av_stream_,
384 feed_done_cb_,
385 decode_done_cb_,
386 init_done_cb_task_.CreateTask());
320 message_loop_.RunAllPending(); 387 message_loop_.RunAllPending();
321 388
322 // Make read requests, OmxCodec should have gotten kBufferCount 389 EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
323 // buffers already. 390
391 // Allocate bitstream buffers.
392 InitializeInputBuffers(kBufferCount);
393
394 // Make emptybuffer requests.
324 EXPECT_EQ(0u, output_units_.size()); 395 EXPECT_EQ(0u, output_units_.size());
396 int count = output_pool_.size();
325 for (int i = 0; i < kBufferCount; ++i) { 397 for (int i = 0; i < kBufferCount; ++i) {
326 // Give buffers back to OmxCodec. OmxCodec will make a new 398 // Give input buffers to OmxVideoDecodeEngine. OmxVideoDecodeEngine will
327 // FillThisBuffer() call for each read. 399 // make a new FillThisBuffer() call for each read.
400 EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
401 .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
402 .RetiresOnSaturation();
328 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull())) 403 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
329 .WillOnce(DoAll(FillEosBuffer(), Return(OMX_ErrorNone))) 404 .WillOnce(DoAll(EnqueueOutputBuffer(&output_pool_),
405 Return(OMX_ErrorNone)))
330 .RetiresOnSaturation(); 406 .RetiresOnSaturation();
331 MakeReadRequest(); 407 MakeEmptyBufferRequest();
332 } 408 }
333 message_loop_.RunAllPending(); 409 message_loop_.RunAllPending();
334 CHECK(kBufferCount == static_cast<int>(output_units_.size())); 410 EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
335 411 EXPECT_EQ(kBufferCount, static_cast<int>(output_units_.size()));
336 // Make sure buffers received are in order. 412 EXPECT_EQ(count, static_cast<int>(output_pool_.size()));
337 for (int i = 0; i < kBufferCount; ++i) {
338 // TODO(jiesun): How to verify this now?
339 // EXPECT_EQ(i, output_units_[i].first);
340 EXPECT_TRUE(output_units_[i] != NULL);
341 }
342
343 output_units_.clear(); 413 output_units_.clear();
344 414
345 // Make some read requests and make sure end-of-stream buffer id 415 // Send EndOfStream, expect eos flag.
346 // are received. 416 SendEOSInputBuffer();
347 EXPECT_EQ(0u, output_units_.size()); 417 EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
348 for (int i = 0; i < 2 * kBufferCount; ++i) { 418 EXPECT_EQ(1, static_cast<int>(output_units_.size()));
349 MakeReadRequest(); 419 EXPECT_EQ(count-1, static_cast<int>(output_pool_.size()));
350 } 420 EXPECT_EQ(true, got_eos_);
351 message_loop_.RunAllPending();
352 EXPECT_EQ(2 * kBufferCount, static_cast<int>(output_units_.size()));
353 421
354 for (size_t i = 0; i <output_units_.size(); ++i) { 422 // Shutdown.
355 EXPECT_EQ(NULL, output_units_[i]);
356 }
357 output_units_.clear();
358
359 // Stop OmxCodec.
360 EXPECT_CALL(stop_callback_, OnFilterCallback());
361 EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
362 ExpectStop(); 423 ExpectStop();
363 omx_codec_->Stop(stop_callback_.NewCallback()); 424 omx_engine_->Stop(stop_callback_.NewCallback());
364 message_loop_.RunAllPending(); 425 message_loop_.RunAllPending();
365 } 426 }
366 427
367 TEST_F(OmxCodecTest, OutputFlowControl) { 428 TEST_F(OmxCodecTest, RecycleInputBuffers) {
368 ExpectSettings(); 429 ExpectSettings();
369 ExpectStart(); 430 ExpectStart();
370 omx_codec_->Start(); 431 omx_engine_->Initialize(&message_loop_,
432 &av_stream_,
433 feed_done_cb_,
434 decode_done_cb_,
435 init_done_cb_task_.CreateTask());
371 message_loop_.RunAllPending(); 436 message_loop_.RunAllPending();
372 437
373 // Since initial FillThisBuffer() calls are made and fulfilled during 438 EXPECT_EQ(VideoDecodeEngine::kNormal, omx_engine_->state());
374 // start. Reads issued to OmxCodec will be fulfilled now. 439
440 // Allocate bitstream buffers.
441 InitializeInputBuffers(kBufferCount);
442
443 // Make emptybuffer requests, also recycle input buffers
375 EXPECT_EQ(0u, output_units_.size()); 444 EXPECT_EQ(0u, output_units_.size());
376 for (int i = 0; i < kBufferCount; ++i) { 445 int count = output_pool_.size();
377 ExpectAndSaveFillThisBuffer(); 446 int repeat_count = kBufferCount * 2;
378 MakeReadRequest(); 447 for (int i = 0; i < repeat_count; ++i) {
448 // Give input buffers to OmxVideoDecodeEngine. OmxVideoDecodeEngine will
449 // make a new FillThisBuffer() call for each read.
450 EXPECT_CALL(*MockOmx::get(), EmptyThisBuffer(NotNull()))
451 .WillOnce(DoAll(EmptyBufferDone(&output_pool_), Return(OMX_ErrorNone)))
452 .RetiresOnSaturation();
453 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
454 .WillOnce(DoAll(EnqueueOutputBuffer(&output_pool_),
455 Return(OMX_ErrorNone)))
456 .RetiresOnSaturation();
457 MakeEmptyBufferRequest();
458 message_loop_.RunAllPending();
459 CHECK(kBufferCount == static_cast<int>(input_units_.size()));
460 CHECK(((i % kBufferCount) + 1) ==
461 static_cast<int>(input_units_.back()->GetDataSize()));
379 } 462 }
380 message_loop_.RunAllPending(); 463 message_loop_.RunAllPending();
381 CHECK(kBufferCount == static_cast<int>(output_units_.size())); 464 EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
382 465 EXPECT_EQ(repeat_count, static_cast<int>(output_units_.size()));
383 // Make sure buffers received are in order. 466 EXPECT_EQ(count, static_cast<int>(output_pool_.size()));
384 for (int i = 0; i < kBufferCount; ++i) {
385 EXPECT_TRUE(output_units_[i] != NULL);
386 }
387
388 output_units_.clear(); 467 output_units_.clear();
389 468
390 // In each loop, perform the following actions: 469 // Send EndOfStream, expect eos flag.
391 // 1. Make a read request to OmxCodec. 470 SendEOSInputBuffer();
392 // 2. Fake a response for FillBufferDone(). 471 EXPECT_EQ(kBufferCount, static_cast<int>(input_units_.size()));
393 // 3. Expect read response received. 472 EXPECT_EQ(1, static_cast<int>(output_units_.size()));
394 // 4. NULL buffer is returned in first time 473 EXPECT_EQ(count-1, static_cast<int>(output_pool_.size()));
395 for (int i = 0; i < kBufferCount + 1; ++i) { 474 EXPECT_EQ(true, got_eos_);
396 // 1. First make a read request.
397 // Since a buffer is given back to OmxCodec component after first time,
398 // a FillThisBuffer() is called to OmxCodec component.
399 if (i > 0) {
400 EXPECT_CALL(*MockOmx::get(), FillThisBuffer(NotNull()))
401 .WillOnce(Return(OMX_ErrorNone))
402 .RetiresOnSaturation();
403 }
404 MakeReadRequest();
405 475
406 // 2. Then fake a response from OpenMAX, only |kBufferCount| times 476 // Shutdown.
407 if (i < kBufferCount) {
408 OMX_BUFFERHEADERTYPE* buffer = fill_this_buffer_received_.front();
409 fill_this_buffer_received_.pop_front();
410 buffer->nFlags = 0;
411 buffer->nFilledLen = kBufferSize;
412 (*MockOmx::get()->callbacks()->FillBufferDone)(
413 MockOmx::get()->component(),
414 MockOmx::get()->component()->pApplicationPrivate,
415 buffer);
416 }
417
418 // Make sure actions are completed.
419 message_loop_.RunAllPending();
420
421 // 3. Expect read response received.
422 // The above action will cause a read callback be called and we should
423 // receive one buffer now. Also expect the buffer id be received in
424 // reverse order.
425 EXPECT_EQ(1u, output_units_.size());
426 //EXPECT_EQ(kBufferCount - i - 1, output_units_.front().first);
427
428 output_units_.pop_front();
429
430 // Make sure actions are completed.
431 message_loop_.RunAllPending();
432 }
433
434 // Now issue kBufferCount reads to OmxCodec.
435 EXPECT_EQ(0u, output_units_.size());
436
437 // Stop OmxCodec.
438 EXPECT_CALL(stop_callback_, OnFilterCallback());
439 EXPECT_CALL(stop_callback_, OnCallbackDestroyed());
440 ExpectStop(); 477 ExpectStop();
441 omx_codec_->Stop(stop_callback_.NewCallback()); 478 omx_engine_->Stop(stop_callback_.NewCallback());
442 message_loop_.RunAllPending(); 479 message_loop_.RunAllPending();
443 } 480 }
444 481
445 // TODO(hclam): Add test case for dynamic port config. 482 // TODO(hclam): Add test case for dynamic port config.
446 // TODO(hclam): Create a more complicated test case so that read 483 // TODO(hclam): Create a more complicated test case so that read
447 // requests and reply from FillThisBuffer() arrives out of order. 484 // requests and reply from FillThisBuffer() arrives out of order.
448 // TODO(hclam): Add test case for Feed().
449 485
450 } // namespace media 486 } // namespace media
451
452 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698