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

Side by Side Diff: ppapi/proxy/video_encoder_resource_unittest.cc

Issue 905023005: Pepper: PPB_VideoEncoder implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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
OLDNEW
(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 const uint32_t kShmSize = 256;
30 const size_t kDecodeBufferSize = 16;
31 const uint32_t kDecodeId = 5;
32
33 class MockCompletionCallback {
34 public:
35 MockCompletionCallback() : called_(false), call_event_(false, false) {}
36
37 bool called() { return called_; }
38 int32_t result() { return result_; }
39
40 void WaitUntilCalled() { call_event_.Wait(); }
41
42 void Reset() {
43 called_ = false;
44 call_event_.Reset();
45 }
46
47 static void Callback(void* user_data, int32_t result) {
48 MockCompletionCallback* that =
49 reinterpret_cast<MockCompletionCallback*>(user_data);
50 that->call_event_.Signal();
51 that->called_ = true;
52 that->result_ = result;
53 }
54
55 private:
56 bool called_;
57 int32_t result_;
58 base::WaitableEvent call_event_;
59 };
60
61 class VideoEncoderResourceTest : public PluginProxyTest {
62 public:
63 VideoEncoderResourceTest()
64 : encoder_iface_(thunk::GetPPB_VideoEncoder_0_1_Thunk()) {}
65
66 const PPB_VideoEncoder_0_1* encoder_iface() const { return encoder_iface_; }
67
68 const uint32_t kBitstreamBufferSize = 4000;
69 const uint32_t kBitstreamBufferNb = 5;
70 const uint32_t kVideoFrameNb = 3;
71 const uint32_t kBitrate = 200000;
72
73 const PP_Size kSize = {640, 480};
74
75 void SendReply(const ResourceMessageCallParams& params,
76 int32_t result,
77 const IPC::Message& nested_message) {
78 ResourceMessageReplyParams reply_params(params.pp_resource(),
79 params.sequence());
80 reply_params.set_result(result);
81 PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
82 nested_message);
83 }
84
85 void SendReplyWithHandle(const ResourceMessageCallParams& params,
86 int32_t result,
87 const IPC::Message& nested_message,
88 const SerializedHandle& handle) {
89 ResourceMessageReplyParams reply_params(params.pp_resource(),
90 params.sequence());
91 reply_params.set_result(result);
92 reply_params.AppendHandle(handle);
93 PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
94 nested_message);
95 }
96
97 void SendReplyWithHandles(const ResourceMessageCallParams& params,
98 int32_t result,
99 const IPC::Message& nested_message,
100 const std::vector<SerializedHandle>& handles) {
101 ResourceMessageReplyParams reply_params(params.pp_resource(),
102 params.sequence());
103 reply_params.set_result(result);
104 for (SerializedHandle handle : handles)
105 reply_params.AppendHandle(handle);
106 PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
107 nested_message);
108 }
109
110 PP_Resource CreateEncoder() {
111 PP_Resource result = encoder_iface()->Create(pp_instance());
112 return result;
113 }
114
115 void CreateBitstreamSharedMemory(uint32_t buffer_size, uint32_t nb_buffers) {
116 shared_memory_bitstreams_.clear();
117 for (uint32_t i = 0; i < nb_buffers; ++i) {
118 scoped_ptr<base::SharedMemory> mem(new base::SharedMemory());
119 ASSERT_TRUE(mem->CreateAnonymous(buffer_size));
120 shared_memory_bitstreams_.push_back(mem.Pass());
121 }
122 }
123
124 void CreateVideoFramesSharedMemory(uint32_t frame_length,
125 uint32_t frame_count) {
126 shared_memory_frames_.reset(new base::SharedMemory());
127 uint32_t frame_buffer_length =
128 frame_length + sizeof(ppapi::MediaStreamBuffer::Video) -
129 sizeof(ppapi::MediaStreamBuffer::Video::data);
130 ASSERT_TRUE(shared_memory_frames_->CreateAnonymous(frame_buffer_length *
131 frame_count));
132 }
133
134 PP_Resource CreateAndInitializeEncoder() {
135 PP_Resource encoder = CreateEncoder();
136 PP_Size size = kSize;
137 MockCompletionCallback cb;
138 int32_t result = encoder_iface()->Initialize(
139 encoder, PP_VIDEOFRAME_FORMAT_I420, &size, PP_VIDEOPROFILE_H264MAIN,
140 kBitrate, PP_HARDWAREACCELERATION_WITHFALLBACK,
141 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
142 &cb));
143 if (result != PP_OK_COMPLETIONPENDING)
144 return 0;
145 ResourceMessageCallParams params;
146 IPC::Message msg;
147 if (!sink().GetFirstResourceCallMatching(
148 PpapiHostMsg_VideoEncoder_Initialize::ID, &params, &msg))
149 return 0;
150 sink().ClearMessages();
151
152 CreateBitstreamSharedMemory(kBitstreamBufferSize, kBitstreamBufferNb);
153 SendInitializeReply(params, kBitstreamBufferNb, kBitstreamBufferSize,
154 kVideoFrameNb, size);
155
156 if (!cb.called() || cb.result() != PP_OK)
157 return 0;
158
159 return encoder;
160 }
161
162 int32_t CallGetFramesRequired(PP_Resource pp_encoder) {
163 return encoder_iface()->GetFramesRequired(pp_encoder);
164 }
165
166 int32_t CallGetFrameCodedSize(PP_Resource pp_encoder, PP_Size* coded_size) {
167 return encoder_iface()->GetFrameCodedSize(pp_encoder, coded_size);
168 }
169
170 int32_t CallGetVideoFrame(PP_Resource pp_encoder,
171 PP_Resource* video_frame,
172 MockCompletionCallback* cb) {
173 return encoder_iface()->GetVideoFrame(
174 pp_encoder, video_frame, PP_MakeOptionalCompletionCallback(
175 &MockCompletionCallback::Callback, cb));
176 }
177
178 int32_t CallFirstGetVideoFrame(PP_Resource pp_encoder,
179 PP_Resource* video_frame,
180 MockCompletionCallback* cb) {
181 int32_t result = encoder_iface()->GetVideoFrame(
182 pp_encoder, video_frame, PP_MakeOptionalCompletionCallback(
183 &MockCompletionCallback::Callback, cb));
184 if (result != PP_OK_COMPLETIONPENDING)
185 return result;
186
187 ResourceMessageCallParams params;
188 CheckGetVideoFramesMsg(&params);
189
190 uint32_t frame_length = kSize.width * kSize.height * 2;
191 CreateVideoFramesSharedMemory(frame_length, kVideoFrameNb);
192 SendGetVideoFramesReply(params, kVideoFrameNb, frame_length, kSize);
193
194 return result;
195 }
196
197 int32_t CallEncode(PP_Resource pp_encoder,
198 PP_Resource video_frame,
199 PP_Bool force_keyframe,
200 MockCompletionCallback* cb) {
201 return encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe,
202 PP_MakeOptionalCompletionCallback(
203 &MockCompletionCallback::Callback, cb));
204 }
205
206 int32_t CallCompleteEncode(PP_Resource pp_encoder,
207 PP_Resource video_frame,
208 PP_Bool force_keyframe,
209 MockCompletionCallback* cb) {
210 int32_t result =
211 encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe,
212 PP_MakeOptionalCompletionCallback(
213 &MockCompletionCallback::Callback, cb));
214 if (result != PP_OK_COMPLETIONPENDING)
215 return result;
216
217 ResourceMessageCallParams params;
218 uint32_t frame_id;
219 bool forced_keyframe;
220 if (!CheckEncodeMsg(&params, &frame_id, &forced_keyframe))
221 return PP_ERROR_FAILED;
222
223 SendEncodeReply(params, frame_id);
224
225 return result;
226 }
227
228 int32_t CallGetBitstreamBuffer(PP_Resource pp_encoder,
229 PP_BitstreamBuffer* bitstream_buffer,
230 MockCompletionCallback* cb) {
231 return encoder_iface()->GetBitstreamBuffer(
232 pp_encoder, bitstream_buffer,
233 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
234 cb));
235 }
236
237 void CallRecycleBitstreamBuffer(PP_Resource pp_encoder,
238 const PP_BitstreamBuffer& buffer) {
239 encoder_iface()->RecycleBitstreamBuffer(pp_encoder, &buffer);
240 }
241
242 void CallRequestEncodingParametersChange(PP_Resource pp_encoder,
243 uint32_t bitrate,
244 uint32_t framerate) {
245 encoder_iface()->RequestEncodingParametersChange(pp_encoder, bitrate,
246 framerate);
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 uint32_t buffer_count,
258 uint32_t buffer_length,
259 uint32_t input_frame_count,
260 const PP_Size& coded_size) {
261 std::vector<SerializedHandle> handles;
262 for (base::SharedMemory* mem : shared_memory_bitstreams_) {
263 ASSERT_EQ(mem->requested_size(), buffer_length);
264 base::SharedMemoryHandle handle;
265
266 ASSERT_TRUE(
267 mem->ShareToProcess(base::Process::Current().Handle(), &handle));
268 handles.push_back(SerializedHandle(handle, buffer_length));
269 }
270 SendReplyWithHandles(
271 params, PP_OK,
272 PpapiPluginMsg_VideoEncoder_InitializeReply(
273 buffer_count, buffer_length, input_frame_count, coded_size),
274 handles);
275 }
276
277 void SendGetVideoFramesReply(const ResourceMessageCallParams& params,
278 uint32_t frame_count,
279 uint32_t frame_length,
280 const PP_Size& size) {
281 base::SharedMemoryHandle handle;
282 ASSERT_TRUE(shared_memory_frames_->ShareToProcess(
283 base::Process::Current().Handle(), &handle));
284 SendReplyWithHandle(
285 params, PP_OK, PpapiPluginMsg_VideoEncoder_GetVideoFramesReply(
286 frame_count, frame_length, size),
287 SerializedHandle(handle, shared_memory_frames_->requested_size()));
288 }
289
290 void SendEncodeReply(const ResourceMessageCallParams& params,
291 uint32_t frame_id) {
292 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_EncodeReply(frame_id));
293 }
294
295 void SendBitstreamBufferReady(const ResourceMessageCallParams& params,
296 uint32_t buffer_id,
297 uint32_t buffer_size,
298 bool keyframe) {
299 SendReply(params, PP_OK,
300 PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
301 buffer_id, buffer_size, PP_FromBool(keyframe)));
302 }
303
304 void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) {
305 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_NotifyError(error));
306 }
307
308 bool CheckGetSupportedProfilesMsg(ResourceMessageCallParams* params) {
309 IPC::Message msg;
310 if (!sink().GetFirstResourceCallMatching(
311 PpapiHostMsg_VideoEncoder_GetSupportedProfiles::ID, params, &msg))
312 return false;
313 return true;
314 }
315
316 bool CheckInitializeMsg(ResourceMessageCallParams* params,
317 PP_VideoFrame_Format* input_format,
318 struct PP_Size* input_visible_size,
319 PP_VideoProfile* output_profile,
320 uint32_t* bitrate,
321 PP_HardwareAcceleration* acceleration) {
322 IPC::Message msg;
323 if (!sink().GetFirstResourceCallMatching(
324 PpapiHostMsg_VideoEncoder_Initialize::ID, params, &msg))
325 return false;
326 sink().ClearMessages();
327 return UnpackMessage<PpapiHostMsg_VideoEncoder_Initialize>(
328 msg, input_format, input_visible_size, output_profile, bitrate,
329 acceleration);
330 }
331
332 bool CheckGetVideoFramesMsg(ResourceMessageCallParams* params) {
333 IPC::Message msg;
334 if (!sink().GetFirstResourceCallMatching(
335 PpapiHostMsg_VideoEncoder_GetVideoFrames::ID, params, &msg))
336 return false;
337 sink().ClearMessages();
338 return true;
339 }
340
341 bool CheckEncodeMsg(ResourceMessageCallParams* params,
342 uint32_t* frame_id,
343 bool* keyframe) {
344 IPC::Message msg;
345 if (!sink().GetFirstResourceCallMatching(
346 PpapiHostMsg_VideoEncoder_Encode::ID, params, &msg))
347 return false;
348 sink().ClearMessages();
349 return UnpackMessage<PpapiHostMsg_VideoEncoder_Encode>(msg, frame_id,
350 keyframe);
351 }
352
353 bool CheckRecycleBitstreamBufferMsg(ResourceMessageCallParams* params,
354 uint32_t* buffer_id) {
355 IPC::Message msg;
356 if (!sink().GetFirstResourceCallMatching(
357 PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer::ID, params, &msg))
358 return false;
359 sink().ClearMessages();
360 return UnpackMessage<PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer>(
361 msg, buffer_id);
362 }
363
364 bool CheckRequestEncodeingParametersChangeMsg(
365 ResourceMessageCallParams* params,
366 uint32_t* bitrate,
367 uint32_t* framerate) {
368 IPC::Message msg;
369 if (!sink().GetFirstResourceCallMatching(
370 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange::ID,
371 params, &msg))
372 return false;
373 sink().ClearMessages();
374 return UnpackMessage<
375 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange>(msg, bitrate,
376 framerate);
377 }
378
379 bool CheckIsVideoFrame(PP_Resource video_frame) {
380 return thunk::GetPPB_VideoFrame_0_1_Thunk()->IsVideoFrame(video_frame);
381 }
382
383 private:
384 bool CheckMsg(ResourceMessageCallParams* params, int id) {
385 IPC::Message msg;
386 if (!sink().GetFirstResourceCallMatching(id, params, &msg))
387 return false;
388 sink().ClearMessages();
389 return true;
390 }
391
392 const PPB_VideoEncoder_0_1* encoder_iface_;
393
394 ScopedVector<base::SharedMemory> shared_memory_bitstreams_;
395 scoped_ptr<base::SharedMemory> shared_memory_frames_;
396
397 char decode_buffer_[kDecodeBufferSize];
398 };
399
400 void* ForwardUserData(void* user_data,
401 uint32_t element_count,
402 uint32_t element_size) {
403 return user_data;
404 }
405
406 } // namespace
407
408 TEST_F(VideoEncoderResourceTest, GetSupportedProfiles) {
409 // Verifies that GetSupportedProfiles calls into the renderer and
410 // the we get the right results back.
411 {
412 LockingResourceReleaser encoder(CreateEncoder());
413 std::vector<PP_VideoProfileDescription> profiles;
414 profiles.resize(2);
415 PP_ArrayOutput output;
416 output.user_data = &profiles[0];
417 output.GetDataBuffer = ForwardUserData;
418 ResourceMessageCallParams params;
419 MockCompletionCallback cb;
420 int32_t result = encoder_iface()->GetSupportedProfiles(
421 encoder.get(), output, PP_MakeOptionalCompletionCallback(
422 &MockCompletionCallback::Callback, &cb));
423 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
424 ASSERT_TRUE(CheckGetSupportedProfilesMsg(&params));
425
426 std::vector<PP_VideoProfileDescription> profiles_response;
427 PP_VideoProfileDescription profile;
428 profile.profile = PP_VIDEOPROFILE_H264MAIN;
429 profile.max_resolution.width = 1920;
430 profile.max_resolution.height = 1080;
431 profile.max_framerate_numerator = 30;
432 profile.max_framerate_denominator = 1;
433 profiles_response.push_back(profile);
434 profile.profile = PP_VIDEOPROFILE_VP8_ANY;
435 profile.max_resolution.width = 1920;
436 profile.max_resolution.height = 1080;
437 profile.max_framerate_numerator = 30;
438 profile.max_framerate_denominator = 1;
439 profiles_response.push_back(profile);
440
441 SendGetSupportedProfilesReply(params, profiles_response);
442 ASSERT_EQ(PP_OK, cb.result());
443
444 ASSERT_EQ(profiles_response.size(), profiles.size());
445 ASSERT_EQ(0, memcmp(&profiles[0], &profiles_response[0],
446 sizeof(PP_VideoProfileDescription) * 2));
447 }
448 }
449
450 TEST_F(VideoEncoderResourceTest, InitializeFailure) {
451 {
452 // Verify the initialize callback is called in case of failure.
453 LockingResourceReleaser encoder(CreateEncoder());
454 ResourceMessageCallParams params;
455 PP_Size size = kSize;
456 MockCompletionCallback cb;
457 int32_t result = encoder_iface()->Initialize(
458 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
459 PP_VIDEOPROFILE_H264MAIN, kBitrate,
460 PP_HARDWAREACCELERATION_WITHFALLBACK,
461 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
462 &cb));
463 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
464
465 PP_VideoFrame_Format input_format;
466 PP_Size input_visible_size;
467 PP_VideoProfile output_profile;
468 uint32_t bitrate;
469 PP_HardwareAcceleration acceleration;
470 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
471 &output_profile, &bitrate, &acceleration));
472 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
473 ASSERT_EQ(size.width, input_visible_size.width);
474 ASSERT_EQ(size.height, input_visible_size.height);
475 ASSERT_EQ(kBitrate, bitrate);
476 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
477 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
478
479 SendReply(params, PP_ERROR_NOTSUPPORTED,
480 PpapiPluginMsg_VideoEncoder_InitializeReply(0, 0, 0, size));
481 ASSERT_TRUE(cb.called());
482 ASSERT_EQ(PP_ERROR_NOTSUPPORTED, cb.result());
483 }
484 {
485 // Verify the initialize callback is called in case of error
486 // notification.
487 LockingResourceReleaser encoder(CreateEncoder());
488 ResourceMessageCallParams params;
489 PP_Size size = kSize;
490 MockCompletionCallback cb;
491 int32_t result = encoder_iface()->Initialize(
492 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
493 PP_VIDEOPROFILE_H264MAIN, kBitrate,
494 PP_HARDWAREACCELERATION_WITHFALLBACK,
495 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
496 &cb));
497 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
498
499 PP_VideoFrame_Format input_format;
500 PP_Size input_visible_size;
501 PP_VideoProfile output_profile;
502 uint32_t bitrate;
503 PP_HardwareAcceleration acceleration;
504 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
505 &output_profile, &bitrate, &acceleration));
506 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
507 ASSERT_EQ(kSize.width, input_visible_size.width);
508 ASSERT_EQ(kSize.height, input_visible_size.height);
509 ASSERT_EQ(kBitrate, bitrate);
510 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
511 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
512
513 ResourceMessageCallParams error_params(encoder.get(), 0);
514 SendNotifyError(error_params, PP_ERROR_FAILED);
515 ASSERT_TRUE(cb.called());
516 ASSERT_EQ(PP_ERROR_FAILED, cb.result());
517 }
518 }
519
520 TEST_F(VideoEncoderResourceTest, InitializeSuccess) {
521 {
522 // Verify the initialize callback is called when initialization is
523 // successfull.
524 LockingResourceReleaser encoder(CreateEncoder());
525 ResourceMessageCallParams params;
526 PP_Size size = kSize;
527 const uint32_t kBitrate = 420000;
528 MockCompletionCallback cb;
529 int32_t result = encoder_iface()->Initialize(
530 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
531 PP_VIDEOPROFILE_H264MAIN, kBitrate,
532 PP_HARDWAREACCELERATION_WITHFALLBACK,
533 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
534 &cb));
535 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
536
537 PP_VideoFrame_Format input_format;
538 PP_Size input_visible_size;
539 PP_VideoProfile output_profile;
540 uint32_t bitrate;
541 PP_HardwareAcceleration acceleration;
542 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
543 &output_profile, &bitrate, &acceleration));
544 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format);
545 ASSERT_EQ(kSize.width, input_visible_size.width);
546 ASSERT_EQ(kSize.height, input_visible_size.height);
547 ASSERT_EQ(kBitrate, bitrate);
548 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
549 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
550
551 CreateBitstreamSharedMemory(kBitstreamBufferSize, kBitstreamBufferNb);
552 SendInitializeReply(params, kBitstreamBufferNb, kBitstreamBufferSize,
553 kVideoFrameNb, size);
554
555 ASSERT_TRUE(cb.called());
556 ASSERT_EQ(PP_OK, cb.result());
557
558 PP_Size coded_size;
559 CallGetFrameCodedSize(encoder.get(), &coded_size);
560 ASSERT_EQ(kSize.width, coded_size.width);
561 ASSERT_EQ(kSize.height, coded_size.height);
562 ASSERT_EQ(static_cast<int32_t>(kVideoFrameNb),
563 CallGetFramesRequired(encoder.get()));
564 }
565 }
566
567 TEST_F(VideoEncoderResourceTest, Uninitialized) {
568 // Operations on uninitialized encoders should fail.
569 LockingResourceReleaser encoder(CreateEncoder());
570
571 ASSERT_EQ(PP_ERROR_FAILED, CallGetFramesRequired(encoder.get()));
572
573 PP_Size size;
574 ASSERT_EQ(PP_ERROR_FAILED, CallGetFrameCodedSize(encoder.get(), &size));
575
576 MockCompletionCallback uncalled_cb;
577 PP_Resource video_frame = 0;
578 ASSERT_EQ(PP_ERROR_FAILED,
579 CallGetVideoFrame(encoder.get(), &video_frame, &uncalled_cb));
580 ASSERT_FALSE(uncalled_cb.called());
581 ASSERT_EQ(0, video_frame);
582
583 ASSERT_EQ(PP_ERROR_FAILED,
584 CallEncode(encoder.get(), video_frame, PP_FALSE, &uncalled_cb));
585 ASSERT_FALSE(uncalled_cb.called());
586
587 PP_BitstreamBuffer bitstream_buffer;
588 ASSERT_EQ(
589 PP_ERROR_FAILED,
590 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, &uncalled_cb));
591 ASSERT_FALSE(uncalled_cb.called());
592
593 ResourceMessageCallParams params;
594 uint32_t buffer_id;
595 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
596 ASSERT_FALSE(CheckRecycleBitstreamBufferMsg(&params, &buffer_id));
597
598 uint32_t bitrate, framerate;
599 CallRequestEncodingParametersChange(encoder.get(), 0, 0);
600 ASSERT_FALSE(
601 CheckRequestEncodeingParametersChangeMsg(&params, &bitrate, &framerate));
602 }
603
604 TEST_F(VideoEncoderResourceTest, InitializeAndGetVideoFrame) {
605 // Verify that we can pull the right number of video frames before
606 // the proxy makes us wait.
607 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
608 ResourceMessageCallParams params;
609 PP_Resource video_frames[kVideoFrameNb + 1];
610 MockCompletionCallback cb;
611
612 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
613 CallGetVideoFrame(encoder.get(), &video_frames[0], &cb));
614 ASSERT_FALSE(cb.called());
615 ASSERT_TRUE(CheckGetVideoFramesMsg(&params));
616
617 uint32_t frame_length = kSize.width * kSize.height * 2;
618 CreateVideoFramesSharedMemory(frame_length, kVideoFrameNb);
619 SendGetVideoFramesReply(params, kVideoFrameNb, frame_length, kSize);
620
621 for (uint32_t i = 1; i < kVideoFrameNb; ++i) {
622 cb.Reset();
623 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
624 CallGetVideoFrame(encoder.get(), &video_frames[i], &cb));
625 ASSERT_TRUE(cb.called());
626 ASSERT_EQ(PP_OK, cb.result());
627 ASSERT_TRUE(CheckIsVideoFrame(video_frames[i]));
628 }
629
630 cb.Reset();
631 ASSERT_EQ(
632 PP_OK_COMPLETIONPENDING,
633 CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameNb], &cb));
634 ASSERT_FALSE(cb.called());
635
636 // Unlock the GetVideoFrame callback.
637 MockCompletionCallback encode_cb;
638 ASSERT_EQ(
639 PP_OK_COMPLETIONPENDING,
640 CallCompleteEncode(encoder.get(), video_frames[0], PP_FALSE, &encode_cb));
641 ASSERT_TRUE(encode_cb.called());
642 ASSERT_EQ(PP_OK, encode_cb.result());
643 ASSERT_TRUE(cb.called());
644
645 {
646 ProxyAutoLock lock;
647 for (uint32_t i = 0; i < (kVideoFrameNb + 1); ++i)
648 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
649 video_frames[i]);
650 }
651 }
652
653 TEST_F(VideoEncoderResourceTest, Encode) {
654 // Check Encode() calls into the renderer.
655 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
656
657 PP_Resource video_frame;
658 MockCompletionCallback get_frame_cb;
659 ;
660 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
661 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
662 ASSERT_TRUE(get_frame_cb.called());
663 ASSERT_EQ(PP_OK, get_frame_cb.result());
664
665 MockCompletionCallback encode_cb;
666 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
667 CallEncode(encoder.get(), video_frame, PP_TRUE, &encode_cb));
668 ASSERT_FALSE(encode_cb.called());
669
670 ResourceMessageCallParams params;
671 uint32_t frame_id;
672 bool force_frame;
673 ASSERT_TRUE(CheckEncodeMsg(&params, &frame_id, &force_frame));
674
675 SendEncodeReply(params, frame_id);
676
677 ASSERT_TRUE(encode_cb.called());
678 ASSERT_EQ(PP_OK, encode_cb.result());
679 }
680
681 TEST_F(VideoEncoderResourceTest, EncodeAndGetVideoFrame) {
682 // Check the encoding loop works well.
683 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
684 ResourceMessageCallParams params;
685 PP_Resource video_frame;
686 MockCompletionCallback get_frame_cb, encode_cb;
687
688 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
689 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
690 ASSERT_TRUE(get_frame_cb.called());
691 ASSERT_EQ(PP_OK, get_frame_cb.result());
692
693 for (uint32_t i = 1; i < 20 * kVideoFrameNb; ++i) {
694 encode_cb.Reset();
695 ASSERT_EQ(
696 PP_OK_COMPLETIONPENDING,
697 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
698 ASSERT_TRUE(encode_cb.called());
699 ASSERT_EQ(PP_OK, encode_cb.result());
700
701 get_frame_cb.Reset();
702 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
703 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
704 ASSERT_TRUE(get_frame_cb.called());
705 ASSERT_EQ(PP_OK, get_frame_cb.result());
706 ASSERT_TRUE(CheckIsVideoFrame(video_frame));
707 }
708
709 ASSERT_EQ(
710 PP_OK_COMPLETIONPENDING,
711 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
712 ASSERT_TRUE(encode_cb.called());
713 ASSERT_EQ(PP_OK, encode_cb.result());
714 }
715
716 TEST_F(VideoEncoderResourceTest, GetBitstreamBuffer) {
717 // Verify that the GetBitstreamBuffer callback is fired whenever the
718 // renderer signals a buffer is available.
719 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
720
721 MockCompletionCallback get_bitstream_buffer_cb;
722 PP_BitstreamBuffer bitstream_buffer;
723 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
724 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
725 &get_bitstream_buffer_cb));
726 ASSERT_FALSE(get_bitstream_buffer_cb.called());
727
728 ResourceMessageCallParams buffer_params(encoder.get(), 0);
729 SendBitstreamBufferReady(buffer_params, 0, 10, true);
730
731 ASSERT_TRUE(get_bitstream_buffer_cb.called());
732 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
733 ASSERT_EQ(static_cast<uint32_t>(10), bitstream_buffer.size);
734 ASSERT_EQ(PP_TRUE, bitstream_buffer.key_frame);
735 }
736
737 TEST_F(VideoEncoderResourceTest, RecycleBitstreamBuffer) {
738 // Verify that we signal the renderer that a bitstream buffer has been
739 // recycled.
740 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
741
742 MockCompletionCallback get_bitstream_buffer_cb;
743 PP_BitstreamBuffer bitstream_buffer;
744 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
745 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
746 &get_bitstream_buffer_cb));
747 ASSERT_FALSE(get_bitstream_buffer_cb.called());
748
749 ResourceMessageCallParams buffer_params(encoder.get(), 0);
750 SendBitstreamBufferReady(buffer_params, kBitstreamBufferNb - 1, 10, true);
751
752 ASSERT_TRUE(get_bitstream_buffer_cb.called());
753 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
754
755 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
756
757 ResourceMessageCallParams recycle_params;
758 uint32_t buffer_id;
759 ASSERT_TRUE(CheckRecycleBitstreamBufferMsg(&recycle_params, &buffer_id));
760 ASSERT_EQ(kBitstreamBufferNb - 1, buffer_id);
761 }
762
763 TEST_F(VideoEncoderResourceTest, RequestEncodingParametersChange) {
764 // Check encoding parameter changes are correctly sent to the
765 // renderer.
766 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
767
768 CallRequestEncodingParametersChange(encoder.get(), 1, 2);
769 ResourceMessageCallParams params;
770 uint32_t bitrate, framerate;
771 ASSERT_TRUE(
772 CheckRequestEncodeingParametersChangeMsg(&params, &bitrate, &framerate));
773 ASSERT_EQ(static_cast<uint32_t>(1), bitrate);
774 ASSERT_EQ(static_cast<uint32_t>(2), framerate);
775 }
776
777 TEST_F(VideoEncoderResourceTest, NotifyError) {
778 // Check an error from the encoder calls back GetVideoFrame and
779 // GetBitstreamBuffer callbacks.
780 {
781 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
782
783 MockCompletionCallback get_frame_cb1;
784 PP_Resource video_frame1;
785 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
786 CallGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb1));
787 ASSERT_FALSE(get_frame_cb1.called());
788 MockCompletionCallback get_frame_cb2;
789 PP_Resource video_frame2;
790 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
791 CallGetVideoFrame(encoder.get(), &video_frame2, &get_frame_cb2));
792 ASSERT_FALSE(get_frame_cb2.called());
793
794 MockCompletionCallback get_bitstream_buffer_cb;
795 PP_BitstreamBuffer bitstream_buffer;
796 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
797 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
798 &get_bitstream_buffer_cb));
799
800 ResourceMessageCallParams error_params(encoder.get(), 0);
801 SendNotifyError(error_params, PP_ERROR_FAILED);
802
803 ASSERT_TRUE(get_frame_cb1.called());
804 ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb1.result());
805 ASSERT_TRUE(get_frame_cb2.called());
806 ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb2.result());
807 ASSERT_TRUE(get_bitstream_buffer_cb.called());
808 ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result());
809 }
810 }
811
812 } // namespace proxy
813 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698