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

Side by Side Diff: content/renderer/pepper/pepper_video_encoder_host.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/bind.h"
6 #include "base/memory/shared_memory.h"
7 #include "base/numerics/safe_math.h"
8 #include "content/common/gpu/client/command_buffer_proxy_impl.h"
9 #include "content/public/renderer/renderer_ppapi_host.h"
10 #include "content/renderer/pepper/gfx_conversion.h"
11 #include "content/renderer/pepper/host_globals.h"
12 #include "content/renderer/pepper/pepper_video_encoder_host.h"
13 #include "content/renderer/render_thread_impl.h"
14 #include "media/base/bind_to_current_loop.h"
15 #include "media/base/video_frame.h"
16 #include "media/filters/gpu_video_accelerator_factories.h"
17 #include "media/video/video_encode_accelerator.h"
18 #include "ppapi/c/pp_codecs.h"
19 #include "ppapi/c/pp_errors.h"
20 #include "ppapi/c/pp_graphics_3d.h"
21 #include "ppapi/host/dispatch_host_message.h"
22 #include "ppapi/host/ppapi_host.h"
23 #include "ppapi/proxy/ppapi_messages.h"
24 #include "ppapi/shared_impl/media_stream_buffer.h"
25
26 using ppapi::proxy::SerializedHandle;
27
28 namespace content {
29
30 namespace {
31
32 const int32_t kDefaultNumberOfBitstreamBuffers = 4;
33
34 base::PlatformFile ConvertSharedMemoryHandle(
35 const base::SharedMemory& shared_memory) {
36 #if defined(OS_POSIX)
37 return shared_memory.handle().fd;
38 #elif defined(OS_WIN)
39 return shared_memory.handle();
40 #else
41 #error "Platform not supported."
42 #endif
43 }
44
45 int32_t PP_FromMediaEncodeAcceleratorError(
46 media::VideoEncodeAccelerator::Error error) {
47 switch (error) {
48 case media::VideoEncodeAccelerator::kInvalidArgumentError:
49 return PP_ERROR_MALFORMED_INPUT;
50 case media::VideoEncodeAccelerator::kIllegalStateError:
51 case media::VideoEncodeAccelerator::kPlatformFailureError:
52 return PP_ERROR_RESOURCE_FAILED;
53 // No default case, to catch unhandled enum values.
bbudge 2015/02/10 22:47:37 Indentation should match 'case', here and below.
llandwerlin-old 2015/02/11 18:42:23 Done.
54 }
55 return PP_ERROR_FAILED;
56 }
57
58 } // namespace
59
60 // TODO(llandwerlin): move following to media_conversion.cc/h?
61 media::VideoCodecProfile PepperToMediaVideoProfile(PP_VideoProfile profile) {
62 switch (profile) {
63 case PP_VIDEOPROFILE_H264BASELINE:
64 return media::H264PROFILE_BASELINE;
65 case PP_VIDEOPROFILE_H264MAIN:
66 return media::H264PROFILE_MAIN;
67 case PP_VIDEOPROFILE_H264EXTENDED:
68 return media::H264PROFILE_EXTENDED;
69 case PP_VIDEOPROFILE_H264HIGH:
70 return media::H264PROFILE_HIGH;
71 case PP_VIDEOPROFILE_H264HIGH10PROFILE:
72 return media::H264PROFILE_HIGH10PROFILE;
73 case PP_VIDEOPROFILE_H264HIGH422PROFILE:
74 return media::H264PROFILE_HIGH422PROFILE;
75 case PP_VIDEOPROFILE_H264HIGH444PREDICTIVEPROFILE:
76 return media::H264PROFILE_HIGH444PREDICTIVEPROFILE;
77 case PP_VIDEOPROFILE_H264SCALABLEBASELINE:
78 return media::H264PROFILE_SCALABLEBASELINE;
79 case PP_VIDEOPROFILE_H264SCALABLEHIGH:
80 return media::H264PROFILE_SCALABLEHIGH;
81 case PP_VIDEOPROFILE_H264STEREOHIGH:
82 return media::H264PROFILE_STEREOHIGH;
83 case PP_VIDEOPROFILE_H264MULTIVIEWHIGH:
84 return media::H264PROFILE_MULTIVIEWHIGH;
85 case PP_VIDEOPROFILE_VP8_ANY:
86 return media::VP8PROFILE_ANY;
87 case PP_VIDEOPROFILE_VP9_ANY:
88 return media::VP9PROFILE_ANY;
89 // No default case, to catch unhandled PP_VideoProfile values.
90 }
91
92 return media::VIDEO_CODEC_PROFILE_UNKNOWN;
93 }
94
95 PP_VideoProfile MediaToPepperVideoProfile(media::VideoCodecProfile profile) {
96 switch (profile) {
97 case media::H264PROFILE_BASELINE:
98 return PP_VIDEOPROFILE_H264BASELINE;
99 case media::H264PROFILE_MAIN:
100 return PP_VIDEOPROFILE_H264MAIN;
101 case media::H264PROFILE_EXTENDED:
102 return PP_VIDEOPROFILE_H264EXTENDED;
103 case media::H264PROFILE_HIGH:
104 return PP_VIDEOPROFILE_H264HIGH;
105 case media::H264PROFILE_HIGH10PROFILE:
106 return PP_VIDEOPROFILE_H264HIGH10PROFILE;
107 case media::H264PROFILE_HIGH422PROFILE:
108 return PP_VIDEOPROFILE_H264HIGH422PROFILE;
109 case media::H264PROFILE_HIGH444PREDICTIVEPROFILE:
110 return PP_VIDEOPROFILE_H264HIGH444PREDICTIVEPROFILE;
111 case media::H264PROFILE_SCALABLEBASELINE:
112 return PP_VIDEOPROFILE_H264SCALABLEBASELINE;
113 case media::H264PROFILE_SCALABLEHIGH:
114 return PP_VIDEOPROFILE_H264SCALABLEHIGH;
115 case media::H264PROFILE_STEREOHIGH:
116 return PP_VIDEOPROFILE_H264STEREOHIGH;
117 case media::H264PROFILE_MULTIVIEWHIGH:
118 return PP_VIDEOPROFILE_H264MULTIVIEWHIGH;
119 case media::VP8PROFILE_ANY:
120 return PP_VIDEOPROFILE_VP8_ANY;
121 case media::VP9PROFILE_ANY:
122 return PP_VIDEOPROFILE_VP9_ANY;
123 default:
124 // TODO(llandwerlin): This is wrong, but there is no PP_VIDEOPROFILE_NONE.
125 return PP_VIDEOPROFILE_VP9_ANY;
bbudge 2015/02/10 22:47:37 add a NOTREACHED and return -1, e.g. https://code.
llandwerlin-old 2015/02/11 18:42:22 Done.
126 }
127 }
128
129 media::VideoFrame::Format PepperToMediaVideoFormat(
bbudge 2015/02/10 22:47:36 s/MediaVideo/VideoFrame or MediaVideoFrame
llandwerlin-old 2015/02/11 18:42:23 Renamed all these functions to match the PP_From*/
130 PP_VideoFrame_Format format) {
131 switch (format) {
132 case PP_VIDEOFRAME_FORMAT_UNKNOWN:
133 return media::VideoFrame::UNKNOWN;
134 case PP_VIDEOFRAME_FORMAT_YV12:
135 return media::VideoFrame::YV12;
136 case PP_VIDEOFRAME_FORMAT_I420:
137 return media::VideoFrame::I420;
138 case PP_VIDEOFRAME_FORMAT_BGRA:
139 return media::VideoFrame::UNKNOWN;
140 // No default case, to catch unhandled PP_VideoFrame_Format values.
141 }
142
143 return media::VideoFrame::UNKNOWN;
144 }
145
146 PP_VideoFrame_Format MediaToPepperVideoFormat(
147 media::VideoFrame::Format format) {
148 switch (format) {
149 case media::VideoFrame::UNKNOWN:
150 return PP_VIDEOFRAME_FORMAT_UNKNOWN;
151 case media::VideoFrame::YV12:
152 return PP_VIDEOFRAME_FORMAT_YV12;
153 case media::VideoFrame::I420:
154 return PP_VIDEOFRAME_FORMAT_I420;
155 default:
156 return PP_VIDEOFRAME_FORMAT_UNKNOWN;
157 }
158 }
159
160 ////////////////////////////////////////////////////////////////////////////////
161 //
162 // PepperVideoEncoderHost
163 //
164 ////////////////////////////////////////////////////////////////////////////////
bbudge 2015/02/10 22:47:37 Chrome doesn't really use this commenting conventi
llandwerlin-old 2015/02/11 18:42:24 Done.
165
166 PepperVideoEncoderHost::ShmBuffer::ShmBuffer(
167 int32_t id,
168 scoped_ptr<base::SharedMemory> memory,
169 size_t size)
170 : id(id), shm(memory.Pass()), in_use(true) {
171 if (shm)
172 shm->Map(size);
173 }
174
175 PepperVideoEncoderHost::ShmBuffer::~ShmBuffer() {
176 }
177
178 media::BitstreamBuffer PepperVideoEncoderHost::ShmBuffer::toBitstreamBuffer() {
179 return media::BitstreamBuffer(id, shm->handle(), shm->mapped_size());
180 }
181
182 PepperVideoEncoderHost::PepperVideoEncoderHost(RendererPpapiHost* host,
183 PP_Instance instance,
184 PP_Resource resource)
185 : ResourceHost(host->GetPpapiHost(), instance, resource),
186 renderer_ppapi_host_(host),
187 buffer_manager_(this),
188 initialized_(false),
189 encoder_last_error_(PP_ERROR_FAILED),
bbudge 2015/02/10 22:47:36 initialize input_coded_size_, frame_count_, and me
llandwerlin-old 2015/02/11 18:42:23 Sure, can I leave the input_coded_size_ initialize
bbudge 2015/02/11 23:27:44 Oh, right, that's fine.
190 command_buffer_(nullptr),
191 weak_ptr_factory_(this) {
192 }
193
194 PepperVideoEncoderHost::~PepperVideoEncoderHost() {
195 if (command_buffer_) {
196 DCHECK(channel_.get());
197 channel_->DestroyCommandBuffer(command_buffer_);
198 command_buffer_ = NULL;
199 }
bbudge 2015/02/10 22:47:37 Shouldn't we Destroy the encoder, here or where we
llandwerlin-old 2015/02/11 18:42:23 I guess it should be destroyed before the command
200
201 channel_ = NULL;
202 }
203
204 int32_t PepperVideoEncoderHost::OnResourceMessageReceived(
205 const IPC::Message& msg,
206 ppapi::host::HostMessageContext* context) {
207 PPAPI_BEGIN_MESSAGE_MAP(PepperVideoEncoderHost, msg)
208 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
209 PpapiHostMsg_VideoEncoder_GetSupportedProfiles,
210 OnHostMsgGetSupportedProfiles)
211 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoEncoder_Initialize,
212 OnHostMsgInitialize)
213 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoEncoder_GetVideoFrames,
214 OnHostMsgGetVideoFrames)
215 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoEncoder_Encode,
216 OnHostMsgEncode)
217 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
218 PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer,
219 OnHostMsgRecycleBitstreamBuffer)
220 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
221 PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange,
222 OnHostMsgRequestEncodingParametersChange)
223 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoEncoder_Close,
224 OnHostMsgClose)
225 PPAPI_END_MESSAGE_MAP()
226 return PP_ERROR_FAILED;
227 }
228
229 int32_t PepperVideoEncoderHost::OnHostMsgGetSupportedProfiles(
230 ppapi::host::HostMessageContext* context) {
231 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles =
232 RenderThreadImpl::current()
233 ->GetGpuFactories()
234 ->GetVideoEncodeAcceleratorSupportedProfiles();
235 // TODO(llandwerlin): merge software supported profiles.
236
237 std::vector<PP_VideoProfileDescription> pp_profiles;
238 for (media::VideoEncodeAccelerator::SupportedProfile profile : profiles) {
239 PP_VideoProfileDescription pp_profile;
240 pp_profile.profile = MediaToPepperVideoProfile(profile.profile);
241 pp_profile.max_resolution = PP_FromGfxSize(profile.max_resolution);
242 pp_profile.max_framerate_numerator = profile.max_framerate_numerator;
243 pp_profile.max_framerate_denominator = profile.max_framerate_denominator;
244 pp_profile.acceleration = PP_HARDWAREACCELERATION_ONLY;
245 pp_profiles.push_back(pp_profile);
246 }
247
248 host()->SendReply(
249 context->MakeReplyMessageContext(),
250 PpapiPluginMsg_VideoEncoder_GetSupportedProfilesReply(pp_profiles));
251
252 return PP_OK_COMPLETIONPENDING;
253 }
254
255 int32_t PepperVideoEncoderHost::OnHostMsgInitialize(
256 ppapi::host::HostMessageContext* context,
257 PP_VideoFrame_Format input_format,
258 const PP_Size& input_visible_size,
259 PP_VideoProfile output_profile,
260 uint32_t initial_bitrate,
261 PP_HardwareAcceleration acceleration) {
bbudge 2015/02/10 22:47:36 You should use this parameter to fail when it's no
llandwerlin-old 2015/02/11 18:42:23 Done.
262 scoped_ptr<media::VideoEncodeAccelerator> encoder;
bbudge 2015/02/10 22:47:37 Unused.
llandwerlin-old 2015/02/11 18:42:22 Done.
263 if (initialized_)
264 return PP_ERROR_FAILED;
265
266 media_format_ = PepperToMediaVideoFormat(input_format);
bbudge 2015/02/10 22:47:37 Could you make the locals that are translated from
llandwerlin-old 2015/02/11 18:42:23 Done.
267 if (media_format_ == media::VideoFrame::UNKNOWN)
268 return PP_ERROR_NOTSUPPORTED;
bbudge 2015/02/10 22:47:36 PP_ERROR_BADARGUMENT
llandwerlin-old 2015/02/11 18:42:22 Done.
269
270 media::VideoCodecProfile media_profile =
271 PepperToMediaVideoProfile(output_profile);
272 gfx::Size input_size(input_visible_size.width, input_visible_size.height);
273
274 initialize_reply_context_ = context->MakeReplyMessageContext();
275
276 // There is no garantee that we have a 3D context to work with. So
277 // we create a dump command buffer to communicate with the gpu
bbudge 2015/02/10 22:47:37 s/garantee/guarantee s/dump/dummy ?
llandwerlin-old 2015/02/11 18:42:24 Done.
278 // process.
279 channel_ = RenderThreadImpl::current()->EstablishGpuChannelSync(
280 CAUSE_FOR_GPU_LAUNCH_PEPPERVIDEOENCODERACCELERATOR_INITIALIZE);
281 if (!channel_.get())
282 return PP_ERROR_FAILED;
283
284 std::vector<int32> attribs;
285 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
286
287 command_buffer_ = channel_->CreateOffscreenCommandBuffer(
288 gfx::Size(), nullptr, attribs, GURL::EmptyGURL(),
289 gfx::PreferIntegratedGpu);
290 if (!command_buffer_)
291 return PP_ERROR_FAILED;
292
293 command_buffer_->SetChannelErrorCallback(media::BindToCurrentLoop(base::Bind(
294 &PepperVideoEncoderHost::NotifyPepperError,
295 weak_ptr_factory_.GetWeakPtr(),
296 PP_ERROR_FAILED)));
297
298 if (!command_buffer_->Initialize())
299 return PP_ERROR_FAILED;
300
301 encoder_ = command_buffer_->CreateVideoEncoder();
302
303 if (encoder_.get() &&
bbudge 2015/02/10 22:47:36 I don't think you need the .get()
llandwerlin-old 2015/02/11 18:42:24 Done.
304 encoder_->Initialize(media_format_, input_size, media_profile,
305 initial_bitrate, this)) {
306 return PP_OK_COMPLETIONPENDING;
307 }
308
309 // TODO(llandwerlin): Software encoder.
310 return PP_ERROR_NOTSUPPORTED;
311 }
312
313 int32_t PepperVideoEncoderHost::OnHostMsgGetVideoFrames(
314 ppapi::host::HostMessageContext* context) {
315 if (encoder_last_error_)
316 return encoder_last_error_;
317
318 uint32_t frame_length =
319 media::VideoFrame::AllocationSize(media_format_, input_coded_size_);
bbudge 2015/02/10 22:47:37 Since this returns size_t and we don't range limit
llandwerlin-old 2015/02/11 18:42:23 Added a method to check against supported format i
320 uint32_t buffer_size = frame_length +
321 sizeof(ppapi::MediaStreamBuffer::Video) -
322 sizeof(ppapi::MediaStreamBuffer::Video::data);
323
324 // Make each buffer 4 byte aligned.
325 base::CheckedNumeric<int32_t> buffer_size_aligned = buffer_size;
326 buffer_size_aligned += (4 - buffer_size % 4);
327
328 base::CheckedNumeric<int32_t> total_size = frame_count_ * buffer_size_aligned;
329 if (!total_size.IsValid())
330 return PP_ERROR_FAILED;
331
332 // TODO(llandwerlin): HostAllocateSharedMemoryBuffer() is apparently
333 // synchronous and should be avoided.
bbudge 2015/02/10 22:47:36 I don't think this TODO will ever get todone. I'd
llandwerlin-old 2015/02/11 18:42:23 Done.
334 scoped_ptr<base::SharedMemory> shm(
335 RenderThreadImpl::current()
336 ->HostAllocateSharedMemoryBuffer(total_size.ValueOrDie())
337 .Pass());
338 if (!shm)
339 return PP_ERROR_FAILED;
340
341 VLOG(4) << " frame_count=" << frame_count_ << " frame_length=" << frame_length
342 << " buffer_size=" << buffer_size_aligned.ValueOrDie();
343
344 if (!buffer_manager_.SetBuffers(
345 frame_count_, buffer_size_aligned.ValueOrDie(), shm.Pass(), true))
346 return PP_ERROR_FAILED;
347
348 for (int32_t i = 0; i < buffer_manager_.number_of_buffers(); ++i) {
349 ppapi::MediaStreamBuffer::Video* buffer =
350 &(buffer_manager_.GetBufferPointer(i)->video);
351 buffer->header.size = buffer_manager_.buffer_size();
352 buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO;
353 buffer->format = MediaToPepperVideoFormat(media_format_);
354 buffer->size.width = input_coded_size_.width();
355 buffer->size.height = input_coded_size_.height();
356 buffer->data_size = frame_length;
357 }
358
359 ppapi::host::ReplyMessageContext reply_context =
360 context->MakeReplyMessageContext();
361 reply_context.params.AppendHandle(SerializedHandle(
362 renderer_ppapi_host_->ShareHandleWithRemote(
363 ConvertSharedMemoryHandle(*buffer_manager_.shm()), false),
364 total_size.ValueOrDie()));
365
366 host()->SendReply(reply_context,
367 PpapiPluginMsg_VideoEncoder_GetVideoFramesReply(
368 frame_count_, buffer_size_aligned.ValueOrDie(),
369 PP_FromGfxSize(input_coded_size_)));
370
371 return PP_OK_COMPLETIONPENDING;
372 }
373
374 int32_t PepperVideoEncoderHost::OnHostMsgEncode(
375 ppapi::host::HostMessageContext* context,
376 uint32_t frame_id,
377 bool force_keyframe) {
378 if (encoder_last_error_)
379 return encoder_last_error_;
380
bbudge 2015/02/10 22:47:36 Range check 'frame_id' here. This is an attack sur
llandwerlin-old 2015/02/11 18:42:23 Done.
381 encoder_->Encode(
382 CreateVideoFrame(frame_id, context->MakeReplyMessageContext()),
383 force_keyframe);
384
385 return PP_OK_COMPLETIONPENDING;
386 }
387
388 int32_t PepperVideoEncoderHost::OnHostMsgRecycleBitstreamBuffer(
389 ppapi::host::HostMessageContext* context,
390 uint32_t buffer_id) {
391 if (encoder_last_error_)
392 return encoder_last_error_;
393
394 if (buffer_id < 0 || buffer_id >= buffers_.size() ||
395 buffers_[buffer_id]->in_use)
396 return PP_ERROR_BADARGUMENT;
bbudge 2015/02/10 22:47:37 use brackets. Also PP_ERROR_FAILED would be better
llandwerlin-old 2015/02/11 18:42:24 Done. Not sure where you would like me to put brac
bbudge 2015/02/11 23:27:44 http://google-styleguide.googlecode.com/svn/trunk/
397
398 buffers_[buffer_id]->in_use = true;
399 encoder_->UseOutputBitstreamBuffer(buffers_[buffer_id]->toBitstreamBuffer());
400
401 return PP_OK;
402 }
403
404 int32_t PepperVideoEncoderHost::OnHostMsgRequestEncodingParametersChange(
405 ppapi::host::HostMessageContext* context,
406 uint32_t bitrate,
407 uint32_t framerate) {
408 if (encoder_last_error_)
409 return encoder_last_error_;
410
411 encoder_->RequestEncodingParametersChange(bitrate, framerate);
412
413 return PP_OK;
414 }
415
416 int32_t PepperVideoEncoderHost::OnHostMsgClose(
417 ppapi::host::HostMessageContext* context) {
418 NotifyPepperError(PP_ERROR_ABORTED);
bbudge 2015/02/10 22:47:37 I think you should just call encoder_->Destroy() h
llandwerlin-old 2015/02/11 18:42:23 Ok, I'll keep setting the encoder_last_error_ vari
419
420 return PP_OK;
421 }
422
423 void PepperVideoEncoderHost::RequireBitstreamBuffers(
424 unsigned int frame_count,
425 const gfx::Size& input_coded_size,
426 size_t output_buffer_size) {
427 DCHECK(RenderThreadImpl::current());
428
429 buffers_.clear();
bbudge 2015/02/10 22:47:36 I think I asked before, but is it possible to rece
llandwerlin-old 2015/02/11 18:42:23 No, not with the current implementations. That cou
430 for (int32_t i = 0; i < kDefaultNumberOfBitstreamBuffers; ++i) {
431 scoped_ptr<base::SharedMemory> shm(
432 RenderThread::Get()
433 ->HostAllocateSharedMemoryBuffer(output_buffer_size)
434 .Pass());
435
436 if (!shm || !shm->Map(output_buffer_size)) {
437 buffers_.clear();
438 break;
439 }
440
441 buffers_.push_back(new ShmBuffer(i, shm.Pass(), output_buffer_size));
442
443 initialize_reply_context_.params.AppendHandle(
444 ppapi::proxy::SerializedHandle(
445 renderer_ppapi_host_->ShareHandleWithRemote(
446 ConvertSharedMemoryHandle(*buffers_.back()->shm), false),
447 output_buffer_size));
448 }
449
450 if (buffers_.empty()) {
451 NotifyPepperError(PP_ERROR_FAILED);
bbudge 2015/02/10 22:47:37 Don't use NotifyPepperError as a generic error rep
llandwerlin-old 2015/02/11 18:42:23 Done.
452 return;
453 }
454
455 // Feed buffers to the encoder.
456 for (size_t i = 0; i < buffers_.size(); ++i) {
457 encoder_->UseOutputBitstreamBuffer(buffers_[i]->toBitstreamBuffer());
458 }
459
460 // Notify the plugins of the buffers and the input size.
bbudge 2015/02/10 22:47:36 s/plugins/plugin
llandwerlin-old 2015/02/11 18:42:24 Done.
461 PP_Size size;
bbudge 2015/02/10 22:47:37 PP_MakeSize would be more concise.
llandwerlin-old 2015/02/11 18:42:22 Done.
462 size.width = input_coded_size.width();
463 size.height = input_coded_size.height();
464 input_coded_size_ = input_coded_size;
465 frame_count_ = frame_count;
466 initialized_ = true;
467 encoder_last_error_ = PP_OK;
468
469 host()->SendReply(
470 initialize_reply_context_,
471 PpapiPluginMsg_VideoEncoder_InitializeReply(
472 output_buffer_size, frame_count, size));
473 }
474
475 void PepperVideoEncoderHost::BitstreamBufferReady(int32 buffer_id,
476 size_t payload_size,
477 bool key_frame) {
478 DCHECK(RenderThreadImpl::current());
479 DCHECK(buffers_[buffer_id]->in_use);
480
481 buffers_[buffer_id]->in_use = false;
482 host()->SendUnsolicitedReply(pp_resource(),
483 PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
484 buffer_id, payload_size, key_frame));
485 }
486
487 void PepperVideoEncoderHost::NotifyError(
488 media::VideoEncodeAccelerator::Error error) {
489 DCHECK(RenderThreadImpl::current());
490 NotifyPepperError(PP_FromMediaEncodeAcceleratorError(error));
491 }
492
493 scoped_refptr<media::VideoFrame> PepperVideoEncoderHost::CreateVideoFrame(
494 uint32_t frame_id,
495 const ppapi::host::ReplyMessageContext& reply_context) {
bbudge 2015/02/10 22:47:37 You might want to DCHECK that frame_id is in range
llandwerlin-old 2015/02/11 18:42:23 Done.
496 ppapi::MediaStreamBuffer* buffer =
497 buffer_manager_->GetBufferPointer(frame_id);
498
499 uint32_t shm_offset = frame_id * buffer_manager_->buffer_size() +
500 sizeof(ppapi::MediaStreamBuffer::Video) -
501 sizeof(ppapi::MediaStreamBuffer::Video::data);
502
503 return media::VideoFrame::WrapExternalPackedMemory(
504 media_format_, input_coded_size, gfx::Rect(input_coded_size_),
505 input_coded_size_, static_cast<uint8*>(buffer->video.data),
506 buffer->video.data_size, buffer_manager_->shm()->handle(), shm_offset,
507 base::TimeDelta(), base::Bind(
508 &PepperVideoEncoderHost::EncodeVideoFrameDone,
509 weak_ptr_factory_.GetWeakPtr(), base::Passed(shm.Pass()),
510 reply_context));
511 }
512
513 void PepperVideoEncoderHost::EncodeVideoFrameDone(
514 const ppapi::host::ReplyMessageContext& reply_context,
515 uint32_t frame_id) {
516 DCHECK(RenderThreadImpl::current());
517
518 ppapi::host::ReplyMessageContext context = reply_context;
519 context.params.set_result(encoder_last_error_);
520 host()->SendReply(reply_context,
521 PpapiPluginMsg_VideoEncoder_EncodeReply(frame_id));
522 }
523
524 void PepperVideoEncoderHost::NotifyPepperError(int32_t error) {
525 DCHECK(RenderThreadImpl::current());
526
527 encoder_last_error_ = error;
528 encoder_->Destroy();
529 base::Unretained(encoder_.release());
530 host()->SendUnsolicitedReply(
531 pp_resource(),
532 PpapiPluginMsg_VideoEncoder_NotifyError(encoder_last_error_));
533 }
534
535 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698