blob: 2ed7717158ac7b34fce82fbc8fff052b5709f1c3 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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// VideoCaptureImpl represents a capture device in renderer process. It provides
6// interfaces for clients to Start/Stop capture. It also communicates to clients
7// when buffer is ready, state of capture device is changed.
8
9// VideoCaptureImpl is also a delegate of VideoCaptureMessageFilter which
10// relays operation of capture device to browser process and receives response
11// from browser process.
12
13// The media::VideoCapture and VideoCaptureMessageFilter::Delegate are
14// asynchronous interfaces, which means callers can call those interfaces
15// from any threads without worrying about thread safety.
16// The |capture_message_loop_proxy_| is the working thread of VideoCaptureImpl.
17// All non-const members are accessed only on that working thread.
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010018//
19// Implementation note: tasks are posted bound to Unretained(this) to both the
20// I/O and Capture threads and this is safe (even though the I/O thread is
21// scoped to the renderer process and the capture_message_loop_proxy_ thread is
22// scoped to the VideoCaptureImplManager) because VideoCaptureImplManager only
23// triggers deletion of its VideoCaptureImpl's by calling DeInit which detours
24// through the capture & I/O threads, so as long as nobody posts tasks after the
25// DeInit() call is made, it is guaranteed none of these Unretained posted tasks
26// will dangle after the delete goes through. The "as long as" is guaranteed by
27// clients of VideoCaptureImplManager not using devices after they've
28// RemoveDevice'd them.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029
30#ifndef CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
31#define CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
32
33#include <list>
34#include <map>
35
36#include "content/common/content_export.h"
37#include "content/common/media/video_capture.h"
38#include "content/renderer/media/video_capture_message_filter.h"
39#include "media/video/capture/video_capture.h"
40#include "media/video/capture/video_capture_types.h"
41
42namespace base {
43class MessageLoopProxy;
44}
45
46namespace content {
47
48class CONTENT_EXPORT VideoCaptureImpl
Ben Murdochbb1529c2013-08-08 10:24:53 +010049 : public media::VideoCapture, public VideoCaptureMessageFilter::Delegate {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000050 public:
51 // media::VideoCapture interface.
52 virtual void StartCapture(
53 media::VideoCapture::EventHandler* handler,
54 const media::VideoCaptureCapability& capability) OVERRIDE;
55 virtual void StopCapture(media::VideoCapture::EventHandler* handler) OVERRIDE;
56 virtual void FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) OVERRIDE;
57 virtual bool CaptureStarted() OVERRIDE;
58 virtual int CaptureWidth() OVERRIDE;
59 virtual int CaptureHeight() OVERRIDE;
60 virtual int CaptureFrameRate() OVERRIDE;
61
62 // VideoCaptureMessageFilter::Delegate interface.
63 virtual void OnBufferCreated(base::SharedMemoryHandle handle,
64 int length, int buffer_id) OVERRIDE;
65 virtual void OnBufferReceived(int buffer_id, base::Time timestamp) OVERRIDE;
66 virtual void OnStateChanged(VideoCaptureState state) OVERRIDE;
67 virtual void OnDeviceInfoReceived(
68 const media::VideoCaptureParams& device_info) OVERRIDE;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010069 virtual void OnDeviceInfoChanged(
70 const media::VideoCaptureParams& device_info) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000071 virtual void OnDelegateAdded(int32 device_id) OVERRIDE;
72
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010073 // Stop/resume delivering video frames to clients, based on flag |suspend|.
74 virtual void SuspendCapture(bool suspend);
75
Torne (Richard Coles)58218062012-11-14 11:43:16 +000076 private:
77 friend class VideoCaptureImplManager;
78 friend class VideoCaptureImplTest;
79 friend class MockVideoCaptureImpl;
80
81 struct DIBBuffer;
82 typedef std::map<media::VideoCapture::EventHandler*,
83 media::VideoCaptureCapability> ClientInfo;
84
85 VideoCaptureImpl(media::VideoCaptureSessionId id,
86 base::MessageLoopProxy* capture_message_loop_proxy,
87 VideoCaptureMessageFilter* filter);
88 virtual ~VideoCaptureImpl();
89
90 void DoStartCaptureOnCaptureThread(
91 media::VideoCapture::EventHandler* handler,
92 const media::VideoCaptureCapability& capability);
93 void DoStopCaptureOnCaptureThread(media::VideoCapture::EventHandler* handler);
94 void DoFeedBufferOnCaptureThread(scoped_refptr<VideoFrameBuffer> buffer);
95
96 void DoBufferCreatedOnCaptureThread(base::SharedMemoryHandle handle,
97 int length, int buffer_id);
98 void DoBufferReceivedOnCaptureThread(int buffer_id, base::Time timestamp);
99 void DoStateChangedOnCaptureThread(VideoCaptureState state);
100 void DoDeviceInfoReceivedOnCaptureThread(
101 const media::VideoCaptureParams& device_info);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100102 void DoDeviceInfoChangedOnCaptureThread(
103 const media::VideoCaptureParams& device_info);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104 void DoDelegateAddedOnCaptureThread(int32 device_id);
105
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100106 void DoSuspendCaptureOnCaptureThread(bool suspend);
107
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000108 void Init();
109 void DeInit(base::Closure task);
110 void DoDeInitOnCaptureThread(base::Closure task);
111 void StopDevice();
112 void RestartCapture();
113 void StartCaptureInternal();
114 void AddDelegateOnIOThread();
115 void RemoveDelegateOnIOThread(base::Closure task);
116 virtual void Send(IPC::Message* message);
117
118 // Helpers.
119 bool ClientHasDIB() const;
120 bool RemoveClient(media::VideoCapture::EventHandler* handler,
121 ClientInfo* clients);
122
123 const scoped_refptr<VideoCaptureMessageFilter> message_filter_;
124 const scoped_refptr<base::MessageLoopProxy> capture_message_loop_proxy_;
125 const scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
126 int device_id_;
127
128 // Pool of DIBs. The key is buffer_id.
129 typedef std::map<int, DIBBuffer*> CachedDIB;
130 CachedDIB cached_dibs_;
131
132 ClientInfo clients_;
133
134 ClientInfo clients_pending_on_filter_;
135 ClientInfo clients_pending_on_restart_;
136
137 media::VideoCaptureCapability::Format video_type_;
138
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100139 // Member capture_format_ represents the video format requested by the client
140 // to this class via DoStartCaptureOnCaptureThread.
141 media::VideoCaptureCapability capture_format_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000142
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100143 // The device's video capture format sent from browser process side.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000144 media::VideoCaptureParams device_info_;
145 bool device_info_available_;
146
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100147 bool suspended_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000148 VideoCaptureState state_;
149
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000150 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl);
151};
152
153} // namespace content
154
155#endif // CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_