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/media/rtc_video_capture_delegate.h"
6
7#include "base/bind.h"
8
9namespace content {
10
11RtcVideoCaptureDelegate::RtcVideoCaptureDelegate(
12    const media::VideoCaptureSessionId id,
13    VideoCaptureImplManager* vc_manager)
14    : session_id_(id),
15      vc_manager_(vc_manager),
16      capture_engine_(NULL),
17      got_first_frame_(false),
18      error_occured_(false) {
19  DVLOG(3) << " RtcVideoCaptureDelegate::ctor";
20  capture_engine_ = vc_manager_->AddDevice(session_id_, this);
21}
22
23RtcVideoCaptureDelegate::~RtcVideoCaptureDelegate() {
24  DVLOG(3) << " RtcVideoCaptureDelegate::dtor";
25  vc_manager_->RemoveDevice(session_id_, this);
26}
27
28void RtcVideoCaptureDelegate::StartCapture(
29    const media::VideoCaptureCapability& capability,
30    const FrameCapturedCallback& captured_callback,
31    const StateChangeCallback& state_callback) {
32  DVLOG(3) << " RtcVideoCaptureDelegate::StartCapture ";
33  message_loop_proxy_ = base::MessageLoopProxy::current();
34  captured_callback_ = captured_callback;
35  state_callback_ = state_callback;
36  got_first_frame_ = false;
37  error_occured_ = false;
38
39  // Increase the reference count to ensure we are not deleted until
40  // The we are unregistered in RtcVideoCaptureDelegate::OnRemoved.
41  AddRef();
42  capture_engine_->StartCapture(this, capability);
43}
44
45void RtcVideoCaptureDelegate::StopCapture() {
46  // Immediately make sure we don't provide more frames.
47  captured_callback_.Reset();
48  state_callback_.Reset();
49  capture_engine_->StopCapture(this);
50}
51
52void RtcVideoCaptureDelegate::OnStarted(media::VideoCapture* capture) {
53  DVLOG(3) << " RtcVideoCaptureDelegate::OnStarted";
54}
55
56void RtcVideoCaptureDelegate::OnStopped(media::VideoCapture* capture) {
57}
58
59void RtcVideoCaptureDelegate::OnPaused(media::VideoCapture* capture) {
60  NOTIMPLEMENTED();
61}
62
63void RtcVideoCaptureDelegate::OnError(media::VideoCapture* capture,
64                                      int error_code) {
65  DVLOG(3) << " RtcVideoCaptureDelegate::OnError";
66  message_loop_proxy_->PostTask(
67      FROM_HERE,
68      base::Bind(&RtcVideoCaptureDelegate::OnErrorOnCaptureThread,
69                 this, capture));
70}
71
72void RtcVideoCaptureDelegate::OnRemoved(media::VideoCapture* capture) {
73  DVLOG(3) << " RtcVideoCaptureDelegate::OnRemoved";
74  message_loop_proxy_->PostTask(
75      FROM_HERE,
76      base::Bind(&RtcVideoCaptureDelegate::OnRemovedOnCaptureThread,
77                 this, capture));
78
79  // Balance the AddRef in StartCapture.
80  // This means we are no longer registered as an event handler and can safely
81  // be deleted.
82  Release();
83}
84
85void RtcVideoCaptureDelegate::OnBufferReady(
86    media::VideoCapture* capture,
87    scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) {
88  message_loop_proxy_->PostTask(
89      FROM_HERE,
90      base::Bind(&RtcVideoCaptureDelegate::OnBufferReadyOnCaptureThread,
91                 this, capture, buf));
92}
93
94void RtcVideoCaptureDelegate::OnDeviceInfoReceived(
95    media::VideoCapture* capture,
96    const media::VideoCaptureParams& device_info) {
97  NOTIMPLEMENTED();
98}
99
100void RtcVideoCaptureDelegate::OnDeviceInfoChanged(
101    media::VideoCapture* capture,
102    const media::VideoCaptureParams& device_info) {
103  NOTIMPLEMENTED();
104}
105
106void RtcVideoCaptureDelegate::OnBufferReadyOnCaptureThread(
107    media::VideoCapture* capture,
108    scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) {
109  if (!captured_callback_.is_null()) {
110    if (!got_first_frame_) {
111      got_first_frame_ = true;
112      if (!state_callback_.is_null())
113        state_callback_.Run(CAPTURE_RUNNING);
114    }
115
116    captured_callback_.Run(*buf.get());
117  }
118  capture->FeedBuffer(buf);
119}
120
121void RtcVideoCaptureDelegate::OnErrorOnCaptureThread(
122    media::VideoCapture* capture) {
123  error_occured_ = true;
124  if (!state_callback_.is_null())
125    state_callback_.Run(CAPTURE_FAILED);
126}
127
128
129void RtcVideoCaptureDelegate::OnRemovedOnCaptureThread(
130    media::VideoCapture* capture) {
131  if (!error_occured_ && !state_callback_.is_null())
132    state_callback_.Run(CAPTURE_STOPPED);
133}
134
135}  // namespace content
136