OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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/shared_memory.h" | |
6 #include "base/process/process.h" | |
7 #include "base/synchronization/waitable_event.h" | |
8 #include "ppapi/c/pp_codecs.h" | |
9 #include "ppapi/c/pp_errors.h" | |
10 #include "ppapi/c/ppb_video_encoder.h" | |
11 #include "ppapi/c/ppb_video_frame.h" | |
12 #include "ppapi/proxy/locking_resource_releaser.h" | |
13 #include "ppapi/proxy/plugin_message_filter.h" | |
14 #include "ppapi/proxy/ppapi_message_utils.h" | |
15 #include "ppapi/proxy/ppapi_messages.h" | |
16 #include "ppapi/proxy/ppapi_proxy_test.h" | |
17 #include "ppapi/proxy/video_encoder_resource.h" | |
18 #include "ppapi/shared_impl/media_stream_buffer.h" | |
19 #include "ppapi/shared_impl/proxy_lock.h" | |
20 #include "ppapi/thunk/thunk.h" | |
21 | |
22 using ppapi::proxy::ResourceMessageTestSink; | |
23 | |
24 namespace ppapi { | |
25 namespace proxy { | |
26 | |
27 namespace { | |
28 | |
29 class MockCompletionCallback { | |
30 public: | |
31 MockCompletionCallback() : called_(false), call_event_(false, false) {} | |
32 | |
33 bool called() { return called_; } | |
34 int32_t result() { return result_; } | |
35 | |
36 void WaitUntilCalled() { call_event_.Wait(); } | |
37 | |
38 void Reset() { | |
39 called_ = false; | |
40 call_event_.Reset(); | |
41 } | |
42 | |
43 static void Callback(void* user_data, int32_t result) { | |
44 MockCompletionCallback* that = | |
45 reinterpret_cast<MockCompletionCallback*>(user_data); | |
46 that->call_event_.Signal(); | |
47 that->called_ = true; | |
48 that->result_ = result; | |
49 } | |
50 | |
51 private: | |
52 bool called_; | |
53 int32_t result_; | |
54 base::WaitableEvent call_event_; | |
55 }; | |
56 | |
57 class VideoEncoderResourceTest : public PluginProxyTest { | |
58 public: | |
59 VideoEncoderResourceTest() | |
60 : encoder_iface_(thunk::GetPPB_VideoEncoder_0_1_Thunk()) {} | |
61 | |
62 const PPB_VideoEncoder_0_1* encoder_iface() const { return encoder_iface_; } | |
63 | |
64 const uint32_t kBitstreamBufferSize = 4000; | |
65 const uint32_t kBitstreamBufferCount = 5; | |
66 const uint32_t kVideoFrameCount = 3; | |
67 const uint32_t kBitrate = 200000; | |
68 | |
69 const PP_Size kFrameSize = {640, 480}; | |
70 | |
71 void SendReply(const ResourceMessageCallParams& params, | |
72 int32_t result, | |
73 const IPC::Message& nested_message) { | |
74 ResourceMessageReplyParams reply_params(params.pp_resource(), | |
75 params.sequence()); | |
76 reply_params.set_result(result); | |
77 PluginMessageFilter::DispatchResourceReplyForTest(reply_params, | |
78 nested_message); | |
79 } | |
80 | |
81 void SendReplyWithHandle(const ResourceMessageCallParams& params, | |
82 int32_t result, | |
83 const IPC::Message& nested_message, | |
84 const SerializedHandle& handle) { | |
85 ResourceMessageReplyParams reply_params(params.pp_resource(), | |
86 params.sequence()); | |
87 reply_params.set_result(result); | |
88 reply_params.AppendHandle(handle); | |
89 PluginMessageFilter::DispatchResourceReplyForTest(reply_params, | |
90 nested_message); | |
91 } | |
92 | |
93 void SendReplyWithHandles(const ResourceMessageCallParams& params, | |
94 int32_t result, | |
95 const IPC::Message& nested_message, | |
96 const std::vector<SerializedHandle>& handles) { | |
97 ResourceMessageReplyParams reply_params(params.pp_resource(), | |
98 params.sequence()); | |
99 reply_params.set_result(result); | |
100 for (SerializedHandle handle : handles) | |
101 reply_params.AppendHandle(handle); | |
102 PluginMessageFilter::DispatchResourceReplyForTest(reply_params, | |
103 nested_message); | |
104 } | |
105 | |
106 PP_Resource CreateEncoder() { | |
107 PP_Resource result = encoder_iface()->Create(pp_instance()); | |
108 return result; | |
109 } | |
110 | |
111 void CreateBitstreamSharedMemory(uint32_t buffer_size, uint32_t nb_buffers) { | |
112 shared_memory_bitstreams_.clear(); | |
113 for (uint32_t i = 0; i < nb_buffers; ++i) { | |
114 scoped_ptr<base::SharedMemory> mem(new base::SharedMemory()); | |
115 ASSERT_TRUE(mem->CreateAnonymous(buffer_size)); | |
116 shared_memory_bitstreams_.push_back(mem.Pass()); | |
117 } | |
118 } | |
119 | |
120 void CreateVideoFramesSharedMemory(uint32_t frame_length, | |
121 uint32_t frame_count) { | |
122 shared_memory_frames_.reset(new base::SharedMemory()); | |
123 uint32_t frame_buffer_length = | |
124 frame_length + sizeof(ppapi::MediaStreamBuffer::Video) - | |
125 sizeof(ppapi::MediaStreamBuffer::Video::data); | |
126 ASSERT_TRUE(shared_memory_frames_->CreateAnonymous(frame_buffer_length * | |
127 frame_count)); | |
128 } | |
129 | |
130 PP_Resource CreateAndInitializeEncoder() { | |
131 PP_Resource encoder = CreateEncoder(); | |
132 PP_Size size = kFrameSize; | |
133 MockCompletionCallback cb; | |
134 int32_t result = encoder_iface()->Initialize( | |
135 encoder, PP_VIDEOFRAME_FORMAT_I420, &size, PP_VIDEOPROFILE_H264MAIN, | |
136 kBitrate, PP_HARDWAREACCELERATION_WITHFALLBACK, | |
137 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
138 &cb)); | |
139 if (result != PP_OK_COMPLETIONPENDING) | |
140 return 0; | |
141 ResourceMessageCallParams params; | |
142 IPC::Message msg; | |
143 if (!sink().GetFirstResourceCallMatching( | |
144 PpapiHostMsg_VideoEncoder_Initialize::ID, ¶ms, &msg)) | |
145 return 0; | |
146 sink().ClearMessages(); | |
147 | |
148 SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize); | |
149 CreateBitstreamSharedMemory(kBitstreamBufferSize, kBitstreamBufferCount); | |
150 SendBitstreamBuffers(params, kBitstreamBufferSize); | |
151 | |
152 if (!cb.called() || cb.result() != PP_OK) | |
153 return 0; | |
154 | |
155 return encoder; | |
156 } | |
157 | |
158 int32_t CallGetFramesRequired(PP_Resource pp_encoder) { | |
159 return encoder_iface()->GetFramesRequired(pp_encoder); | |
160 } | |
161 | |
162 int32_t CallGetFrameCodedSize(PP_Resource pp_encoder, PP_Size* coded_size) { | |
163 return encoder_iface()->GetFrameCodedSize(pp_encoder, coded_size); | |
164 } | |
165 | |
166 int32_t CallGetVideoFrame(PP_Resource pp_encoder, | |
167 PP_Resource* video_frame, | |
168 MockCompletionCallback* cb) { | |
169 return encoder_iface()->GetVideoFrame( | |
170 pp_encoder, video_frame, PP_MakeOptionalCompletionCallback( | |
171 &MockCompletionCallback::Callback, cb)); | |
172 } | |
173 | |
174 int32_t CallFirstGetVideoFrame(PP_Resource pp_encoder, | |
175 PP_Resource* video_frame, | |
176 MockCompletionCallback* cb) { | |
177 int32_t result = encoder_iface()->GetVideoFrame( | |
178 pp_encoder, video_frame, PP_MakeOptionalCompletionCallback( | |
179 &MockCompletionCallback::Callback, cb)); | |
180 if (result != PP_OK_COMPLETIONPENDING) | |
181 return result; | |
182 | |
183 ResourceMessageCallParams params; | |
184 CheckGetVideoFramesMsg(¶ms); | |
185 | |
186 uint32_t frame_length = kFrameSize.width * kFrameSize.height * 2; | |
187 CreateVideoFramesSharedMemory(frame_length, kVideoFrameCount); | |
188 SendGetVideoFramesReply(params, kVideoFrameCount, frame_length, kFrameSize); | |
189 | |
190 return result; | |
191 } | |
192 | |
193 int32_t CallEncode(PP_Resource pp_encoder, | |
194 PP_Resource video_frame, | |
195 PP_Bool force_keyframe, | |
196 MockCompletionCallback* cb) { | |
197 return encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe, | |
198 PP_MakeOptionalCompletionCallback( | |
199 &MockCompletionCallback::Callback, cb)); | |
200 } | |
201 | |
202 int32_t CallCompleteEncode(PP_Resource pp_encoder, | |
203 PP_Resource video_frame, | |
204 PP_Bool force_keyframe, | |
205 MockCompletionCallback* cb) { | |
206 int32_t result = | |
207 encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe, | |
208 PP_MakeOptionalCompletionCallback( | |
209 &MockCompletionCallback::Callback, cb)); | |
210 if (result != PP_OK_COMPLETIONPENDING) | |
211 return result; | |
212 | |
213 ResourceMessageCallParams params; | |
214 uint32_t frame_id; | |
215 bool forced_keyframe; | |
216 if (!CheckEncodeMsg(¶ms, &frame_id, &forced_keyframe)) | |
217 return PP_ERROR_FAILED; | |
218 | |
219 SendEncodeReply(params, frame_id); | |
220 | |
221 return result; | |
222 } | |
223 | |
224 int32_t CallGetBitstreamBuffer(PP_Resource pp_encoder, | |
225 PP_BitstreamBuffer* bitstream_buffer, | |
226 MockCompletionCallback* cb) { | |
227 return encoder_iface()->GetBitstreamBuffer( | |
228 pp_encoder, bitstream_buffer, | |
229 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
230 cb)); | |
231 } | |
232 | |
233 void CallRecycleBitstreamBuffer(PP_Resource pp_encoder, | |
234 const PP_BitstreamBuffer& buffer) { | |
235 encoder_iface()->RecycleBitstreamBuffer(pp_encoder, &buffer); | |
236 } | |
237 | |
238 void CallRequestEncodingParametersChange(PP_Resource pp_encoder, | |
239 uint32_t bitrate, | |
240 uint32_t framerate) { | |
241 encoder_iface()->RequestEncodingParametersChange(pp_encoder, bitrate, | |
242 framerate); | |
243 } | |
244 | |
245 void CallClose(PP_Resource pp_encoder) { | |
246 encoder_iface()->Close(pp_encoder); | |
247 } | |
248 | |
249 void SendGetSupportedProfilesReply( | |
250 const ResourceMessageCallParams& params, | |
251 const std::vector<PP_VideoProfileDescription>& profiles) { | |
252 SendReply(params, PP_OK, | |
253 PpapiPluginMsg_VideoEncoder_GetSupportedProfilesReply(profiles)); | |
254 } | |
255 | |
256 void SendInitializeReply(const ResourceMessageCallParams& params, | |
257 int32_t success, | |
258 uint32_t input_frame_count, | |
259 const PP_Size& input_coded_size) { | |
260 SendReply(params, success, PpapiPluginMsg_VideoEncoder_InitializeReply( | |
261 input_frame_count, input_coded_size)); | |
262 } | |
263 | |
264 void SendBitstreamBuffers(const ResourceMessageCallParams& params, | |
265 uint32_t buffer_length) { | |
266 std::vector<SerializedHandle> handles; | |
267 for (base::SharedMemory* mem : shared_memory_bitstreams_) { | |
268 ASSERT_EQ(mem->requested_size(), buffer_length); | |
269 base::SharedMemoryHandle handle; | |
270 | |
271 ASSERT_TRUE( | |
272 mem->ShareToProcess(base::Process::Current().Handle(), &handle)); | |
273 handles.push_back(SerializedHandle(handle, buffer_length)); | |
274 } | |
275 SendReplyWithHandles( | |
276 params, PP_OK, | |
277 PpapiPluginMsg_VideoEncoder_BitstreamBuffers(buffer_length), handles); | |
278 } | |
279 | |
280 void SendGetVideoFramesReply(const ResourceMessageCallParams& params, | |
281 uint32_t frame_count, | |
282 uint32_t frame_length, | |
283 const PP_Size& size) { | |
284 base::SharedMemoryHandle handle; | |
285 ASSERT_TRUE(shared_memory_frames_->ShareToProcess( | |
286 base::Process::Current().Handle(), &handle)); | |
287 SendReplyWithHandle( | |
288 params, PP_OK, PpapiPluginMsg_VideoEncoder_GetVideoFramesReply( | |
289 frame_count, frame_length, size), | |
290 SerializedHandle(handle, shared_memory_frames_->requested_size())); | |
291 } | |
292 | |
293 void SendEncodeReply(const ResourceMessageCallParams& params, | |
294 uint32_t frame_id) { | |
295 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_EncodeReply(frame_id)); | |
296 } | |
297 | |
298 void SendBitstreamBufferReady(const ResourceMessageCallParams& params, | |
299 uint32_t buffer_id, | |
300 uint32_t buffer_size, | |
301 bool keyframe) { | |
302 SendReply(params, PP_OK, | |
303 PpapiPluginMsg_VideoEncoder_BitstreamBufferReady( | |
304 buffer_id, buffer_size, PP_FromBool(keyframe))); | |
305 } | |
306 | |
307 void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) { | |
308 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_NotifyError(error)); | |
309 } | |
310 | |
311 bool CheckGetSupportedProfilesMsg(ResourceMessageCallParams* params) { | |
312 IPC::Message msg; | |
313 if (!sink().GetFirstResourceCallMatching( | |
Tom Sepez
2015/02/20 17:48:02
nit: wouldn't this be just
return sink().GetFirs
llandwerlin-old
2015/02/20 18:23:09
Done.
| |
314 PpapiHostMsg_VideoEncoder_GetSupportedProfiles::ID, params, &msg)) | |
315 return false; | |
316 return true; | |
317 } | |
318 | |
319 bool CheckInitializeMsg(ResourceMessageCallParams* params, | |
320 PP_VideoFrame_Format* input_format, | |
321 struct PP_Size* input_visible_size, | |
322 PP_VideoProfile* output_profile, | |
323 uint32_t* bitrate, | |
324 PP_HardwareAcceleration* acceleration) { | |
325 IPC::Message msg; | |
326 if (!sink().GetFirstResourceCallMatching( | |
327 PpapiHostMsg_VideoEncoder_Initialize::ID, params, &msg)) | |
328 return false; | |
329 sink().ClearMessages(); | |
330 return UnpackMessage<PpapiHostMsg_VideoEncoder_Initialize>( | |
331 msg, input_format, input_visible_size, output_profile, bitrate, | |
332 acceleration); | |
333 } | |
334 | |
335 bool CheckGetVideoFramesMsg(ResourceMessageCallParams* params) { | |
336 IPC::Message msg; | |
337 if (!sink().GetFirstResourceCallMatching( | |
338 PpapiHostMsg_VideoEncoder_GetVideoFrames::ID, params, &msg)) | |
339 return false; | |
340 sink().ClearMessages(); | |
341 return true; | |
342 } | |
343 | |
344 bool CheckEncodeMsg(ResourceMessageCallParams* params, | |
345 uint32_t* frame_id, | |
346 bool* keyframe) { | |
347 IPC::Message msg; | |
348 if (!sink().GetFirstResourceCallMatching( | |
349 PpapiHostMsg_VideoEncoder_Encode::ID, params, &msg)) | |
350 return false; | |
351 sink().ClearMessages(); | |
352 return UnpackMessage<PpapiHostMsg_VideoEncoder_Encode>(msg, frame_id, | |
353 keyframe); | |
354 } | |
355 | |
356 bool CheckRecycleBitstreamBufferMsg(ResourceMessageCallParams* params, | |
357 uint32_t* buffer_id) { | |
358 IPC::Message msg; | |
359 if (!sink().GetFirstResourceCallMatching( | |
360 PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer::ID, params, &msg)) | |
361 return false; | |
362 sink().ClearMessages(); | |
363 return UnpackMessage<PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer>( | |
364 msg, buffer_id); | |
365 } | |
366 | |
367 bool CheckRequestEncodingParametersChangeMsg( | |
368 ResourceMessageCallParams* params, | |
369 uint32_t* bitrate, | |
370 uint32_t* framerate) { | |
371 IPC::Message msg; | |
372 if (!sink().GetFirstResourceCallMatching( | |
373 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange::ID, | |
374 params, &msg)) | |
375 return false; | |
376 sink().ClearMessages(); | |
377 return UnpackMessage< | |
378 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange>(msg, bitrate, | |
379 framerate); | |
380 } | |
381 | |
382 bool CheckIsVideoFrame(PP_Resource video_frame) { | |
383 return thunk::GetPPB_VideoFrame_0_1_Thunk()->IsVideoFrame(video_frame); | |
384 } | |
385 | |
386 bool CheckIsVideoFrameValid(PP_Resource video_frame) { | |
387 PP_Size frame_size; | |
388 return thunk::GetPPB_VideoFrame_0_1_Thunk()->GetSize( | |
389 video_frame, &frame_size) == PP_TRUE; | |
390 } | |
391 | |
392 private: | |
393 const PPB_VideoEncoder_0_1* encoder_iface_; | |
394 | |
395 ScopedVector<base::SharedMemory> shared_memory_bitstreams_; | |
396 scoped_ptr<base::SharedMemory> shared_memory_frames_; | |
397 }; | |
398 | |
399 void* ForwardUserData(void* user_data, | |
400 uint32_t element_count, | |
401 uint32_t element_size) { | |
402 return user_data; | |
403 } | |
404 | |
405 } // namespace | |
406 | |
407 TEST_F(VideoEncoderResourceTest, GetSupportedProfiles) { | |
408 // Verifies that GetSupportedProfiles calls into the renderer and | |
409 // the we get the right results back. | |
410 { | |
411 LockingResourceReleaser encoder(CreateEncoder()); | |
412 PP_VideoProfileDescription profiles[2]; | |
413 PP_ArrayOutput output; | |
414 output.user_data = &profiles[0]; | |
415 output.GetDataBuffer = ForwardUserData; | |
416 ResourceMessageCallParams params; | |
417 MockCompletionCallback cb; | |
418 int32_t result = encoder_iface()->GetSupportedProfiles( | |
419 encoder.get(), output, PP_MakeOptionalCompletionCallback( | |
420 &MockCompletionCallback::Callback, &cb)); | |
421 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
422 ASSERT_TRUE(CheckGetSupportedProfilesMsg(¶ms)); | |
423 | |
424 std::vector<PP_VideoProfileDescription> profiles_response; | |
425 PP_VideoProfileDescription profile; | |
426 profile.profile = PP_VIDEOPROFILE_H264MAIN; | |
427 profile.max_resolution.width = 1920; | |
428 profile.max_resolution.height = 1080; | |
429 profile.max_framerate_numerator = 30; | |
430 profile.max_framerate_denominator = 1; | |
431 profiles_response.push_back(profile); | |
432 profile.profile = PP_VIDEOPROFILE_VP8_ANY; | |
433 profile.max_resolution.width = 1920; | |
434 profile.max_resolution.height = 1080; | |
435 profile.max_framerate_numerator = 30; | |
436 profile.max_framerate_denominator = 1; | |
437 profiles_response.push_back(profile); | |
438 | |
439 SendGetSupportedProfilesReply(params, profiles_response); | |
440 ASSERT_EQ(PP_OK, cb.result()); | |
441 | |
442 ASSERT_EQ(2U, profiles_response.size()); | |
443 ASSERT_EQ(0, memcmp(&profiles[0], &profiles_response[0], | |
444 sizeof(PP_VideoProfileDescription) * 2)); | |
445 } | |
446 } | |
447 | |
448 TEST_F(VideoEncoderResourceTest, InitializeFailure) { | |
449 { | |
450 // Verify the initialize callback is called in case of failure. | |
451 LockingResourceReleaser encoder(CreateEncoder()); | |
452 ResourceMessageCallParams params; | |
453 PP_Size size = kFrameSize; | |
454 MockCompletionCallback cb; | |
455 int32_t result = encoder_iface()->Initialize( | |
456 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size, | |
457 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
458 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
459 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
460 &cb)); | |
461 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
462 | |
463 PP_VideoFrame_Format input_format; | |
464 PP_Size input_visible_size; | |
465 PP_VideoProfile output_profile; | |
466 uint32_t bitrate; | |
467 PP_HardwareAcceleration acceleration; | |
468 ASSERT_TRUE(CheckInitializeMsg(¶ms, &input_format, &input_visible_size, | |
469 &output_profile, &bitrate, &acceleration)); | |
470 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format); | |
471 ASSERT_EQ(size.width, input_visible_size.width); | |
472 ASSERT_EQ(size.height, input_visible_size.height); | |
473 ASSERT_EQ(kBitrate, bitrate); | |
474 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile); | |
475 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration); | |
476 | |
477 SendInitializeReply(params, PP_ERROR_NOTSUPPORTED, kVideoFrameCount, | |
478 kFrameSize); | |
479 ASSERT_TRUE(cb.called()); | |
480 ASSERT_EQ(PP_ERROR_NOTSUPPORTED, cb.result()); | |
481 } | |
482 { | |
483 // Verify the initialize callback is called in case of error | |
484 // notification. | |
485 LockingResourceReleaser encoder(CreateEncoder()); | |
486 ResourceMessageCallParams params; | |
487 PP_Size size = kFrameSize; | |
488 MockCompletionCallback cb; | |
489 int32_t result = encoder_iface()->Initialize( | |
490 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size, | |
491 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
492 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
493 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
494 &cb)); | |
495 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
496 | |
497 PP_VideoFrame_Format input_format; | |
498 PP_Size input_visible_size; | |
499 PP_VideoProfile output_profile; | |
500 uint32_t bitrate; | |
501 PP_HardwareAcceleration acceleration; | |
502 ASSERT_TRUE(CheckInitializeMsg(¶ms, &input_format, &input_visible_size, | |
503 &output_profile, &bitrate, &acceleration)); | |
504 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format); | |
505 ASSERT_EQ(kFrameSize.width, input_visible_size.width); | |
506 ASSERT_EQ(kFrameSize.height, input_visible_size.height); | |
507 ASSERT_EQ(kBitrate, bitrate); | |
508 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile); | |
509 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration); | |
510 | |
511 ResourceMessageCallParams error_params(encoder.get(), 0); | |
512 SendNotifyError(error_params, PP_ERROR_FAILED); | |
513 ASSERT_TRUE(cb.called()); | |
514 ASSERT_EQ(PP_ERROR_FAILED, cb.result()); | |
515 } | |
516 { | |
517 // Verify that calling initialize twice fails the second time if | |
518 // we haven't received a response yet. | |
519 LockingResourceReleaser encoder(CreateEncoder()); | |
520 ResourceMessageCallParams params; | |
521 PP_Size size = kFrameSize; | |
522 MockCompletionCallback cb; | |
523 int32_t result = encoder_iface()->Initialize( | |
524 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size, | |
525 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
526 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
527 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
528 &cb)); | |
529 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
530 | |
531 PP_VideoFrame_Format input_format; | |
532 PP_Size input_visible_size; | |
533 PP_VideoProfile output_profile; | |
534 uint32_t bitrate; | |
535 PP_HardwareAcceleration acceleration; | |
536 ASSERT_TRUE(CheckInitializeMsg(¶ms, &input_format, &input_visible_size, | |
537 &output_profile, &bitrate, &acceleration)); | |
538 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format); | |
539 ASSERT_EQ(size.width, input_visible_size.width); | |
540 ASSERT_EQ(size.height, input_visible_size.height); | |
541 ASSERT_EQ(kBitrate, bitrate); | |
542 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile); | |
543 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration); | |
544 | |
545 result = encoder_iface()->Initialize( | |
546 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size, | |
547 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
548 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
549 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
550 &cb)); | |
551 ASSERT_EQ(PP_ERROR_INPROGRESS, result); | |
552 } | |
553 } | |
554 | |
555 TEST_F(VideoEncoderResourceTest, InitializeSuccess) { | |
556 { | |
557 // Verify the initialize callback is called when initialization is | |
558 // successfull. | |
559 LockingResourceReleaser encoder(CreateEncoder()); | |
560 ResourceMessageCallParams params; | |
561 PP_Size size = kFrameSize; | |
562 const uint32_t kBitrate = 420000; | |
563 MockCompletionCallback cb; | |
564 int32_t result = encoder_iface()->Initialize( | |
565 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size, | |
566 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
567 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
568 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
569 &cb)); | |
570 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
571 | |
572 PP_VideoFrame_Format input_format; | |
573 PP_Size input_visible_size; | |
574 PP_VideoProfile output_profile; | |
575 uint32_t bitrate; | |
576 PP_HardwareAcceleration acceleration; | |
577 ASSERT_TRUE(CheckInitializeMsg(¶ms, &input_format, &input_visible_size, | |
578 &output_profile, &bitrate, &acceleration)); | |
579 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format); | |
580 ASSERT_EQ(kFrameSize.width, input_visible_size.width); | |
581 ASSERT_EQ(kFrameSize.height, input_visible_size.height); | |
582 ASSERT_EQ(kBitrate, bitrate); | |
583 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile); | |
584 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration); | |
585 | |
586 SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize); | |
587 | |
588 ASSERT_TRUE(cb.called()); | |
589 ASSERT_EQ(PP_OK, cb.result()); | |
590 } | |
591 { | |
592 // Verify that calling initialize a second time, after it already | |
593 // succeeded, fails. | |
594 LockingResourceReleaser encoder(CreateEncoder()); | |
595 ResourceMessageCallParams params; | |
596 PP_Size size = kFrameSize; | |
597 const uint32_t kBitrate = 420000; | |
598 MockCompletionCallback cb; | |
599 int32_t result = encoder_iface()->Initialize( | |
600 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size, | |
601 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
602 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
603 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
604 &cb)); | |
605 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
606 | |
607 PP_VideoFrame_Format input_format; | |
608 PP_Size input_visible_size; | |
609 PP_VideoProfile output_profile; | |
610 uint32_t bitrate; | |
611 PP_HardwareAcceleration acceleration; | |
612 ASSERT_TRUE(CheckInitializeMsg(¶ms, &input_format, &input_visible_size, | |
613 &output_profile, &bitrate, &acceleration)); | |
614 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format); | |
615 ASSERT_EQ(kFrameSize.width, input_visible_size.width); | |
616 ASSERT_EQ(kFrameSize.height, input_visible_size.height); | |
617 ASSERT_EQ(kBitrate, bitrate); | |
618 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile); | |
619 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration); | |
620 | |
621 SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize); | |
622 | |
623 ASSERT_TRUE(cb.called()); | |
624 ASSERT_EQ(PP_OK, cb.result()); | |
625 | |
626 result = encoder_iface()->Initialize( | |
627 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size, | |
628 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
629 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
630 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
631 &cb)); | |
632 ASSERT_EQ(PP_ERROR_FAILED, result); | |
633 } | |
634 { | |
635 // Verify the sending the bitstream buffers details makes them | |
636 // available through the API. the right values. | |
637 LockingResourceReleaser encoder(CreateEncoder()); | |
638 ResourceMessageCallParams params; | |
639 PP_Size size = kFrameSize; | |
640 const uint32_t kBitrate = 420000; | |
641 MockCompletionCallback cb; | |
642 int32_t result = encoder_iface()->Initialize( | |
643 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size, | |
644 PP_VIDEOPROFILE_H264MAIN, kBitrate, | |
645 PP_HARDWAREACCELERATION_WITHFALLBACK, | |
646 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback, | |
647 &cb)); | |
648 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | |
649 | |
650 PP_VideoFrame_Format input_format; | |
651 PP_Size input_visible_size; | |
652 PP_VideoProfile output_profile; | |
653 uint32_t bitrate; | |
654 PP_HardwareAcceleration acceleration; | |
655 ASSERT_TRUE(CheckInitializeMsg(¶ms, &input_format, &input_visible_size, | |
656 &output_profile, &bitrate, &acceleration)); | |
657 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format); | |
658 ASSERT_EQ(kFrameSize.width, input_visible_size.width); | |
659 ASSERT_EQ(kFrameSize.height, input_visible_size.height); | |
660 ASSERT_EQ(kBitrate, bitrate); | |
661 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile); | |
662 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration); | |
663 | |
664 SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize); | |
665 | |
666 ASSERT_TRUE(cb.called()); | |
667 ASSERT_EQ(PP_OK, cb.result()); | |
668 | |
669 PP_Size coded_size; | |
670 ASSERT_EQ(PP_OK, CallGetFrameCodedSize(encoder.get(), &coded_size)); | |
671 ASSERT_EQ(kFrameSize.width, coded_size.width); | |
672 ASSERT_EQ(kFrameSize.height, coded_size.height); | |
673 ASSERT_EQ(static_cast<int32_t>(kVideoFrameCount), | |
674 CallGetFramesRequired(encoder.get())); | |
675 } | |
676 } | |
677 | |
678 TEST_F(VideoEncoderResourceTest, Uninitialized) { | |
679 // Operations on uninitialized encoders should fail. | |
680 LockingResourceReleaser encoder(CreateEncoder()); | |
681 | |
682 ASSERT_EQ(PP_ERROR_FAILED, CallGetFramesRequired(encoder.get())); | |
683 | |
684 PP_Size size; | |
685 ASSERT_EQ(PP_ERROR_FAILED, CallGetFrameCodedSize(encoder.get(), &size)); | |
686 | |
687 MockCompletionCallback uncalled_cb; | |
688 PP_Resource video_frame = 0; | |
689 ASSERT_EQ(PP_ERROR_FAILED, | |
690 CallGetVideoFrame(encoder.get(), &video_frame, &uncalled_cb)); | |
691 ASSERT_FALSE(uncalled_cb.called()); | |
692 ASSERT_EQ(0, video_frame); | |
693 | |
694 ASSERT_EQ(PP_ERROR_FAILED, | |
695 CallEncode(encoder.get(), video_frame, PP_FALSE, &uncalled_cb)); | |
696 ASSERT_FALSE(uncalled_cb.called()); | |
697 | |
698 PP_BitstreamBuffer bitstream_buffer; | |
699 ASSERT_EQ( | |
700 PP_ERROR_FAILED, | |
701 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, &uncalled_cb)); | |
702 ASSERT_FALSE(uncalled_cb.called()); | |
703 | |
704 ResourceMessageCallParams params; | |
705 uint32_t buffer_id; | |
706 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer); | |
707 ASSERT_FALSE(CheckRecycleBitstreamBufferMsg(¶ms, &buffer_id)); | |
708 | |
709 uint32_t bitrate, framerate; | |
710 CallRequestEncodingParametersChange(encoder.get(), 0, 0); | |
711 ASSERT_FALSE( | |
712 CheckRequestEncodingParametersChangeMsg(¶ms, &bitrate, &framerate)); | |
713 } | |
714 | |
715 TEST_F(VideoEncoderResourceTest, InitializeAndGetVideoFrame) { | |
716 // Verify that we can pull the right number of video frames before | |
717 // the proxy makes us wait. | |
718 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
719 ResourceMessageCallParams params; | |
720 PP_Resource video_frames[kVideoFrameCount + 1]; | |
721 MockCompletionCallback get_frame_cb; | |
722 | |
723 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
724 CallGetVideoFrame(encoder.get(), &video_frames[0], &get_frame_cb)); | |
725 ASSERT_FALSE(get_frame_cb.called()); | |
726 ASSERT_TRUE(CheckGetVideoFramesMsg(¶ms)); | |
727 | |
728 uint32_t frame_length = kFrameSize.width * kFrameSize.height * 2; | |
729 CreateVideoFramesSharedMemory(frame_length, kVideoFrameCount); | |
730 SendGetVideoFramesReply(params, kVideoFrameCount, frame_length, kFrameSize); | |
731 | |
732 for (uint32_t i = 1; i < kVideoFrameCount; ++i) { | |
733 get_frame_cb.Reset(); | |
734 ASSERT_EQ( | |
735 PP_OK_COMPLETIONPENDING, | |
736 CallGetVideoFrame(encoder.get(), &video_frames[i], &get_frame_cb)); | |
737 ASSERT_TRUE(get_frame_cb.called()); | |
738 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
739 ASSERT_TRUE(CheckIsVideoFrame(video_frames[i])); | |
740 } | |
741 | |
742 get_frame_cb.Reset(); | |
743 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
744 CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameCount], | |
745 &get_frame_cb)); | |
746 ASSERT_FALSE(get_frame_cb.called()); | |
747 | |
748 MockCompletionCallback get_frame_fail_cb; | |
749 ASSERT_EQ(PP_ERROR_INPROGRESS, | |
750 CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameCount], | |
751 &get_frame_fail_cb)); | |
752 ASSERT_FALSE(get_frame_fail_cb.called()); | |
753 | |
754 // Unblock the GetVideoFrame callback by freeing up a frame. | |
755 MockCompletionCallback encode_cb; | |
756 ASSERT_EQ( | |
757 PP_OK_COMPLETIONPENDING, | |
758 CallCompleteEncode(encoder.get(), video_frames[0], PP_FALSE, &encode_cb)); | |
759 ASSERT_TRUE(encode_cb.called()); | |
760 ASSERT_EQ(PP_OK, encode_cb.result()); | |
761 ASSERT_TRUE(get_frame_cb.called()); | |
762 | |
763 CallClose(encoder.get()); | |
764 } | |
765 | |
766 TEST_F(VideoEncoderResourceTest, Encode) { | |
767 // Check Encode() calls into the renderer. | |
768 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
769 PP_Resource video_frame; | |
770 MockCompletionCallback get_frame_cb; | |
771 | |
772 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
773 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb)); | |
774 ASSERT_TRUE(get_frame_cb.called()); | |
775 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
776 | |
777 MockCompletionCallback encode_cb; | |
778 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
779 CallEncode(encoder.get(), video_frame, PP_TRUE, &encode_cb)); | |
780 ASSERT_FALSE(encode_cb.called()); | |
781 ASSERT_FALSE(CheckIsVideoFrameValid(video_frame)); | |
782 | |
783 ResourceMessageCallParams params; | |
784 uint32_t frame_id; | |
785 bool force_frame; | |
786 ASSERT_TRUE(CheckEncodeMsg(¶ms, &frame_id, &force_frame)); | |
787 | |
788 SendEncodeReply(params, frame_id); | |
789 | |
790 ASSERT_TRUE(encode_cb.called()); | |
791 ASSERT_EQ(PP_OK, encode_cb.result()); | |
792 } | |
793 | |
794 TEST_F(VideoEncoderResourceTest, EncodeAndGetVideoFrame) { | |
795 // Check the encoding loop works well. | |
796 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
797 ResourceMessageCallParams params; | |
798 PP_Resource video_frame; | |
799 MockCompletionCallback get_frame_cb, encode_cb; | |
800 | |
801 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
802 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb)); | |
803 ASSERT_TRUE(get_frame_cb.called()); | |
804 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
805 | |
806 for (uint32_t i = 1; i < 20 * kVideoFrameCount; ++i) { | |
807 encode_cb.Reset(); | |
808 ASSERT_EQ( | |
809 PP_OK_COMPLETIONPENDING, | |
810 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb)); | |
811 ASSERT_TRUE(encode_cb.called()); | |
812 ASSERT_EQ(PP_OK, encode_cb.result()); | |
813 | |
814 get_frame_cb.Reset(); | |
815 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
816 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb)); | |
817 ASSERT_TRUE(get_frame_cb.called()); | |
818 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
819 ASSERT_TRUE(CheckIsVideoFrame(video_frame)); | |
820 } | |
821 | |
822 ASSERT_EQ( | |
823 PP_OK_COMPLETIONPENDING, | |
824 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb)); | |
825 ASSERT_TRUE(encode_cb.called()); | |
826 ASSERT_EQ(PP_OK, encode_cb.result()); | |
827 } | |
828 | |
829 TEST_F(VideoEncoderResourceTest, GetBitstreamBuffer) { | |
830 { | |
831 // Verify that the GetBitstreamBuffer callback is fired whenever the | |
832 // renderer signals a buffer is available. | |
833 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
834 | |
835 MockCompletionCallback get_bitstream_buffer_cb; | |
836 PP_BitstreamBuffer bitstream_buffer; | |
837 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
838 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
839 &get_bitstream_buffer_cb)); | |
840 ASSERT_FALSE(get_bitstream_buffer_cb.called()); | |
841 | |
842 ResourceMessageCallParams buffer_params(encoder.get(), 0); | |
843 SendBitstreamBufferReady(buffer_params, 0, 10, true); | |
844 | |
845 ASSERT_TRUE(get_bitstream_buffer_cb.called()); | |
846 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result()); | |
847 ASSERT_EQ(10U, bitstream_buffer.size); | |
848 ASSERT_EQ(PP_TRUE, bitstream_buffer.key_frame); | |
849 } | |
850 { | |
851 // Verify that calling GetBitstreamBuffer a second time, while the | |
852 // first callback hasn't been fired fails. | |
853 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
854 | |
855 MockCompletionCallback get_bitstream_buffer_cb; | |
856 PP_BitstreamBuffer bitstream_buffer; | |
857 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
858 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
859 &get_bitstream_buffer_cb)); | |
860 ASSERT_FALSE(get_bitstream_buffer_cb.called()); | |
861 | |
862 ASSERT_EQ(PP_ERROR_INPROGRESS, | |
863 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
864 &get_bitstream_buffer_cb)); | |
865 ASSERT_FALSE(get_bitstream_buffer_cb.called()); | |
866 } | |
867 } | |
868 | |
869 TEST_F(VideoEncoderResourceTest, RecycleBitstreamBuffer) { | |
870 // Verify that we signal the renderer that a bitstream buffer has been | |
871 // recycled. | |
872 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
873 | |
874 MockCompletionCallback get_bitstream_buffer_cb; | |
875 PP_BitstreamBuffer bitstream_buffer; | |
876 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
877 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
878 &get_bitstream_buffer_cb)); | |
879 ASSERT_FALSE(get_bitstream_buffer_cb.called()); | |
880 | |
881 ResourceMessageCallParams buffer_params(encoder.get(), 0); | |
882 SendBitstreamBufferReady(buffer_params, kBitstreamBufferCount - 1, 10, true); | |
883 | |
884 ASSERT_TRUE(get_bitstream_buffer_cb.called()); | |
885 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result()); | |
886 | |
887 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer); | |
888 | |
889 ResourceMessageCallParams recycle_params; | |
890 uint32_t buffer_id; | |
891 ASSERT_TRUE(CheckRecycleBitstreamBufferMsg(&recycle_params, &buffer_id)); | |
892 ASSERT_EQ(kBitstreamBufferCount - 1, buffer_id); | |
893 } | |
894 | |
895 TEST_F(VideoEncoderResourceTest, RequestEncodingParametersChange) { | |
896 // Check encoding parameter changes are correctly sent to the | |
897 // renderer. | |
898 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
899 | |
900 CallRequestEncodingParametersChange(encoder.get(), 1, 2); | |
901 ResourceMessageCallParams params; | |
902 uint32_t bitrate, framerate; | |
903 ASSERT_TRUE( | |
904 CheckRequestEncodingParametersChangeMsg(¶ms, &bitrate, &framerate)); | |
905 ASSERT_EQ(1U, bitrate); | |
906 ASSERT_EQ(2U, framerate); | |
907 } | |
908 | |
909 TEST_F(VideoEncoderResourceTest, NotifyError) { | |
910 { | |
911 // Check an error from the encoder aborts GetVideoFrame and | |
912 // GetBitstreamBuffer callbacks. | |
913 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
914 | |
915 MockCompletionCallback get_frame_cb; | |
916 PP_Resource video_frame; | |
917 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
918 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb)); | |
919 ASSERT_FALSE(get_frame_cb.called()); | |
920 | |
921 MockCompletionCallback get_bitstream_buffer_cb; | |
922 PP_BitstreamBuffer bitstream_buffer; | |
923 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
924 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
925 &get_bitstream_buffer_cb)); | |
926 | |
927 ResourceMessageCallParams error_params(encoder.get(), 0); | |
928 SendNotifyError(error_params, PP_ERROR_FAILED); | |
929 | |
930 ASSERT_TRUE(get_frame_cb.called()); | |
931 ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb.result()); | |
932 ASSERT_TRUE(get_bitstream_buffer_cb.called()); | |
933 ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result()); | |
934 } | |
935 { | |
936 // Check an error from the encoder aborts Encode and GetBitstreamBuffer | |
937 // callbacks. | |
938 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
939 | |
940 MockCompletionCallback get_frame_cb, encode_cb1, encode_cb2; | |
941 PP_Resource video_frame1, video_frame2; | |
942 ASSERT_EQ( | |
943 PP_OK_COMPLETIONPENDING, | |
944 CallFirstGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb)); | |
945 ASSERT_TRUE(get_frame_cb.called()); | |
946 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
947 | |
948 get_frame_cb.Reset(); | |
949 ASSERT_EQ( | |
950 PP_OK_COMPLETIONPENDING, | |
951 CallFirstGetVideoFrame(encoder.get(), &video_frame2, &get_frame_cb)); | |
952 ASSERT_TRUE(get_frame_cb.called()); | |
953 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
954 | |
955 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
956 CallEncode(encoder.get(), video_frame1, PP_FALSE, &encode_cb1)); | |
957 ASSERT_FALSE(encode_cb1.called()); | |
958 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
959 CallEncode(encoder.get(), video_frame2, PP_FALSE, &encode_cb2)); | |
960 ASSERT_FALSE(encode_cb2.called()); | |
961 | |
962 MockCompletionCallback get_bitstream_buffer_cb; | |
963 PP_BitstreamBuffer bitstream_buffer; | |
964 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
965 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
966 &get_bitstream_buffer_cb)); | |
967 | |
968 ResourceMessageCallParams error_params(encoder.get(), 0); | |
969 SendNotifyError(error_params, PP_ERROR_FAILED); | |
970 | |
971 ASSERT_TRUE(encode_cb1.called()); | |
972 ASSERT_EQ(PP_ERROR_FAILED, encode_cb1.result()); | |
973 ASSERT_TRUE(encode_cb2.called()); | |
974 ASSERT_EQ(PP_ERROR_FAILED, encode_cb2.result()); | |
975 ASSERT_TRUE(get_bitstream_buffer_cb.called()); | |
976 ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result()); | |
977 } | |
978 } | |
979 | |
980 TEST_F(VideoEncoderResourceTest, Close) { | |
981 { | |
982 // Check closing the encoder aborts GetVideoFrame and | |
983 // GetBitstreamBuffer callbacks. | |
984 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
985 | |
986 MockCompletionCallback get_frame_cb; | |
987 PP_Resource video_frame; | |
988 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
989 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb)); | |
990 ASSERT_FALSE(get_frame_cb.called()); | |
991 | |
992 MockCompletionCallback get_bitstream_buffer_cb; | |
993 PP_BitstreamBuffer bitstream_buffer; | |
994 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
995 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
996 &get_bitstream_buffer_cb)); | |
997 | |
998 CallClose(encoder.get()); | |
999 | |
1000 ASSERT_TRUE(get_frame_cb.called()); | |
1001 ASSERT_EQ(PP_ERROR_ABORTED, get_frame_cb.result()); | |
1002 ASSERT_TRUE(get_bitstream_buffer_cb.called()); | |
1003 ASSERT_EQ(PP_ERROR_ABORTED, get_bitstream_buffer_cb.result()); | |
1004 } | |
1005 { | |
1006 // Check closing the encoder aborts Encode and GetBitstreamBuffer | |
1007 // callbacks. | |
1008 LockingResourceReleaser encoder(CreateAndInitializeEncoder()); | |
1009 | |
1010 MockCompletionCallback get_frame_cb, encode_cb1, encode_cb2; | |
1011 PP_Resource video_frame1, video_frame2; | |
1012 ASSERT_EQ( | |
1013 PP_OK_COMPLETIONPENDING, | |
1014 CallFirstGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb)); | |
1015 ASSERT_TRUE(get_frame_cb.called()); | |
1016 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
1017 | |
1018 get_frame_cb.Reset(); | |
1019 ASSERT_EQ( | |
1020 PP_OK_COMPLETIONPENDING, | |
1021 CallFirstGetVideoFrame(encoder.get(), &video_frame2, &get_frame_cb)); | |
1022 ASSERT_TRUE(get_frame_cb.called()); | |
1023 ASSERT_EQ(PP_OK, get_frame_cb.result()); | |
1024 | |
1025 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
1026 CallEncode(encoder.get(), video_frame1, PP_FALSE, &encode_cb1)); | |
1027 ASSERT_FALSE(encode_cb1.called()); | |
1028 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
1029 CallEncode(encoder.get(), video_frame2, PP_FALSE, &encode_cb2)); | |
1030 ASSERT_FALSE(encode_cb2.called()); | |
1031 | |
1032 MockCompletionCallback get_bitstream_buffer_cb; | |
1033 PP_BitstreamBuffer bitstream_buffer; | |
1034 ASSERT_EQ(PP_OK_COMPLETIONPENDING, | |
1035 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, | |
1036 &get_bitstream_buffer_cb)); | |
1037 | |
1038 CallClose(encoder.get()); | |
1039 | |
1040 ASSERT_TRUE(encode_cb1.called()); | |
1041 ASSERT_EQ(PP_ERROR_ABORTED, encode_cb1.result()); | |
1042 ASSERT_TRUE(encode_cb2.called()); | |
1043 ASSERT_EQ(PP_ERROR_ABORTED, encode_cb2.result()); | |
1044 ASSERT_TRUE(get_bitstream_buffer_cb.called()); | |
1045 ASSERT_EQ(PP_ERROR_ABORTED, get_bitstream_buffer_cb.result()); | |
1046 } | |
1047 } | |
1048 | |
1049 } // namespace proxy | |
1050 } // namespace ppapi | |
OLD | NEW |