12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/pepper/pepper_video_capture_host.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_globals.h"
8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_media_device_manager.h"
9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_platform_video_capture.h"
1058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/renderer/render_frame_impl.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/base/limits.h"
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "media/base/video_frame.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/dispatch_host_message.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/ppapi_host.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/host_dispatcher.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/host_resource.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/enter.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/ppb_buffer_api.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::HostResource;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::TrackedCallback;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::EnterResourceNoLock;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::PPB_Buffer_API;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum number of buffers to actually allocate.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const uint32_t kMaxBuffers = 20;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochPepperVideoCaptureHost::PepperVideoCaptureHost(RendererPpapiHostImpl* host,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               PP_Instance instance,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               PP_Resource resource)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : ResourceHost(host->GetPpapiHost(), instance, resource),
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      renderer_ppapi_host_(host),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buffer_count_hint_(0),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      enumeration_helper_(this,
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          PepperMediaDeviceManager::GetForRenderFrame(
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              host->GetRenderFrameForInstance(pp_instance())),
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                          PP_DEVICETYPE_DEV_VIDEOCAPTURE,
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                          host->GetDocumentURL(instance)) {
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuPepperVideoCaptureHost::~PepperVideoCaptureHost() {
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Close();
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PepperVideoCaptureHost::Init() {
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return !!renderer_ppapi_host_->GetPluginInstance(pp_instance());
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::OnResourceMessageReceived(
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const IPC::Message& msg,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32_t result = PP_ERROR_FAILED;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enumeration_helper_.HandleResourceMessage(msg, context, &result))
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg)
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_Open, OnOpen)
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StartCapture,
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        OnStartCapture)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_ReuseBuffer,
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      OnReuseBuffer)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StopCapture,
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        OnStopCapture)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_Close,
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        OnClose)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_END_MESSAGE_MAP()
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_ERROR_FAILED;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid PepperVideoCaptureHost::OnInitialized(bool succeeded) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (succeeded) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    open_reply_context_.params.set_result(PP_OK);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DetachPlatformVideoCapture();
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    open_reply_context_.params.set_result(PP_ERROR_FAILED);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host()->SendReply(open_reply_context_,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    PpapiPluginMsg_VideoCapture_OpenReply());
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid PepperVideoCaptureHost::OnStarted() {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTED, false))
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendStatus();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid PepperVideoCaptureHost::OnStopped() {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, false))
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendStatus();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid PepperVideoCaptureHost::OnPaused() {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false))
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendStatus();
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid PepperVideoCaptureHost::OnError() {
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  PostErrorReply();
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void PepperVideoCaptureHost::PostErrorReply() {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It either comes because some error was detected while starting (e.g. 2
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // conflicting "master" resolution), or because the browser failed to start
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the capture.
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true);
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  host()->SendUnsolicitedReply(
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pp_resource(),
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      PpapiPluginMsg_VideoCapture_OnError(
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          static_cast<uint32_t>(PP_ERROR_FAILED)));
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PepperVideoCaptureHost::OnFrameReady(
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const scoped_refptr<media::VideoFrame>& frame,
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    media::VideoCaptureFormat format) {
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(frame.get());
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (alloc_size_ != frame->coded_size() || buffers_.empty()) {
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    AllocBuffers(frame->coded_size(), format.frame_rate);
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    alloc_size_ = frame->coded_size();
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint32_t i = 0; i < buffers_.size(); ++i) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!buffers_[i].in_use) {
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      DCHECK_EQ(frame->format(), media::VideoFrame::I420);
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (buffers_[i].buffer->size() <
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          media::VideoFrame::AllocationSize(frame->format(),
137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                            frame->coded_size())) {
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // TODO(ihf): handle size mismatches gracefully here.
139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        return;
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      uint8* dst = reinterpret_cast<uint8*>(buffers_[i].data);
142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      COMPILE_ASSERT(media::VideoFrame::kYPlane == 0, y_plane_should_be_0);
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      COMPILE_ASSERT(media::VideoFrame::kUPlane == 1, u_plane_should_be_1);
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      COMPILE_ASSERT(media::VideoFrame::kVPlane == 2, v_plane_should_be_2);
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      for (size_t j = 0; j < media::VideoFrame::NumPlanes(frame->format());
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           ++j) {
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        const uint8* src = frame->data(j);
148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        const size_t row_bytes = frame->row_bytes(j);
149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        const size_t src_stride = frame->stride(j);
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        for (int k = 0; k < frame->rows(j); ++k) {
151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          memcpy(dst, src, row_bytes);
152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          dst += row_bytes;
153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          src += src_stride;
154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        }
155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buffers_[i].in_use = true;
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      host()->SendUnsolicitedReply(
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_resource(), PpapiPluginMsg_VideoCapture_OnBufferReady(i));
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PepperVideoCaptureHost::AllocBuffers(const gfx::Size& resolution,
165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                          int frame_rate) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_VideoCaptureDeviceInfo_Dev info = {
167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      static_cast<uint32_t>(resolution.width()),
168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      static_cast<uint32_t>(resolution.height()),
169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      static_cast<uint32_t>(frame_rate)};
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReleaseBuffers();
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const size_t size = media::VideoFrame::AllocationSize(
173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      media::VideoFrame::I420, gfx::Size(info.width, info.height));
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ppapi::proxy::ResourceMessageReplyParams params(pp_resource(), 0);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allocate buffers. We keep a reference to them, that is released in
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ReleaseBuffers. In the mean time, we prepare the resource and handle here
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for sending below.
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<HostResource> buffer_host_resources;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffers_.reserve(buffer_count_hint_);
182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ppapi::ResourceTracker* tracker = HostGlobals::Get()->GetResourceTracker();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ppapi::proxy::HostDispatcher* dispatcher =
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < buffer_count_hint_; ++i) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_Resource res = PPB_Buffer_Impl::Create(pp_instance(), size);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!res)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EnterResourceNoLock<PPB_Buffer_API> enter(res, true);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(enter.succeeded());
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferInfo buf;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    buf.buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    buf.data = buf.buffer->Map();
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!buf.data) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tracker->ReleaseResource(res);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    buffers_.push_back(buf);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add to HostResource array to be sent.
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostResource host_resource;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_resource.SetHostResource(pp_instance(), res);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buffer_host_resources.push_back(host_resource);
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Add a reference for the plugin, which is resposible for releasing it.
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tracker->AddRefResource(res);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add the serialized shared memory handle to params. FileDescriptor is
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // treated in special case.
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EnterResourceNoLock<PPB_Buffer_API> enter(res, true);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(enter.succeeded());
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int handle;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int32_t result = enter.object()->GetSharedMemory(&handle);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(result == PP_OK);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // those casts are ugly.
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::PlatformFile platform_file =
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle));
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_POSIX)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          handle;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#error Not implemented.
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      params.AppendHandle(ppapi::proxy::SerializedHandle(
231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          dispatcher->ShareHandleWithRemote(platform_file, false), size));
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (buffers_.empty()) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We couldn't allocate/map buffers at all. Send an error and stop the
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // capture.
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true);
2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    platform_video_capture_->StopCapture();
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    PostErrorReply();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  host()->Send(
245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      new PpapiPluginMsg_ResourceReply(params,
246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                       PpapiPluginMsg_VideoCapture_OnDeviceInfo(
247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                           info, buffer_host_resources, size)));
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::OnOpen(
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context,
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_VideoCaptureDeviceInfo_Dev& requested_info,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t buffer_count) {
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (platform_video_capture_.get())
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetRequestedInfo(requested_info, buffer_count);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!document_url.is_valid())
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return PP_ERROR_FAILED;
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  platform_video_capture_.reset(new PepperPlatformVideoCapture(
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())->
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          GetRoutingID(),
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      device_id,
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      document_url,
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this));
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  open_reply_context_ = context->MakeReplyMessageContext();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::OnStartCapture(
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context) {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false) ||
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !platform_video_capture_.get())
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(buffers_.empty());
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It's safe to call this regardless it's capturing or not, because
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // PepperPlatformVideoCapture maintains the state.
2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  platform_video_capture_->StartCapture(video_capture_params_);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::OnReuseBuffer(
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context,
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t buffer) {
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (buffer >= buffers_.size() || !buffers_[buffer].in_use)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_BADARGUMENT;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffers_[buffer].in_use = false;
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::OnStopCapture(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context) {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return StopCapture();
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::OnClose(
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ppapi::host::HostMessageContext* context) {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Close();
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::StopCapture() {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, false))
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(platform_video_capture_.get());
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReleaseBuffers();
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It's safe to call this regardless it's capturing or not, because
317558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // PepperPlatformVideoCapture maintains the state.
3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  platform_video_capture_->StopCapture();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperVideoCaptureHost::Close() {
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!platform_video_capture_.get())
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_OK;
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopCapture();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(buffers_.empty());
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DetachPlatformVideoCapture();
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PP_OK;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PepperVideoCaptureHost::ReleaseBuffers() {
333ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ppapi::ResourceTracker* tracker = HostGlobals::Get()->GetResourceTracker();
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < buffers_.size(); ++i) {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    buffers_[i].buffer->Unmap();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker->ReleaseResource(buffers_[i].buffer->pp_resource());
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffers_.clear();
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PepperVideoCaptureHost::SendStatus() {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host()->SendUnsolicitedReply(pp_resource(),
343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                               PpapiPluginMsg_VideoCapture_OnStatus(status_));
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PepperVideoCaptureHost::SetRequestedInfo(
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_VideoCaptureDeviceInfo_Dev& device_info,
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t buffer_count) {
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clamp the buffer count to between 1 and |kMaxBuffers|.
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers);
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Clamp the frame rate to between 1 and |kMaxFramesPerSecond - 1|.
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int frames_per_second =
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::min(std::max(device_info.frames_per_second, 1U),
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               static_cast<uint32_t>(media::limits::kMaxFramesPerSecond - 1));
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  video_capture_params_.requested_format = media::VideoCaptureFormat(
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      gfx::Size(device_info.width, device_info.height),
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      frames_per_second,
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      media::PIXEL_FORMAT_I420);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PepperVideoCaptureHost::DetachPlatformVideoCapture() {
3635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (platform_video_capture_) {
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    platform_video_capture_->DetachEventHandler();
3655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    platform_video_capture_.reset();
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status,
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       bool forced) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!forced) {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (status) {
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PP_VIDEO_CAPTURE_STATUS_STOPPED:
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return false;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PP_VIDEO_CAPTURE_STATUS_STARTING:
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPED)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return false;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PP_VIDEO_CAPTURE_STATUS_STARTED:
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switch (status_) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_STARTING:
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_PAUSED:
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default:
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return false;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PP_VIDEO_CAPTURE_STATUS_PAUSED:
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switch (status_) {
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_STARTING:
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_STARTED:
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default:
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return false;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PP_VIDEO_CAPTURE_STATUS_STOPPING:
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switch (status_) {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_STARTING:
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_STARTED:
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case PP_VIDEO_CAPTURE_STATUS_PAUSED:
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default:
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return false;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_ = status;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperVideoCaptureHost::BufferInfo::BufferInfo()
4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : in_use(false), data(NULL), buffer() {
4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuPepperVideoCaptureHost::BufferInfo::~BufferInfo() {
4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
424