Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 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 | // 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) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 18 | // |
| 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 29 | |
| 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 | |
| 42 | namespace base { |
| 43 | class MessageLoopProxy; |
| 44 | } |
| 45 | |
| 46 | namespace content { |
| 47 | |
| 48 | class CONTENT_EXPORT VideoCaptureImpl |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 49 | : public media::VideoCapture, public VideoCaptureMessageFilter::Delegate { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 50 | 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 69 | virtual void OnDeviceInfoChanged( |
| 70 | const media::VideoCaptureParams& device_info) OVERRIDE; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 71 | virtual void OnDelegateAdded(int32 device_id) OVERRIDE; |
| 72 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 73 | // Stop/resume delivering video frames to clients, based on flag |suspend|. |
| 74 | virtual void SuspendCapture(bool suspend); |
| 75 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 76 | 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 102 | void DoDeviceInfoChangedOnCaptureThread( |
| 103 | const media::VideoCaptureParams& device_info); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 104 | void DoDelegateAddedOnCaptureThread(int32 device_id); |
| 105 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 106 | void DoSuspendCaptureOnCaptureThread(bool suspend); |
| 107 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 108 | 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) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 139 | // 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 142 | |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 143 | // The device's video capture format sent from browser process side. |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 144 | media::VideoCaptureParams device_info_; |
| 145 | bool device_info_available_; |
| 146 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 147 | bool suspended_; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 148 | VideoCaptureState state_; |
| 149 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 150 | DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl); |
| 151 | }; |
| 152 | |
| 153 | } // namespace content |
| 154 | |
| 155 | #endif // CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_ |