video_capture_impl_manager.h revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(hclam): This class should be renamed to VideoCaptureService.
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This class provides access to a video capture device in the browser
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// process through IPC. The main function is to deliver video frames
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// to a client.
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// THREADING
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// VideoCaptureImplManager lives only on the render thread. All methods
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// must be called on this thread.
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// VideoFrames are delivered on the IO thread. Callbacks provided by
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// a client are also called on the IO thread.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_MANAGER_H_
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_MANAGER_H_
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/linked_ptr.h"
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/ref_counted.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/weak_ptr.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/threading/thread_checker.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h"
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/common/media/video_capture.h"
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "media/video/capture/video_capture_types.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoCaptureImpl;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoCaptureMessageFilter;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CONTENT_EXPORT VideoCaptureImplManager {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VideoCaptureImplManager();
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~VideoCaptureImplManager();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Open a device associated with the session ID.
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // This method must be called before any methods with the same ID
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // is used.
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Returns a callback that should be used to release the acquired
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // resources.
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::Closure UseDevice(media::VideoCaptureSessionId id);
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Start receiving video frames for the given session ID.
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  //
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |state_update_cb| will be called on the IO thread when capturing
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // state changes.
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // States will be one of the following four:
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // * VIDEO_CAPTURE_STATE_STARTED
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // * VIDEO_CAPTURE_STATE_STOPPED
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // * VIDEO_CAPTURE_STATE_PAUSED
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // * VIDEO_CAPTURE_STATE_ERROR
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  //
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |deliver_frame_cb| will be called on the IO thread when a video
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // frame is ready.
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  //
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Returns a callback that is used to stop capturing. Note that stopping
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // video capture is not synchronous. Client should handle the case where
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // callbacks are called after capturing is instructed to stop, typically
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // by binding the passed callbacks on a WeakPtr.
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::Closure StartCapture(
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      media::VideoCaptureSessionId id,
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const media::VideoCaptureParams& params,
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const VideoCaptureStateUpdateCB& state_update_cb,
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const VideoCaptureDeliverFrameCB& deliver_frame_cb);
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Get supported formats supported by the device for the given session
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // ID. |callback| will be called on the IO thread.
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void GetDeviceSupportedFormats(
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      media::VideoCaptureSessionId id,
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const VideoCaptureDeviceFormatsCB& callback);
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Get supported formats currently in use for the given session ID.
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |callback| will be called on the IO thread.
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void GetDeviceFormatsInUse(
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      media::VideoCaptureSessionId id,
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const VideoCaptureDeviceFormatsCB& callback);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make all existing VideoCaptureImpl instances stop/resume delivering
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // video frames to their clients, depends on flag |suspend|.
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SuspendDevices(bool suspend);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VideoCaptureMessageFilter* video_capture_message_filter() const {
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return filter_.get();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual VideoCaptureImpl* CreateVideoCaptureImplForTesting(
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      media::VideoCaptureSessionId id,
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VideoCaptureMessageFilter* filter) const;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void StopCapture(int client_id, media::VideoCaptureSessionId id);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void UnrefDevice(media::VideoCaptureSessionId id);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The int is used to count clients of the corresponding VideoCaptureImpl.
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // VideoCaptureImpl objects are owned by this object. But they are
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // destroyed on the IO thread. These are raw pointers because we destroy
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // them manually.
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef std::map<media::VideoCaptureSessionId,
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   std::pair<int, VideoCaptureImpl*> >
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VideoCaptureDeviceMap;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VideoCaptureDeviceMap devices_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // This is an internal ID for identifying clients of VideoCaptureImpl.
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // The ID is global for the render process.
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int next_client_id_;
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<VideoCaptureMessageFilter> filter_;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Bound to the render thread.
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ThreadChecker thread_checker_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Bound to the render thread.
12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: Weak pointers must be invalidated before all other member variables.
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::WeakPtrFactory<VideoCaptureImplManager> weak_factory_;
12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplManager);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_MANAGER_H_
133