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

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: Deal with Encode() callbacks in the proxy 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;
bbudge 2015/02/13 01:45:54 I don't think you need these definitions.
llandwerlin-old 2015/02/13 20:12:26 Done.
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;
bbudge 2015/02/13 01:45:54 It took me a while to get that Nb is 'Count'.
llandwerlin-old 2015/02/13 20:12:26 Done.
71 const uint32_t kBitrate = 200000;
72
73 const PP_Size kSize = {640, 480};
bbudge 2015/02/13 01:45:54 kFrameSize?
llandwerlin-old 2015/02/13 20:12:26 Done.
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 CallClose(PP_Resource pp_encoder) {
249 encoder_iface()->Close(pp_encoder);
250 }
251
252 void SendGetSupportedProfilesReply(
253 const ResourceMessageCallParams& params,
254 const std::vector<PP_VideoProfileDescription>& profiles) {
255 SendReply(params, PP_OK,
256 PpapiPluginMsg_VideoEncoder_GetSupportedProfilesReply(profiles));
257 }
258
259 void SendInitializeReply(const ResourceMessageCallParams& params,
260 uint32_t buffer_length,
261 uint32_t input_frame_count,
262 const PP_Size& coded_size) {
263 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_InitializeReply());
264 std::vector<SerializedHandle> handles;
265 for (base::SharedMemory* mem : shared_memory_bitstreams_) {
266 ASSERT_EQ(mem->requested_size(), buffer_length);
267 base::SharedMemoryHandle handle;
268
269 ASSERT_TRUE(
270 mem->ShareToProcess(base::Process::Current().Handle(), &handle));
271 handles.push_back(SerializedHandle(handle, buffer_length));
272 }
273 SendReplyWithHandles(params, PP_OK,
274 PpapiPluginMsg_VideoEncoder_BitstreamBuffers(
275 buffer_length, input_frame_count, coded_size),
276 handles);
277 }
278
279 void SendGetVideoFramesReply(const ResourceMessageCallParams& params,
280 uint32_t frame_count,
281 uint32_t frame_length,
282 const PP_Size& size) {
283 base::SharedMemoryHandle handle;
284 ASSERT_TRUE(shared_memory_frames_->ShareToProcess(
285 base::Process::Current().Handle(), &handle));
286 SendReplyWithHandle(
287 params, PP_OK, PpapiPluginMsg_VideoEncoder_GetVideoFramesReply(
288 frame_count, frame_length, size),
289 SerializedHandle(handle, shared_memory_frames_->requested_size()));
290 }
291
292 void SendEncodeReply(const ResourceMessageCallParams& params,
293 uint32_t frame_id) {
294 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_EncodeReply(frame_id));
295 }
296
297 void SendBitstreamBufferReady(const ResourceMessageCallParams& params,
298 uint32_t buffer_id,
299 uint32_t buffer_size,
300 bool keyframe) {
301 SendReply(params, PP_OK,
302 PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
303 buffer_id, buffer_size, PP_FromBool(keyframe)));
304 }
305
306 void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) {
307 SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_NotifyError(error));
308 }
309
310 bool CheckGetSupportedProfilesMsg(ResourceMessageCallParams* params) {
311 IPC::Message msg;
312 if (!sink().GetFirstResourceCallMatching(
313 PpapiHostMsg_VideoEncoder_GetSupportedProfiles::ID, params, &msg))
314 return false;
315 return true;
316 }
317
318 bool CheckInitializeMsg(ResourceMessageCallParams* params,
319 PP_VideoFrame_Format* input_format,
320 struct PP_Size* input_visible_size,
321 PP_VideoProfile* output_profile,
322 uint32_t* bitrate,
323 PP_HardwareAcceleration* acceleration) {
324 IPC::Message msg;
325 if (!sink().GetFirstResourceCallMatching(
326 PpapiHostMsg_VideoEncoder_Initialize::ID, params, &msg))
327 return false;
328 sink().ClearMessages();
329 return UnpackMessage<PpapiHostMsg_VideoEncoder_Initialize>(
330 msg, input_format, input_visible_size, output_profile, bitrate,
331 acceleration);
332 }
333
334 bool CheckGetVideoFramesMsg(ResourceMessageCallParams* params) {
335 IPC::Message msg;
336 if (!sink().GetFirstResourceCallMatching(
337 PpapiHostMsg_VideoEncoder_GetVideoFrames::ID, params, &msg))
338 return false;
339 sink().ClearMessages();
340 return true;
341 }
342
343 bool CheckEncodeMsg(ResourceMessageCallParams* params,
344 uint32_t* frame_id,
345 bool* keyframe) {
346 IPC::Message msg;
347 if (!sink().GetFirstResourceCallMatching(
348 PpapiHostMsg_VideoEncoder_Encode::ID, params, &msg))
349 return false;
350 sink().ClearMessages();
351 return UnpackMessage<PpapiHostMsg_VideoEncoder_Encode>(msg, frame_id,
352 keyframe);
353 }
354
355 bool CheckRecycleBitstreamBufferMsg(ResourceMessageCallParams* params,
356 uint32_t* buffer_id) {
357 IPC::Message msg;
358 if (!sink().GetFirstResourceCallMatching(
359 PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer::ID, params, &msg))
360 return false;
361 sink().ClearMessages();
362 return UnpackMessage<PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer>(
363 msg, buffer_id);
364 }
365
366 bool CheckRequestEncodeingParametersChangeMsg(
bbudge 2015/02/13 01:45:53 s/Encodeing/Encoding
llandwerlin-old 2015/02/13 20:12:26 Done.
367 ResourceMessageCallParams* params,
368 uint32_t* bitrate,
369 uint32_t* framerate) {
370 IPC::Message msg;
371 if (!sink().GetFirstResourceCallMatching(
372 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange::ID,
373 params, &msg))
374 return false;
375 sink().ClearMessages();
376 return UnpackMessage<
377 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange>(msg, bitrate,
378 framerate);
379 }
380
381 bool CheckIsVideoFrame(PP_Resource video_frame) {
382 return thunk::GetPPB_VideoFrame_0_1_Thunk()->IsVideoFrame(video_frame);
383 }
384
385 private:
386 bool CheckMsg(ResourceMessageCallParams* params, int id) {
bbudge 2015/02/13 01:45:53 Not used
llandwerlin-old 2015/02/13 20:12:26 Done.
387 IPC::Message msg;
388 if (!sink().GetFirstResourceCallMatching(id, params, &msg))
389 return false;
390 sink().ClearMessages();
391 return true;
392 }
393
394 const PPB_VideoEncoder_0_1* encoder_iface_;
395
396 ScopedVector<base::SharedMemory> shared_memory_bitstreams_;
397 scoped_ptr<base::SharedMemory> shared_memory_frames_;
398
399 char decode_buffer_[kDecodeBufferSize];
bbudge 2015/02/13 01:45:54 Not used.
llandwerlin-old 2015/02/13 20:12:26 Done.
400 };
401
402 void* ForwardUserData(void* user_data,
403 uint32_t element_count,
404 uint32_t element_size) {
405 return user_data;
406 }
407
408 } // namespace
409
410 TEST_F(VideoEncoderResourceTest, GetSupportedProfiles) {
411 // Verifies that GetSupportedProfiles calls into the renderer and
412 // the we get the right results back.
413 {
414 LockingResourceReleaser encoder(CreateEncoder());
415 std::vector<PP_VideoProfileDescription> profiles;
bbudge 2015/02/13 01:45:54 This could just be an array, i.e. PP_VideoProfileD
llandwerlin-old 2015/02/13 20:12:26 Done.
416 profiles.resize(2);
417 PP_ArrayOutput output;
418 output.user_data = &profiles[0];
419 output.GetDataBuffer = ForwardUserData;
420 ResourceMessageCallParams params;
421 MockCompletionCallback cb;
422 int32_t result = encoder_iface()->GetSupportedProfiles(
423 encoder.get(), output, PP_MakeOptionalCompletionCallback(
424 &MockCompletionCallback::Callback, &cb));
425 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
426 ASSERT_TRUE(CheckGetSupportedProfilesMsg(&params));
427
428 std::vector<PP_VideoProfileDescription> profiles_response;
429 PP_VideoProfileDescription profile;
430 profile.profile = PP_VIDEOPROFILE_H264MAIN;
431 profile.max_resolution.width = 1920;
432 profile.max_resolution.height = 1080;
433 profile.max_framerate_numerator = 30;
434 profile.max_framerate_denominator = 1;
435 profiles_response.push_back(profile);
436 profile.profile = PP_VIDEOPROFILE_VP8_ANY;
437 profile.max_resolution.width = 1920;
438 profile.max_resolution.height = 1080;
439 profile.max_framerate_numerator = 30;
440 profile.max_framerate_denominator = 1;
441 profiles_response.push_back(profile);
442
443 SendGetSupportedProfilesReply(params, profiles_response);
444 ASSERT_EQ(PP_OK, cb.result());
445
446 ASSERT_EQ(profiles_response.size(), profiles.size());
447 ASSERT_EQ(0, memcmp(&profiles[0], &profiles_response[0],
448 sizeof(PP_VideoProfileDescription) * 2));
449 }
450 }
451
452 TEST_F(VideoEncoderResourceTest, InitializeFailure) {
453 {
454 // Verify the initialize callback is called in case of failure.
455 LockingResourceReleaser encoder(CreateEncoder());
456 ResourceMessageCallParams params;
457 PP_Size size = kSize;
458 MockCompletionCallback cb;
459 int32_t result = encoder_iface()->Initialize(
460 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
461 PP_VIDEOPROFILE_H264MAIN, kBitrate,
462 PP_HARDWAREACCELERATION_WITHFALLBACK,
463 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
464 &cb));
465 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
466
467 PP_VideoFrame_Format input_format;
468 PP_Size input_visible_size;
469 PP_VideoProfile output_profile;
470 uint32_t bitrate;
471 PP_HardwareAcceleration acceleration;
472 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
473 &output_profile, &bitrate, &acceleration));
474 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
475 ASSERT_EQ(size.width, input_visible_size.width);
476 ASSERT_EQ(size.height, input_visible_size.height);
477 ASSERT_EQ(kBitrate, bitrate);
478 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
479 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
480
481 SendReply(params, PP_ERROR_NOTSUPPORTED,
482 PpapiPluginMsg_VideoEncoder_InitializeReply());
483 ASSERT_TRUE(cb.called());
484 ASSERT_EQ(PP_ERROR_NOTSUPPORTED, cb.result());
485 }
486 {
487 // Verify the initialize callback is called in case of error
488 // notification.
489 LockingResourceReleaser encoder(CreateEncoder());
490 ResourceMessageCallParams params;
491 PP_Size size = kSize;
492 MockCompletionCallback cb;
493 int32_t result = encoder_iface()->Initialize(
494 encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
495 PP_VIDEOPROFILE_H264MAIN, kBitrate,
496 PP_HARDWAREACCELERATION_WITHFALLBACK,
497 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
498 &cb));
499 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
500
501 PP_VideoFrame_Format input_format;
502 PP_Size input_visible_size;
503 PP_VideoProfile output_profile;
504 uint32_t bitrate;
505 PP_HardwareAcceleration acceleration;
506 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
507 &output_profile, &bitrate, &acceleration));
508 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
509 ASSERT_EQ(kSize.width, input_visible_size.width);
510 ASSERT_EQ(kSize.height, input_visible_size.height);
511 ASSERT_EQ(kBitrate, bitrate);
512 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
513 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
514
515 ResourceMessageCallParams error_params(encoder.get(), 0);
516 SendNotifyError(error_params, PP_ERROR_FAILED);
517 ASSERT_TRUE(cb.called());
518 ASSERT_EQ(PP_ERROR_FAILED, cb.result());
519 }
520 }
bbudge 2015/02/13 01:45:54 As discussed, the Initialize callback should alway
llandwerlin-old 2015/02/13 20:12:26 Done.
521
522 TEST_F(VideoEncoderResourceTest, InitializeSuccess) {
523 {
524 // Verify the initialize callback is called when initialization is
525 // successfull.
526 LockingResourceReleaser encoder(CreateEncoder());
527 ResourceMessageCallParams params;
528 PP_Size size = kSize;
529 const uint32_t kBitrate = 420000;
530 MockCompletionCallback cb;
531 int32_t result = encoder_iface()->Initialize(
532 encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
533 PP_VIDEOPROFILE_H264MAIN, kBitrate,
534 PP_HARDWAREACCELERATION_WITHFALLBACK,
535 PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
536 &cb));
537 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
538
539 PP_VideoFrame_Format input_format;
540 PP_Size input_visible_size;
541 PP_VideoProfile output_profile;
542 uint32_t bitrate;
543 PP_HardwareAcceleration acceleration;
544 ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
545 &output_profile, &bitrate, &acceleration));
546 ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format);
547 ASSERT_EQ(kSize.width, input_visible_size.width);
548 ASSERT_EQ(kSize.height, input_visible_size.height);
549 ASSERT_EQ(kBitrate, bitrate);
550 ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
551 ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);
552
553 CreateBitstreamSharedMemory(kBitstreamBufferSize, kBitstreamBufferNb);
554 SendInitializeReply(params, kBitstreamBufferSize, kVideoFrameNb, size);
bbudge 2015/02/13 01:45:54 Again, Initialize completes without getting buffer
llandwerlin-old 2015/02/13 20:12:26 Done.
555
556 ASSERT_TRUE(cb.called());
557 ASSERT_EQ(PP_OK, cb.result());
558
559 PP_Size coded_size;
560 CallGetFrameCodedSize(encoder.get(), &coded_size);
561 ASSERT_EQ(kSize.width, coded_size.width);
562 ASSERT_EQ(kSize.height, coded_size.height);
563 ASSERT_EQ(static_cast<int32_t>(kVideoFrameNb),
564 CallGetFramesRequired(encoder.get()));
565 }
566 }
567
568 TEST_F(VideoEncoderResourceTest, Uninitialized) {
569 // Operations on uninitialized encoders should fail.
570 LockingResourceReleaser encoder(CreateEncoder());
571
572 ASSERT_EQ(PP_ERROR_FAILED, CallGetFramesRequired(encoder.get()));
573
574 PP_Size size;
575 ASSERT_EQ(PP_ERROR_FAILED, CallGetFrameCodedSize(encoder.get(), &size));
576
577 MockCompletionCallback uncalled_cb;
578 PP_Resource video_frame = 0;
579 ASSERT_EQ(PP_ERROR_FAILED,
580 CallGetVideoFrame(encoder.get(), &video_frame, &uncalled_cb));
581 ASSERT_FALSE(uncalled_cb.called());
582 ASSERT_EQ(0, video_frame);
583
584 ASSERT_EQ(PP_ERROR_FAILED,
585 CallEncode(encoder.get(), video_frame, PP_FALSE, &uncalled_cb));
586 ASSERT_FALSE(uncalled_cb.called());
587
588 PP_BitstreamBuffer bitstream_buffer;
589 ASSERT_EQ(
590 PP_ERROR_FAILED,
591 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, &uncalled_cb));
592 ASSERT_FALSE(uncalled_cb.called());
593
594 ResourceMessageCallParams params;
595 uint32_t buffer_id;
596 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
597 ASSERT_FALSE(CheckRecycleBitstreamBufferMsg(&params, &buffer_id));
598
599 uint32_t bitrate, framerate;
600 CallRequestEncodingParametersChange(encoder.get(), 0, 0);
601 ASSERT_FALSE(
602 CheckRequestEncodeingParametersChangeMsg(&params, &bitrate, &framerate));
603 }
604
605 TEST_F(VideoEncoderResourceTest, InitializeAndGetVideoFrame) {
606 // Verify that we can pull the right number of video frames before
607 // the proxy makes us wait.
608 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
609 ResourceMessageCallParams params;
610 PP_Resource video_frames[kVideoFrameNb + 1];
611 MockCompletionCallback get_frame_cb;
612
613 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
614 CallGetVideoFrame(encoder.get(), &video_frames[0], &get_frame_cb));
615 ASSERT_FALSE(get_frame_cb.called());
616 ASSERT_TRUE(CheckGetVideoFramesMsg(&params));
617
618 uint32_t frame_length = kSize.width * kSize.height * 2;
619 CreateVideoFramesSharedMemory(frame_length, kVideoFrameNb);
620 SendGetVideoFramesReply(params, kVideoFrameNb, frame_length, kSize);
621
622 for (uint32_t i = 1; i < kVideoFrameNb; ++i) {
623 get_frame_cb.Reset();
624 ASSERT_EQ(PP_OK, CallGetVideoFrame(encoder.get(), &video_frames[i],
625 &get_frame_cb));
626 ASSERT_FALSE(get_frame_cb.called());
627 ASSERT_TRUE(CheckIsVideoFrame(video_frames[i]));
628 }
629
630 get_frame_cb.Reset();
631 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
632 CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameNb],
633 &get_frame_cb));
634 ASSERT_FALSE(get_frame_cb.called());
635
636 MockCompletionCallback get_frame_fail_cb;
637 ASSERT_EQ(PP_ERROR_INPROGRESS,
638 CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameNb],
639 &get_frame_fail_cb));
640 ASSERT_FALSE(get_frame_fail_cb.called());
641
642 // Unlock the GetVideoFrame callback.
bbudge 2015/02/13 01:45:53 // Unblock the GetVideoFrame callback by freeing u
llandwerlin-old 2015/02/13 20:12:26 Done.
643 MockCompletionCallback encode_cb;
644 ASSERT_EQ(
645 PP_OK_COMPLETIONPENDING,
646 CallCompleteEncode(encoder.get(), video_frames[0], PP_FALSE, &encode_cb));
647 ASSERT_TRUE(encode_cb.called());
648 ASSERT_EQ(PP_OK, encode_cb.result());
649 ASSERT_TRUE(get_frame_cb.called());
650
651 {
652 ProxyAutoLock lock;
653 for (uint32_t i = 0; i < (kVideoFrameNb + 1); ++i)
654 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
655 video_frames[i]);
bbudge 2015/02/13 01:45:54 Could you call encoder.Close() instead?
llandwerlin-old 2015/02/13 20:12:26 Done.
656 }
657 }
658
659 TEST_F(VideoEncoderResourceTest, Encode) {
660 // Check Encode() calls into the renderer.
661 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
662
663 PP_Resource video_frame;
664 MockCompletionCallback get_frame_cb;
665 ;
bbudge 2015/02/13 01:45:54 empty statement
llandwerlin-old 2015/02/13 20:12:26 Done.
666 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
667 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
668 ASSERT_TRUE(get_frame_cb.called());
669 ASSERT_EQ(PP_OK, get_frame_cb.result());
670
671 MockCompletionCallback encode_cb;
672 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
673 CallEncode(encoder.get(), video_frame, PP_TRUE, &encode_cb));
674 ASSERT_FALSE(encode_cb.called());
675
676 ResourceMessageCallParams params;
677 uint32_t frame_id;
678 bool force_frame;
679 ASSERT_TRUE(CheckEncodeMsg(&params, &frame_id, &force_frame));
680
681 SendEncodeReply(params, frame_id);
682
683 ASSERT_TRUE(encode_cb.called());
684 ASSERT_EQ(PP_OK, encode_cb.result());
685 }
686
687 TEST_F(VideoEncoderResourceTest, EncodeAndGetVideoFrame) {
688 // Check the encoding loop works well.
689 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
690 ResourceMessageCallParams params;
691 PP_Resource video_frame;
692 MockCompletionCallback get_frame_cb, encode_cb;
693
694 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
695 CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
696 ASSERT_TRUE(get_frame_cb.called());
697 ASSERT_EQ(PP_OK, get_frame_cb.result());
698
699 for (uint32_t i = 1; i < 20 * kVideoFrameNb; ++i) {
700 encode_cb.Reset();
701 ASSERT_EQ(
702 PP_OK_COMPLETIONPENDING,
703 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
704 ASSERT_TRUE(encode_cb.called());
705 ASSERT_EQ(PP_OK, encode_cb.result());
706
707 get_frame_cb.Reset();
708 ASSERT_EQ(PP_OK,
709 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
710 ASSERT_FALSE(get_frame_cb.called());
711 ASSERT_TRUE(CheckIsVideoFrame(video_frame));
712 }
713
714 ASSERT_EQ(
715 PP_OK_COMPLETIONPENDING,
716 CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
717 ASSERT_TRUE(encode_cb.called());
718 ASSERT_EQ(PP_OK, encode_cb.result());
719 }
720
721 TEST_F(VideoEncoderResourceTest, GetBitstreamBuffer) {
722 // Verify that the GetBitstreamBuffer callback is fired whenever the
723 // renderer signals a buffer is available.
724 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
725
726 MockCompletionCallback get_bitstream_buffer_cb;
727 PP_BitstreamBuffer bitstream_buffer;
728 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
729 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
730 &get_bitstream_buffer_cb));
731 ASSERT_FALSE(get_bitstream_buffer_cb.called());
732
bbudge 2015/02/13 01:45:54 Test a second call gets INPROGRESS.
llandwerlin-old 2015/02/13 20:12:26 Done.
733 ResourceMessageCallParams buffer_params(encoder.get(), 0);
734 SendBitstreamBufferReady(buffer_params, 0, 10, true);
735
736 ASSERT_TRUE(get_bitstream_buffer_cb.called());
737 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
738 ASSERT_EQ(static_cast<uint32_t>(10), bitstream_buffer.size);
739 ASSERT_EQ(PP_TRUE, bitstream_buffer.key_frame);
740 }
741
742 TEST_F(VideoEncoderResourceTest, RecycleBitstreamBuffer) {
743 // Verify that we signal the renderer that a bitstream buffer has been
744 // recycled.
745 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
746
747 MockCompletionCallback get_bitstream_buffer_cb;
748 PP_BitstreamBuffer bitstream_buffer;
749 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
750 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
751 &get_bitstream_buffer_cb));
752 ASSERT_FALSE(get_bitstream_buffer_cb.called());
753
754 ResourceMessageCallParams buffer_params(encoder.get(), 0);
755 SendBitstreamBufferReady(buffer_params, kBitstreamBufferNb - 1, 10, true);
756
757 ASSERT_TRUE(get_bitstream_buffer_cb.called());
758 ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
759
760 CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
761
762 ResourceMessageCallParams recycle_params;
763 uint32_t buffer_id;
764 ASSERT_TRUE(CheckRecycleBitstreamBufferMsg(&recycle_params, &buffer_id));
765 ASSERT_EQ(kBitstreamBufferNb - 1, buffer_id);
766 }
767
768 TEST_F(VideoEncoderResourceTest, RequestEncodingParametersChange) {
769 // Check encoding parameter changes are correctly sent to the
770 // renderer.
771 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
772
773 CallRequestEncodingParametersChange(encoder.get(), 1, 2);
774 ResourceMessageCallParams params;
775 uint32_t bitrate, framerate;
776 ASSERT_TRUE(
777 CheckRequestEncodeingParametersChangeMsg(&params, &bitrate, &framerate));
778 ASSERT_EQ(static_cast<uint32_t>(1), bitrate);
779 ASSERT_EQ(static_cast<uint32_t>(2), framerate);
780 }
781
782 TEST_F(VideoEncoderResourceTest, NotifyError) {
783 {
784 // Check an error from the encoder calls back GetVideoFrame and
bbudge 2015/02/13 01:45:53 s/calls back/aborts
785 // GetBitstreamBuffer callbacks.
786 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
787
788 MockCompletionCallback get_frame_cb;
789 PP_Resource video_frame;
790 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
791 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
792 ASSERT_FALSE(get_frame_cb.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_cb.called());
804 ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb.result());
805 ASSERT_TRUE(get_bitstream_buffer_cb.called());
806 ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result());
807 }
808 {
809 // Check an error from the encoder calls back Encode and GetBitstreamBuffer
bbudge 2015/02/13 01:45:54 s/calls back/aborts
llandwerlin-old 2015/02/13 20:12:26 Done.
810 // callbacks.
811 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
812
813 MockCompletionCallback get_frame_cb, encode_cb1, encode_cb2;
814 PP_Resource video_frame1, video_frame2;
815 ASSERT_EQ(
816 PP_OK_COMPLETIONPENDING,
817 CallFirstGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb));
818 ASSERT_TRUE(get_frame_cb.called());
819 ASSERT_EQ(PP_OK, get_frame_cb.result());
820
821 get_frame_cb.Reset();
822 ASSERT_EQ(PP_OK, CallFirstGetVideoFrame(encoder.get(), &video_frame2,
823 &get_frame_cb));
824 ASSERT_FALSE(get_frame_cb.called());
825
826 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
827 CallEncode(encoder.get(), video_frame1, PP_FALSE, &encode_cb1));
828 ASSERT_FALSE(encode_cb1.called());
829 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
830 CallEncode(encoder.get(), video_frame2, PP_FALSE, &encode_cb2));
831 ASSERT_FALSE(encode_cb2.called());
832
833 MockCompletionCallback get_bitstream_buffer_cb;
834 PP_BitstreamBuffer bitstream_buffer;
835 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
836 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
837 &get_bitstream_buffer_cb));
838
839 ResourceMessageCallParams error_params(encoder.get(), 0);
840 SendNotifyError(error_params, PP_ERROR_FAILED);
841
842 ASSERT_TRUE(encode_cb1.called());
843 ASSERT_EQ(PP_ERROR_FAILED, encode_cb1.result());
844 ASSERT_TRUE(encode_cb2.called());
845 ASSERT_EQ(PP_ERROR_FAILED, encode_cb2.result());
846 ASSERT_TRUE(get_bitstream_buffer_cb.called());
847 ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result());
848 }
849 }
850
851 TEST_F(VideoEncoderResourceTest, Close) {
852 {
853 // Check closing the encoder callbacks back GetVideoFrame and
bbudge 2015/02/13 01:45:54 s/callbacks back/aborts
llandwerlin-old 2015/02/13 20:12:26 Done.
854 // GetBitstreamBuffer callbacks.
855 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
856
857 MockCompletionCallback get_frame_cb;
858 PP_Resource video_frame;
859 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
860 CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
861 ASSERT_FALSE(get_frame_cb.called());
862
863 MockCompletionCallback get_bitstream_buffer_cb;
864 PP_BitstreamBuffer bitstream_buffer;
865 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
866 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
867 &get_bitstream_buffer_cb));
868
869 CallClose(encoder.get());
870
871 ASSERT_TRUE(get_frame_cb.called());
872 ASSERT_EQ(PP_ERROR_ABORTED, get_frame_cb.result());
873 ASSERT_TRUE(get_bitstream_buffer_cb.called());
874 ASSERT_EQ(PP_ERROR_ABORTED, get_bitstream_buffer_cb.result());
875 }
876 {
877 // Check closing the encoder calls back Encode and GetBitstreamBuffer
bbudge 2015/02/13 01:45:53 s/calls back/aborts
llandwerlin-old 2015/02/13 20:12:26 Done.
878 // callbacks.
879 LockingResourceReleaser encoder(CreateAndInitializeEncoder());
880
881 MockCompletionCallback get_frame_cb, encode_cb1, encode_cb2;
882 PP_Resource video_frame1, video_frame2;
883 ASSERT_EQ(
884 PP_OK_COMPLETIONPENDING,
885 CallFirstGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb));
886 ASSERT_TRUE(get_frame_cb.called());
887 ASSERT_EQ(PP_OK, get_frame_cb.result());
888
889 get_frame_cb.Reset();
890 ASSERT_EQ(PP_OK, CallFirstGetVideoFrame(encoder.get(), &video_frame2,
891 &get_frame_cb));
892 ASSERT_FALSE(get_frame_cb.called());
893
894 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
895 CallEncode(encoder.get(), video_frame1, PP_FALSE, &encode_cb1));
896 ASSERT_FALSE(encode_cb1.called());
897 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
898 CallEncode(encoder.get(), video_frame2, PP_FALSE, &encode_cb2));
899 ASSERT_FALSE(encode_cb2.called());
900
901 MockCompletionCallback get_bitstream_buffer_cb;
902 PP_BitstreamBuffer bitstream_buffer;
903 ASSERT_EQ(PP_OK_COMPLETIONPENDING,
904 CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
905 &get_bitstream_buffer_cb));
906
907 CallClose(encoder.get());
908
909 ASSERT_TRUE(encode_cb1.called());
910 ASSERT_EQ(PP_ERROR_ABORTED, encode_cb1.result());
911 ASSERT_TRUE(encode_cb2.called());
912 ASSERT_EQ(PP_ERROR_ABORTED, encode_cb2.result());
913 ASSERT_TRUE(get_bitstream_buffer_cb.called());
914 ASSERT_EQ(PP_ERROR_ABORTED, get_bitstream_buffer_cb.result());
915 }
916 }
917
918 } // namespace proxy
919 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698