Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 2012 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 "content/renderer/pepper/pepper_platform_video_capture.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "content/renderer/media/video_capture_impl_manager.h"
     11 #include "content/renderer/pepper/pepper_media_device_manager.h"
     12 #include "content/renderer/pepper/pepper_video_capture_host.h"
     13 #include "content/renderer/render_frame_impl.h"
     14 #include "content/renderer/render_thread_impl.h"
     15 #include "media/base/bind_to_current_loop.h"
     16 #include "url/gurl.h"
     17 
     18 namespace content {
     19 
     20 PepperPlatformVideoCapture::PepperPlatformVideoCapture(
     21     int render_frame_id,
     22     const std::string& device_id,
     23     const GURL& document_url,
     24     PepperVideoCaptureHost* handler)
     25     : render_frame_id_(render_frame_id),
     26       device_id_(device_id),
     27       session_id_(0),
     28       handler_(handler),
     29       pending_open_device_(false),
     30       pending_open_device_id_(-1),
     31       weak_factory_(this) {
     32   // We need to open the device and obtain the label and session ID before
     33   // initializing.
     34   PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
     35   if (device_manager) {
     36     pending_open_device_id_ = device_manager->OpenDevice(
     37         PP_DEVICETYPE_DEV_VIDEOCAPTURE,
     38         device_id,
     39         document_url,
     40         base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened,
     41                    weak_factory_.GetWeakPtr()));
     42     pending_open_device_ = true;
     43   }
     44 }
     45 
     46 void PepperPlatformVideoCapture::StartCapture(
     47     const media::VideoCaptureParams& params) {
     48   DCHECK(thread_checker_.CalledOnValidThread());
     49   if (!stop_capture_cb_.is_null())
     50     return;
     51   VideoCaptureImplManager* manager =
     52       RenderThreadImpl::current()->video_capture_impl_manager();
     53   stop_capture_cb_ =
     54       manager->StartCapture(session_id_,
     55                             params,
     56                             media::BindToCurrentLoop(base::Bind(
     57                                 &PepperPlatformVideoCapture::OnStateUpdate,
     58                                 weak_factory_.GetWeakPtr())),
     59                             media::BindToCurrentLoop(base::Bind(
     60                                 &PepperPlatformVideoCapture::OnFrameReady,
     61                                 weak_factory_.GetWeakPtr())));
     62 }
     63 
     64 void PepperPlatformVideoCapture::StopCapture() {
     65   DCHECK(thread_checker_.CalledOnValidThread());
     66   if (stop_capture_cb_.is_null())
     67     return;
     68   stop_capture_cb_.Run();
     69   stop_capture_cb_.Reset();
     70 }
     71 
     72 void PepperPlatformVideoCapture::DetachEventHandler() {
     73   handler_ = NULL;
     74   StopCapture();
     75   if (!release_device_cb_.is_null()) {
     76     release_device_cb_.Run();
     77     release_device_cb_.Reset();
     78   }
     79   if (!label_.empty()) {
     80     PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
     81     if (device_manager)
     82       device_manager->CloseDevice(label_);
     83     label_.clear();
     84   }
     85   if (pending_open_device_) {
     86     PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
     87     if (device_manager)
     88       device_manager->CancelOpenDevice(pending_open_device_id_);
     89     pending_open_device_ = false;
     90     pending_open_device_id_ = -1;
     91   }
     92 }
     93 
     94 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() {
     95   DCHECK(stop_capture_cb_.is_null());
     96   DCHECK(release_device_cb_.is_null());
     97   DCHECK(label_.empty());
     98   DCHECK(!pending_open_device_);
     99 }
    100 
    101 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id,
    102                                                 bool succeeded,
    103                                                 const std::string& label) {
    104   pending_open_device_ = false;
    105   pending_open_device_id_ = -1;
    106 
    107   PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
    108   succeeded = succeeded && device_manager;
    109   if (succeeded) {
    110     label_ = label;
    111     session_id_ = device_manager->GetSessionID(
    112         PP_DEVICETYPE_DEV_VIDEOCAPTURE, label);
    113     VideoCaptureImplManager* manager =
    114         RenderThreadImpl::current()->video_capture_impl_manager();
    115     release_device_cb_ = manager->UseDevice(session_id_);
    116   }
    117 
    118   if (handler_)
    119     handler_->OnInitialized(succeeded);
    120 }
    121 
    122 void PepperPlatformVideoCapture::OnStateUpdate(VideoCaptureState state) {
    123   if (!handler_)
    124     return;
    125   switch (state) {
    126     case VIDEO_CAPTURE_STATE_STARTED:
    127       handler_->OnStarted();
    128       break;
    129     case VIDEO_CAPTURE_STATE_STOPPED:
    130       handler_->OnStopped();
    131       break;
    132     case VIDEO_CAPTURE_STATE_PAUSED:
    133       handler_->OnPaused();
    134       break;
    135     case VIDEO_CAPTURE_STATE_ERROR:
    136       handler_->OnError();
    137       break;
    138     default:
    139       NOTREACHED() << "Unexpected state: " << state << ".";
    140   }
    141 }
    142 
    143 void PepperPlatformVideoCapture::OnFrameReady(
    144     const scoped_refptr<media::VideoFrame>& frame,
    145     const media::VideoCaptureFormat& format,
    146     const base::TimeTicks& estimated_capture_time) {
    147   if (handler_ && !stop_capture_cb_.is_null())
    148     handler_->OnFrameReady(frame, format);
    149 }
    150 
    151 PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() {
    152   RenderFrameImpl* const render_frame =
    153       RenderFrameImpl::FromRoutingID(render_frame_id_);
    154   return render_frame ?
    155       PepperMediaDeviceManager::GetForRenderFrame(render_frame).get() : NULL;
    156 }
    157 
    158 }  // namespace content
    159