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

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: Update after bbudge's review 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, kBitstreamBufferSize, kVideoFrameNb, size);
154
155 if (!cb.called() || cb.result() != PP_OK)
156 return 0;
157
158 return encoder;
159 }
160
161 int32_t CallGetFramesRequired(PP_Resource pp_encoder) {
162 return encoder_iface()->GetFramesRequired(pp_encoder);
163 }
164
165 int32_t CallGetFrameCodedSize(PP_Resource pp_encoder, PP_Size* coded_size) {
166 return encoder_iface()->GetFrameCodedSize(pp_encoder, coded_size);
167 }
168
169 int32_t CallGetVideoFrame(PP_Resource pp_encoder,
170 PP_Resource* video_frame,
171 MockCompletionCallback* cb) {
172 return encoder_iface()->GetVideoFrame(
173 pp_encoder, video_frame, PP_MakeOptionalCompletionCallback(
174 &MockCompletionCallback::Callback, cb));
175 }
176
177 int32_t CallFirstGetVideoFrame(PP_Resource pp_encoder,
178 PP_Resource* video_frame,
179 MockCompletionCallback* cb) {
180 int32_t result = encoder_iface()->GetVideoFrame(
181 pp_encoder, video_frame, PP_MakeOptionalCompletionCallback(
182 &MockCompletionCallback::Callback, cb));
183 if (result != PP_OK_COMPLETIONPENDING)
184 return result;
185
186 ResourceMessageCallParams params;
187 CheckGetVideoFramesMsg(&params);
188
189 uint32_t frame_length = kSize.width * kSize.height * 2;
190 CreateVideoFramesSharedMemory(frame_length, kVideoFrameNb);
191 SendGetVideoFramesReply(params, kVideoFrameNb, frame_length, kSize);
192
193 return result;
194 }
195
196 int32_t CallEncode(PP_Resource pp_encoder,
197 PP_Resource video_frame,
198 PP_Bool force_keyframe,
199 MockCompletionCallback* cb) {
200 return encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe,
201 PP_MakeOptionalCompletionCallback(
202 &MockCompletionCallback::Callback, cb));
203 }
204
205 int32_t CallCompleteEncode(PP_Resource pp_encoder,
206 PP_Resource video_frame,
207 PP_Bool force_keyframe,
208 MockCompletionCallback* cb) {
209 int32_t result =
210 encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe,
211 PP_MakeOptionalCompletionCallback(
212 &MockCompletionCallback::Callback, cb));
213 if (result != PP_OK_COMPLETIONPENDING)
214 return result;
215
216 ResourceMessageCallParams params;
217 uint32_t frame_id;
218 bool forced_keyframe;
219 if (!CheckEncodeMsg(&params, &frame_id, &forced_keyframe))
220 return PP_ERROR_FAILED;
221
222 SendEncodeReply(params, frame_id);
223
224 return result;
225 }
226
227 int32_t CallGetBitstreamBuffer(PP_Resource pp_encoder,
228 PP_BitstreamBuffer* bitstream_buffer,
229 MockCompletionCallback* cb) {
230 return encoder_iface()->GetBitstreamBuffer(
231 pp_encoder, bitstream_buffer,
232 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
233 cb));
234 }
235
236 void CallRecycleBitstreamBuffer(PP_Resource pp_encoder,
237 const PP_BitstreamBuffer& buffer) {
238 encoder_iface()->RecycleBitstreamBuffer(pp_encoder, &buffer);
239 }
240
241 void CallRequestEncodingParametersChange(PP_Resource pp_encoder,
242 uint32_t bitrate,
243 uint32_t framerate) {
244 encoder_iface()->RequestEncodingParametersChange(pp_encoder, bitrate,
245 framerate);
246 }
247
248 void SendGetSupportedProfilesReply(
249 const ResourceMessageCallParams& params,
250 const std::vector<PP_VideoProfileDescription>& profiles) {
251 SendReply(params, PP_OK,
252 PpapiPluginMsg_VideoEncoder_GetSupportedProfilesReply(profiles));
253 }
254
255 void SendInitializeReply(const ResourceMessageCallParams& params,
256 uint32_t buffer_length,
257 uint32_t input_frame_count,
258 const PP_Size& coded_size) {
259 std::vector<SerializedHandle> handles;
260 for (base::SharedMemory* mem : shared_memory_bitstreams_) {
261 ASSERT_EQ(mem->requested_size(), buffer_length);
262 base::SharedMemoryHandle handle;
263
264 ASSERT_TRUE(
265 mem->ShareToProcess(base::Process::Current().Handle(), &handle));
266 handles.push_back(SerializedHandle(handle, buffer_length));
267 }
268 SendReplyWithHandles(
269 params, PP_OK,
270 PpapiPluginMsg_VideoEncoder_InitializeReply(
271 buffer_length, input_frame_count, coded_size),
272 handles);
273 }
274
275 void SendGetVideoFramesReply(const ResourceMessageCallParams& params,
276 uint32_t frame_count,
277 uint32_t frame_length,
278 const PP_Size& size) {
279 base::SharedMemoryHandle handle;
280 ASSERT_TRUE(shared_memory_frames_->ShareToProcess(
281 base::Process::Current().Handle(), &handle));
282 SendReplyWithHandle(
283 params, PP_OK, PpapiPluginMsg_VideoEncoder_GetVideoFramesReply(
284 frame_count, frame_length, size),
285 SerializedHandle(handle, shared_memory_frames_->requested_size()));
286 }
287
288 void SendEncodeReply(const ResourceMessageCallParams& params,
289 uint32_t frame_id) {
290 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_EncodeReply(frame_id));
291 }
292
293 void SendBitstreamBufferReady(const ResourceMessageCallParams& params,
294 uint32_t buffer_id,
295 uint32_t buffer_size,
296 bool keyframe) {
297 SendReply(params, PP_OK,
298 PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
299 buffer_id, buffer_size, PP_FromBool(keyframe)));
300 }
301
302 void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) {
303 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_NotifyError(error));
304 }
305
306 bool CheckGetSupportedProfilesMsg(ResourceMessageCallParams* params) {
307 IPC::Message msg;
308 if (!sink().GetFirstResourceCallMatching(
309 PpapiHostMsg_VideoEncoder_GetSupportedProfiles::ID, params, &msg))
310 return false;
311 return true;
312 }
313
314 bool CheckInitializeMsg(ResourceMessageCallParams* params,
315 PP_VideoFrame_Format* input_format,
316 struct PP_Size* input_visible_size,
317 PP_VideoProfile* output_profile,
318 uint32_t* bitrate,
319 PP_HardwareAcceleration* acceleration) {
320 IPC::Message msg;
321 if (!sink().GetFirstResourceCallMatching(
322 PpapiHostMsg_VideoEncoder_Initialize::ID, params, &msg))
323 return false;
324 sink().ClearMessages();
325 return UnpackMessage<PpapiHostMsg_VideoEncoder_Initialize>(
326 msg, input_format, input_visible_size, output_profile, bitrate,
327 acceleration);
328 }
329
330 bool CheckGetVideoFramesMsg(ResourceMessageCallParams* params) {
331 IPC::Message msg;
332 if (!sink().GetFirstResourceCallMatching(
333 PpapiHostMsg_VideoEncoder_GetVideoFrames::ID, params, &msg))
334 return false;
335 sink().ClearMessages();
336 return true;
337 }
338
339 bool CheckEncodeMsg(ResourceMessageCallParams* params,
340 uint32_t* frame_id,
341 bool* keyframe) {
342 IPC::Message msg;
343 if (!sink().GetFirstResourceCallMatching(
344 PpapiHostMsg_VideoEncoder_Encode::ID, params, &msg))
345 return false;
346 sink().ClearMessages();
347 return UnpackMessage<PpapiHostMsg_VideoEncoder_Encode>(msg, frame_id,
348 keyframe);
349 }
350
351 bool CheckRecycleBitstreamBufferMsg(ResourceMessageCallParams* params,
352 uint32_t* buffer_id) {
353 IPC::Message msg;
354 if (!sink().GetFirstResourceCallMatching(
355 PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer::ID, params, &msg))
356 return false;
357 sink().ClearMessages();
358 return UnpackMessage<PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer>(
359 msg, buffer_id);
360 }
361
362 bool CheckRequestEncodeingParametersChangeMsg(
363 ResourceMessageCallParams* params,
364 uint32_t* bitrate,
365 uint32_t* framerate) {
366 IPC::Message msg;
367 if (!sink().GetFirstResourceCallMatching(
368 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange::ID,
369 params, &msg))
370 return false;
371 sink().ClearMessages();
372 return UnpackMessage<
373 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange>(msg, bitrate,
374 framerate);
375 }
376
377 bool CheckIsVideoFrame(PP_Resource video_frame) {
378 return thunk::GetPPB_VideoFrame_0_1_Thunk()->IsVideoFrame(video_frame);
379 }
380
381 private:
382 bool CheckMsg(ResourceMessageCallParams* params, int id) {
383 IPC::Message msg;
384 if (!sink().GetFirstResourceCallMatching(id, params, &msg))
385 return false;
386 sink().ClearMessages();
387 return true;
388 }
389
390 const PPB_VideoEncoder_0_1* encoder_iface_;
391
392 ScopedVector<base::SharedMemory> shared_memory_bitstreams_;
393 scoped_ptr<base::SharedMemory> shared_memory_frames_;
394
395 char decode_buffer_[kDecodeBufferSize];
396 };
397
398 void* ForwardUserData(void* user_data,
399 uint32_t element_count,
400 uint32_t element_size) {
401 return user_data;
402 }
403
404 } // namespace
405
406 TEST_F(VideoEncoderResourceTest, GetSupportedProfiles) {
407 // Verifies that GetSupportedProfiles calls into the renderer and
408 // the we get the right results back.
409 {
410 LockingResourceReleaser encoder(CreateEncoder());
411 std::vector<PP_VideoProfileDescription> profiles;
412 profiles.resize(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(&params));
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(profiles_response.size(), profiles.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 = kSize;
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(&params, &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 SendReply(params, PP_ERROR_NOTSUPPORTED,
478 PpapiPluginMsg_VideoEncoder_InitializeReply(0, 0, size));
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 = kSize;
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(&params, &input_format, &input_visible_size,
503 &output_profile, &bitrate, &acceleration));
504 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
505 ASSERT_EQ(kSize.width, input_visible_size.width);
506 ASSERT_EQ(kSize.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
518 TEST_F(VideoEncoderResourceTest, InitializeSuccess) {
519 {
520 // Verify the initialize callback is called when initialization is
521 // successfull.
522 LockingResourceReleaser encoder(CreateEncoder());
523 ResourceMessageCallParams params;
524 PP_Size size = kSize;
525 const uint32_t kBitrate = 420000;
526 MockCompletionCallback cb;
527 int32_t result = encoder_iface()->Initialize(
528 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
529 PP_VIDEOPROFILE_H264MAIN, kBitrate,
530 PP_HARDWAREACCELERATION_WITHFALLBACK,
531 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
532 &cb));
533 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
534
535 PP_VideoFrame_Format input_format;
536 PP_Size input_visible_size;
537 PP_VideoProfile output_profile;
538 uint32_t bitrate;
539 PP_HardwareAcceleration acceleration;
540 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
541 &output_profile, &bitrate, &acceleration));
542 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format);
543 ASSERT_EQ(kSize.width, input_visible_size.width);
544 ASSERT_EQ(kSize.height, input_visible_size.height);
545 ASSERT_EQ(kBitrate, bitrate);
546 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
547 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
548
549 CreateBitstreamSharedMemory(kBitstreamBufferSize, kBitstreamBufferNb);
550 SendInitializeReply(params, kBitstreamBufferSize, kVideoFrameNb, size);
551
552 ASSERT_TRUE(cb.called());
553 ASSERT_EQ(PP_OK, cb.result());
554
555 PP_Size coded_size;
556 CallGetFrameCodedSize(encoder.get(), &coded_size);
557 ASSERT_EQ(kSize.width, coded_size.width);
558 ASSERT_EQ(kSize.height, coded_size.height);
559 ASSERT_EQ(static_cast<int32_t>(kVideoFrameNb),
560 CallGetFramesRequired(encoder.get()));
561 }
562 }
563
564 TEST_F(VideoEncoderResourceTest, Uninitialized) {
565 // Operations on uninitialized encoders should fail.
566 LockingResourceReleaser encoder(CreateEncoder());
567
568 ASSERT_EQ(PP_ERROR_FAILED, CallGetFramesRequired(encoder.get()));
569
570 PP_Size size;
571 ASSERT_EQ(PP_ERROR_FAILED, CallGetFrameCodedSize(encoder.get(), &size));
572
573 MockCompletionCallback uncalled_cb;
574 PP_Resource video_frame = 0;
575 ASSERT_EQ(PP_ERROR_FAILED,
576 CallGetVideoFrame(encoder.get(), &video_frame, &uncalled_cb));
577 ASSERT_FALSE(uncalled_cb.called());
578 ASSERT_EQ(0, video_frame);
579
580 ASSERT_EQ(PP_ERROR_FAILED,
581 CallEncode(encoder.get(), video_frame, PP_FALSE, &uncalled_cb));
582 ASSERT_FALSE(uncalled_cb.called());
583
584 PP_BitstreamBuffer bitstream_buffer;
585 ASSERT_EQ(
586 PP_ERROR_FAILED,
587 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, &uncalled_cb));
588 ASSERT_FALSE(uncalled_cb.called());
589
590 ResourceMessageCallParams params;
591 uint32_t buffer_id;
592 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
593 ASSERT_FALSE(CheckRecycleBitstreamBufferMsg(&params, &buffer_id));
594
595 uint32_t bitrate, framerate;
596 CallRequestEncodingParametersChange(encoder.get(), 0, 0);
597 ASSERT_FALSE(
598 CheckRequestEncodeingParametersChangeMsg(&params, &bitrate, &framerate));
599 }
600
601 TEST_F(VideoEncoderResourceTest, InitializeAndGetVideoFrame) {
602 // Verify that we can pull the right number of video frames before
603 // the proxy makes us wait.
604 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
605 ResourceMessageCallParams params;
606 PP_Resource video_frames[kVideoFrameNb + 1];
607 MockCompletionCallback cb;
608
609 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
610 CallGetVideoFrame(encoder.get(), &video_frames[0], &cb));
611 ASSERT_FALSE(cb.called());
612 ASSERT_TRUE(CheckGetVideoFramesMsg(&params));
613
614 uint32_t frame_length = kSize.width * kSize.height * 2;
615 CreateVideoFramesSharedMemory(frame_length, kVideoFrameNb);
616 SendGetVideoFramesReply(params, kVideoFrameNb, frame_length, kSize);
617
618 for (uint32_t i = 1; i < kVideoFrameNb; ++i) {
619 cb.Reset();
620 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
621 CallGetVideoFrame(encoder.get(), &video_frames[i], &cb));
622 ASSERT_TRUE(cb.called());
623 ASSERT_EQ(PP_OK, cb.result());
624 ASSERT_TRUE(CheckIsVideoFrame(video_frames[i]));
625 }
626
627 cb.Reset();
628 ASSERT_EQ(
629 PP_OK_COMPLETIONPENDING,
630 CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameNb], &cb));
631 ASSERT_FALSE(cb.called());
632
633 // Unlock the GetVideoFrame callback.
634 MockCompletionCallback encode_cb;
635 ASSERT_EQ(
636 PP_OK_COMPLETIONPENDING,
637 CallCompleteEncode(encoder.get(), video_frames[0], PP_FALSE, &encode_cb));
638 ASSERT_TRUE(encode_cb.called());
639 ASSERT_EQ(PP_OK, encode_cb.result());
640 ASSERT_TRUE(cb.called());
641
642 {
643 ProxyAutoLock lock;
644 for (uint32_t i = 0; i < (kVideoFrameNb + 1); ++i)
645 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
646 video_frames[i]);
647 }
648 }
649
650 TEST_F(VideoEncoderResourceTest, Encode) {
651 // Check Encode() calls into the renderer.
652 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
653
654 PP_Resource video_frame;
655 MockCompletionCallback get_frame_cb;
656 ;
657 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
658 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
659 ASSERT_TRUE(get_frame_cb.called());
660 ASSERT_EQ(PP_OK, get_frame_cb.result());
661
662 MockCompletionCallback encode_cb;
663 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
664 CallEncode(encoder.get(), video_frame, PP_TRUE, &encode_cb));
665 ASSERT_FALSE(encode_cb.called());
666
667 ResourceMessageCallParams params;
668 uint32_t frame_id;
669 bool force_frame;
670 ASSERT_TRUE(CheckEncodeMsg(&params, &frame_id, &force_frame));
671
672 SendEncodeReply(params, frame_id);
673
674 ASSERT_TRUE(encode_cb.called());
675 ASSERT_EQ(PP_OK, encode_cb.result());
676 }
677
678 TEST_F(VideoEncoderResourceTest, EncodeAndGetVideoFrame) {
679 // Check the encoding loop works well.
680 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
681 ResourceMessageCallParams params;
682 PP_Resource video_frame;
683 MockCompletionCallback get_frame_cb, encode_cb;
684
685 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
686 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
687 ASSERT_TRUE(get_frame_cb.called());
688 ASSERT_EQ(PP_OK, get_frame_cb.result());
689
690 for (uint32_t i = 1; i < 20 * kVideoFrameNb; ++i) {
691 encode_cb.Reset();
692 ASSERT_EQ(
693 PP_OK_COMPLETIONPENDING,
694 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
695 ASSERT_TRUE(encode_cb.called());
696 ASSERT_EQ(PP_OK, encode_cb.result());
697
698 get_frame_cb.Reset();
699 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
700 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
701 ASSERT_TRUE(get_frame_cb.called());
702 ASSERT_EQ(PP_OK, get_frame_cb.result());
703 ASSERT_TRUE(CheckIsVideoFrame(video_frame));
704 }
705
706 ASSERT_EQ(
707 PP_OK_COMPLETIONPENDING,
708 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
709 ASSERT_TRUE(encode_cb.called());
710 ASSERT_EQ(PP_OK, encode_cb.result());
711 }
712
713 TEST_F(VideoEncoderResourceTest, GetBitstreamBuffer) {
714 // Verify that the GetBitstreamBuffer callback is fired whenever the
715 // renderer signals a buffer is available.
716 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
717
718 MockCompletionCallback get_bitstream_buffer_cb;
719 PP_BitstreamBuffer bitstream_buffer;
720 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
721 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
722 &get_bitstream_buffer_cb));
723 ASSERT_FALSE(get_bitstream_buffer_cb.called());
724
725 ResourceMessageCallParams buffer_params(encoder.get(), 0);
726 SendBitstreamBufferReady(buffer_params, 0, 10, true);
727
728 ASSERT_TRUE(get_bitstream_buffer_cb.called());
729 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
730 ASSERT_EQ(static_cast<uint32_t>(10), bitstream_buffer.size);
731 ASSERT_EQ(PP_TRUE, bitstream_buffer.key_frame);
732 }
733
734 TEST_F(VideoEncoderResourceTest, RecycleBitstreamBuffer) {
735 // Verify that we signal the renderer that a bitstream buffer has been
736 // recycled.
737 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
738
739 MockCompletionCallback get_bitstream_buffer_cb;
740 PP_BitstreamBuffer bitstream_buffer;
741 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
742 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
743 &get_bitstream_buffer_cb));
744 ASSERT_FALSE(get_bitstream_buffer_cb.called());
745
746 ResourceMessageCallParams buffer_params(encoder.get(), 0);
747 SendBitstreamBufferReady(buffer_params, kBitstreamBufferNb - 1, 10, true);
748
749 ASSERT_TRUE(get_bitstream_buffer_cb.called());
750 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
751
752 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
753
754 ResourceMessageCallParams recycle_params;
755 uint32_t buffer_id;
756 ASSERT_TRUE(CheckRecycleBitstreamBufferMsg(&recycle_params, &buffer_id));
757 ASSERT_EQ(kBitstreamBufferNb - 1, buffer_id);
758 }
759
760 TEST_F(VideoEncoderResourceTest, RequestEncodingParametersChange) {
761 // Check encoding parameter changes are correctly sent to the
762 // renderer.
763 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
764
765 CallRequestEncodingParametersChange(encoder.get(), 1, 2);
766 ResourceMessageCallParams params;
767 uint32_t bitrate, framerate;
768 ASSERT_TRUE(
769 CheckRequestEncodeingParametersChangeMsg(&params, &bitrate, &framerate));
770 ASSERT_EQ(static_cast<uint32_t>(1), bitrate);
771 ASSERT_EQ(static_cast<uint32_t>(2), framerate);
772 }
773
774 TEST_F(VideoEncoderResourceTest, NotifyError) {
775 // Check an error from the encoder calls back GetVideoFrame and
776 // GetBitstreamBuffer callbacks.
777 {
778 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
779
780 MockCompletionCallback get_frame_cb1;
781 PP_Resource video_frame1;
782 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
783 CallGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb1));
784 ASSERT_FALSE(get_frame_cb1.called());
785 MockCompletionCallback get_frame_cb2;
786 PP_Resource video_frame2;
787 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
788 CallGetVideoFrame(encoder.get(), &video_frame2, &get_frame_cb2));
789 ASSERT_FALSE(get_frame_cb2.called());
790
791 MockCompletionCallback get_bitstream_buffer_cb;
792 PP_BitstreamBuffer bitstream_buffer;
793 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
794 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
795 &get_bitstream_buffer_cb));
796
797 ResourceMessageCallParams error_params(encoder.get(), 0);
798 SendNotifyError(error_params, PP_ERROR_FAILED);
799
800 ASSERT_TRUE(get_frame_cb1.called());
801 ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb1.result());
802 ASSERT_TRUE(get_frame_cb2.called());
803 ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb2.result());
804 ASSERT_TRUE(get_bitstream_buffer_cb.called());
805 ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result());
806 }
807 }
808
809 } // namespace proxy
810 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698