Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(986)

Side by Side Diff: content/browser/renderer_host/media/video_capture_controller.h

Issue 24133002: Make VideoCaptureController single-threaded and not ref counted. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix a memory leak Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // VideoCaptureController is the glue between a VideoCaptureDevice and all 5 // VideoCaptureController is the glue between a VideoCaptureDevice and all
6 // VideoCaptureHosts that have connected to it. A controller exists on behalf of 6 // VideoCaptureHosts that have connected to it. A controller exists on behalf of
7 // one (and only one) VideoCaptureDevice; both are owned by the 7 // one (and only one) VideoCaptureDevice; both are owned by the
8 // VideoCaptureManager. 8 // VideoCaptureManager.
9 // 9 //
10 // The VideoCaptureController is responsible for: 10 // The VideoCaptureController is responsible for:
11 // 11 //
12 // * Allocating and keeping track of shared memory buffers, and filling them 12 // * Allocating and keeping track of shared memory buffers, and filling them
13 // with I420 video frames for IPC communication between VideoCaptureHost (in 13 // with I420 video frames for IPC communication between VideoCaptureHost (in
14 // the browser process) and VideoCaptureMessageFilter (in the renderer 14 // the browser process) and VideoCaptureMessageFilter (in the renderer
15 // process). 15 // process).
16 // * Conveying events from the device thread (where capture devices live) to
17 // the IO thread (where the clients can be reached).
18 // * Broadcasting the events from a single VideoCaptureDevice, fanning them 16 // * Broadcasting the events from a single VideoCaptureDevice, fanning them
19 // out to multiple clients. 17 // out to multiple clients.
20 // * Keeping track of the clients on behalf of the VideoCaptureManager, making 18 // * Keeping track of the clients on behalf of the VideoCaptureManager, making
21 // it possible for the Manager to delete the Controller and its Device when 19 // it possible for the Manager to delete the Controller and its Device when
22 // there are no clients left. 20 // there are no clients left.
21 //
22 // A helper class, VCC::VideoCaptureDeviceClient, is responsible for:
23 //
24 // * Conveying events from the device thread (where VideoCaptureDevices live)
25 // the IO thread (where the VideoCaptureController lives).
23 // * Performing some image transformations on the output of the Device; 26 // * Performing some image transformations on the output of the Device;
24 // specifically, colorspace conversion and rotation. 27 // specifically, colorspace conversion and rotation.
25 // 28 //
26 // Interactions between VideoCaptureController and other classes: 29 // Interactions between VideoCaptureController and other classes:
27 // 30 //
28 // * VideoCaptureController receives events from its VideoCaptureDevice 31 // * VideoCaptureController indirectly observes a VideoCaptureDevice
29 // entirely through the VideoCaptureDevice::EventHandler interface, which 32 // by means of its proxy, VideoCaptureDeviceClient, which implements
30 // VCC implements. 33 // the VideoCaptureDevice::EventHandler interface. The proxy forwards
34 // observed events to the VideoCaptureController on the IO thread.
31 // * A VideoCaptureController interacts with its clients (VideoCaptureHosts) 35 // * A VideoCaptureController interacts with its clients (VideoCaptureHosts)
32 // via the VideoCaptureControllerEventHandler interface. 36 // via the VideoCaptureControllerEventHandler interface.
33 // * Conversely, a VideoCaptureControllerEventHandler (typically, 37 // * Conversely, a VideoCaptureControllerEventHandler (typically,
34 // VideoCaptureHost) will interact directly with VideoCaptureController to 38 // VideoCaptureHost) will interact directly with VideoCaptureController to
35 // return leased buffers by means of the ReturnBuffer() public method of 39 // return leased buffers by means of the ReturnBuffer() public method of
36 // VCC. 40 // VCC.
37 // * VideoCaptureManager (which owns the VCC) interacts directly with 41 // * VideoCaptureManager (which owns the VCC) interacts directly with
38 // VideoCaptureController through its public methods, to add and remove 42 // VideoCaptureController through its public methods, to add and remove
39 // clients. 43 // clients.
40 // 44 //
41 // Thread safety: 45 // VideoCaptureController is not thread safe and operates on the IO thread only.
42 //
43 // The public methods implementing the VCD::EventHandler interface are safe to
44 // call from any thread -- in practice, this is the thread on which the Device
45 // is running. For this reason, it is RefCountedThreadSafe. ALL OTHER METHODS
46 // are only safe to run on the IO browser thread.
47 46
48 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_CONTROLLER_H_ 47 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_CONTROLLER_H_
49 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_CONTROLLER_H_ 48 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_CONTROLLER_H_
50 49
51 #include <list> 50 #include <list>
52 #include <map> 51 #include <map>
53 52
54 #include "base/compiler_specific.h" 53 #include "base/compiler_specific.h"
55 #include "base/memory/ref_counted.h" 54 #include "base/memory/ref_counted.h"
55 #include "base/memory/scoped_ptr.h"
56 #include "base/memory/weak_ptr.h"
56 #include "base/process/process.h" 57 #include "base/process/process.h"
57 #include "base/synchronization/lock.h" 58 #include "base/synchronization/lock.h"
58 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" 59 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
59 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" 60 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h"
60 #include "content/common/content_export.h" 61 #include "content/common/content_export.h"
61 #include "content/common/media/video_capture.h" 62 #include "content/common/media/video_capture.h"
62 #include "media/video/capture/video_capture.h" 63 #include "media/video/capture/video_capture.h"
63 #include "media/video/capture/video_capture_device.h" 64 #include "media/video/capture/video_capture_device.h"
64 #include "media/video/capture/video_capture_types.h" 65 #include "media/video/capture/video_capture_types.h"
65 66
66 namespace content { 67 namespace content {
67 class VideoCaptureBufferPool; 68 class VideoCaptureBufferPool;
68 69
69 class CONTENT_EXPORT VideoCaptureController 70 class CONTENT_EXPORT VideoCaptureController {
70 : public base::RefCountedThreadSafe<VideoCaptureController>,
71 public media::VideoCaptureDevice::EventHandler {
72 public: 71 public:
73 VideoCaptureController(); 72 VideoCaptureController();
73 virtual ~VideoCaptureController();
74
75 base::WeakPtr<VideoCaptureController> AsWeakPtr();
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 "As" connotes SupportsWeakPtr, which is generally
ncarter (slow) 2013/09/14 00:07:24 Done. Having thought about it, I agree with you.
76
77 // Return a new VideoCaptureDeviceClient to forward capture events to this
78 // instance.
79 scoped_ptr<media::VideoCaptureDevice::EventHandler> NewDeviceClient();
74 80
75 // Start video capturing and try to use the resolution specified in 81 // Start video capturing and try to use the resolution specified in
76 // |params|. 82 // |params|.
77 // When capturing starts, the |event_handler| will receive an OnFrameInfo() 83 // When capturing starts, the |event_handler| will receive an OnFrameInfo()
78 // call informing it of the resolution that was actually picked by the device. 84 // call informing it of the resolution that was actually picked by the device.
79 void AddClient(const VideoCaptureControllerID& id, 85 void AddClient(const VideoCaptureControllerID& id,
80 VideoCaptureControllerEventHandler* event_handler, 86 VideoCaptureControllerEventHandler* event_handler,
81 base::ProcessHandle render_process, 87 base::ProcessHandle render_process,
82 const media::VideoCaptureParams& params); 88 const media::VideoCaptureParams& params);
83 89
84 // Stop video capture. This will take back all buffers held by by 90 // Stop video capture. This will take back all buffers held by by
85 // |event_handler|, and |event_handler| shouldn't use those buffers any more. 91 // |event_handler|, and |event_handler| shouldn't use those buffers any more.
86 // Returns the session_id of the stopped client, or 92 // Returns the session_id of the stopped client, or
87 // kInvalidMediaCaptureSessionId if the indicated client was not registered. 93 // kInvalidMediaCaptureSessionId if the indicated client was not registered.
88 int RemoveClient(const VideoCaptureControllerID& id, 94 int RemoveClient(const VideoCaptureControllerID& id,
89 VideoCaptureControllerEventHandler* event_handler); 95 VideoCaptureControllerEventHandler* event_handler);
90 96
91 int GetClientCount(); 97 int GetClientCount();
92 98
93 // API called directly by VideoCaptureManager in case the device is 99 // API called directly by VideoCaptureManager in case the device is
94 // prematurely closed. 100 // prematurely closed.
95 void StopSession(int session_id); 101 void StopSession(int session_id);
96 102
97 // Return a buffer previously given in 103 // Return a buffer previously given in
98 // VideoCaptureControllerEventHandler::OnBufferReady. 104 // VideoCaptureControllerEventHandler::OnBufferReady.
99 void ReturnBuffer(const VideoCaptureControllerID& id, 105 void ReturnBuffer(const VideoCaptureControllerID& id,
100 VideoCaptureControllerEventHandler* event_handler, 106 VideoCaptureControllerEventHandler* event_handler,
101 int buffer_id); 107 int buffer_id);
102 108
103 // Implement media::VideoCaptureDevice::EventHandler. 109 private:
104 virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() OVERRIDE; 110 // Receives events from the VideoCaptureDevice and posts them to a
105 virtual void OnIncomingCapturedFrame(const uint8* data, 111 // VideoCaptureController on the IO thread. An instance of this class may
106 int length, 112 // safely outlive its target VideoCaptureController. Methods of this class may
107 base::Time timestamp, 113 // be called from any thread.
108 int rotation, 114 class VideoCaptureDeviceClient
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 Could this move into the .cc file with merely a fw
ncarter (slow) 2013/09/14 00:07:24 Sure. Done. FWIW, I put it here in the header for
109 bool flip_vert, 115 : public media::VideoCaptureDevice::EventHandler {
110 bool flip_horiz) OVERRIDE; 116 public:
111 virtual void OnIncomingCapturedVideoFrame( 117 explicit VideoCaptureDeviceClient(
112 const scoped_refptr<media::VideoFrame>& frame, 118 const base::WeakPtr<VideoCaptureController>& controller);
113 base::Time timestamp) OVERRIDE; 119 virtual ~VideoCaptureDeviceClient();
114 virtual void OnError() OVERRIDE;
115 virtual void OnFrameInfo(const media::VideoCaptureCapability& info) OVERRIDE;
116 virtual void OnFrameInfoChanged(
117 const media::VideoCaptureCapability& info) OVERRIDE;
118 120
119 protected: 121 // VideoCaptureDevice::EventHandler implementation.
120 virtual ~VideoCaptureController(); 122 virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() OVERRIDE;
123 virtual void OnIncomingCapturedFrame(const uint8* data,
124 int length,
125 base::Time timestamp,
126 int rotation,
127 bool flip_vert,
128 bool flip_horiz) OVERRIDE;
129 virtual void OnIncomingCapturedVideoFrame(
130 const scoped_refptr<media::VideoFrame>& frame,
131 base::Time timestamp) OVERRIDE;
132 virtual void OnError() OVERRIDE;
133 virtual void OnFrameInfo(
134 const media::VideoCaptureCapability& info) OVERRIDE;
135 virtual void OnFrameInfoChanged(
136 const media::VideoCaptureCapability& info) OVERRIDE;
121 137
122 private: 138 private:
123 friend class base::RefCountedThreadSafe<VideoCaptureController>; 139 // The controller to which we post events.
140 const base::WeakPtr<VideoCaptureController> controller_;
141
142 // The pool of shared-memory buffers used for capturing.
143 scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
144
145 // Chopped pixels in width/height in case video capture device has odd
146 // numbers for width/height.
147 int chopped_width_;
148 int chopped_height_;
149
150 // Tracks the current frame format.
151 media::VideoCaptureCapability frame_info_;
152 };
124 153
125 struct ControllerClient; 154 struct ControllerClient;
126 typedef std::list<ControllerClient*> ControllerClients; 155 typedef std::list<ControllerClient*> ControllerClients;
127 156
128 // Worker functions on IO thread. 157 // Worker functions on IO thread. Called by the VideoCaptureDeviceClient.
129 void DoIncomingCapturedFrameOnIOThread( 158 void DoIncomingCapturedFrameOnIOThread(
130 const scoped_refptr<media::VideoFrame>& captured_frame, 159 const scoped_refptr<media::VideoFrame>& captured_frame,
131 base::Time timestamp); 160 base::Time timestamp);
132 void DoFrameInfoOnIOThread(); 161 void DoFrameInfoOnIOThread(
162 const media::VideoCaptureCapability& frame_info,
163 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool);
133 void DoFrameInfoChangedOnIOThread(const media::VideoCaptureCapability& info); 164 void DoFrameInfoChangedOnIOThread(const media::VideoCaptureCapability& info);
134 void DoErrorOnIOThread(); 165 void DoErrorOnIOThread();
135 void DoDeviceStoppedOnIOThread(); 166 void DoDeviceStoppedOnIOThread();
136 167
137 // Send frame info and init buffers to |client|. 168 // Send frame info and init buffers to |client|.
138 void SendFrameInfoAndBuffers(ControllerClient* client); 169 void SendFrameInfoAndBuffers(ControllerClient* client);
139 170
140 // Find a client of |id| and |handler| in |clients|. 171 // Find a client of |id| and |handler| in |clients|.
141 ControllerClient* FindClient( 172 ControllerClient* FindClient(
142 const VideoCaptureControllerID& id, 173 const VideoCaptureControllerID& id,
143 VideoCaptureControllerEventHandler* handler, 174 VideoCaptureControllerEventHandler* handler,
144 const ControllerClients& clients); 175 const ControllerClients& clients);
145 176
146 // Find a client of |session_id| in |clients|. 177 // Find a client of |session_id| in |clients|.
147 ControllerClient* FindClient( 178 ControllerClient* FindClient(
148 int session_id, 179 int session_id,
149 const ControllerClients& clients); 180 const ControllerClients& clients);
150 181
151 // Protects access to the |buffer_pool_| pointer on non-IO threads. IO thread
152 // must hold this lock when modifying the |buffer_pool_| pointer itself.
153 // TODO(nick): Make it so that this lock isn't required.
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 You made it so!
ncarter (slow) 2013/09/14 00:07:24 Done.
154 base::Lock buffer_pool_lock_;
155
156 // The pool of shared-memory buffers used for capturing. 182 // The pool of shared-memory buffers used for capturing.
157 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; 183 scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
158 184
159 // All clients served by this controller. 185 // All clients served by this controller.
160 ControllerClients controller_clients_; 186 ControllerClients controller_clients_;
161 187
162 // The parameter that currently used for the capturing. 188 // The parameter that currently used for the capturing.
163 media::VideoCaptureParams current_params_; 189 media::VideoCaptureParams current_params_;
164 190
165 // It's modified on caller thread, assuming there is only one OnFrameInfo() 191 // Tracks whether OnFrameInfo() has occurred, and whether |frame_info_| is
166 // call per StartCapture(). 192 // valid.
193 bool frame_info_available_;
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 VideoCaptureCapability's default ctor zero-initial
ncarter (slow) 2013/09/14 00:07:24 Neato. Done.
194
195 // Tracks the current frame format.
167 media::VideoCaptureCapability frame_info_; 196 media::VideoCaptureCapability frame_info_;
168 197
169 // Chopped pixels in width/height in case video capture device has odd numbers 198 // Takes on only the states 'STARTED' and 'ERROR'. 'ERROR' is an absorbing
170 // for width/height. Accessed only on the device thread. 199 // state which stops the flow of data to clients.
171 int chopped_width_; 200 VideoCaptureState state_;
172 int chopped_height_;
173 201
174 // It's accessed only on IO thread. 202 base::WeakPtrFactory<VideoCaptureController> weak_ptr_factory_;
175 bool frame_info_available_;
176
177 // Takes on only the states 'STARTED' and 'ERROR'. 'ERROR' is an absorbing
178 // state which stops the flow of data to clients. Accessed only on IO thread.
179 VideoCaptureState state_;
180 203
181 DISALLOW_COPY_AND_ASSIGN(VideoCaptureController); 204 DISALLOW_COPY_AND_ASSIGN(VideoCaptureController);
182 }; 205 };
183 206
184 } // namespace content 207 } // namespace content
185 208
186 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_CONTROLLER_H_ 209 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_CONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698