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" 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/renderer/media_stream_video_sink.h" 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "media/video/capture/video_capture_types.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoCaptureImpl; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoCaptureMessageFilter; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CONTENT_EXPORT VideoCaptureImplManager { 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VideoCaptureImplManager(); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~VideoCaptureImplManager(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Open a device associated with the session ID. 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // This method must be called before any methods with the same ID 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // is used. 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Returns a callback that should be used to release the acquired 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // resources. 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Closure UseDevice(media::VideoCaptureSessionId id); 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Start receiving video frames for the given session ID. 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |state_update_cb| will be called on the IO thread when capturing 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // state changes. 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // States will be one of the following four: 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // * VIDEO_CAPTURE_STATE_STARTED 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // * VIDEO_CAPTURE_STATE_STOPPED 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // * VIDEO_CAPTURE_STATE_PAUSED 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // * VIDEO_CAPTURE_STATE_ERROR 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |deliver_frame_cb| will be called on the IO thread when a video 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // frame is ready. 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Returns a callback that is used to stop capturing. Note that stopping 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // video capture is not synchronous. Client should handle the case where 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // callbacks are called after capturing is instructed to stop, typically 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // by binding the passed callbacks on a WeakPtr. 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Closure StartCapture( 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu media::VideoCaptureSessionId id, 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const media::VideoCaptureParams& params, 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const VideoCaptureStateUpdateCB& state_update_cb, 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const VideoCaptureDeliverFrameCB& deliver_frame_cb); 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Get supported formats supported by the device for the given session 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // ID. |callback| will be called on the IO thread. 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void GetDeviceSupportedFormats( 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu media::VideoCaptureSessionId id, 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const VideoCaptureDeviceFormatsCB& callback); 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Get supported formats currently in use for the given session ID. 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |callback| will be called on the IO thread. 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void GetDeviceFormatsInUse( 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu media::VideoCaptureSessionId id, 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const VideoCaptureDeviceFormatsCB& callback); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make all existing VideoCaptureImpl instances stop/resume delivering 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // video frames to their clients, depends on flag |suspend|. 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SuspendDevices(bool suspend); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoCaptureMessageFilter* video_capture_message_filter() const { 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return filter_.get(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual VideoCaptureImpl* CreateVideoCaptureImplForTesting( 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) media::VideoCaptureSessionId id, 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VideoCaptureMessageFilter* filter) const; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void StopCapture(int client_id, media::VideoCaptureSessionId id); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UnrefDevice(media::VideoCaptureSessionId id); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The int is used to count clients of the corresponding VideoCaptureImpl. 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // VideoCaptureImpl objects are owned by this object. But they are 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // destroyed on the IO thread. These are raw pointers because we destroy 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // them manually. 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef std::map<media::VideoCaptureSessionId, 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::pair<int, VideoCaptureImpl*> > 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VideoCaptureDeviceMap; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VideoCaptureDeviceMap devices_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // This is an internal ID for identifying clients of VideoCaptureImpl. 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The ID is global for the render process. 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int next_client_id_; 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<VideoCaptureMessageFilter> filter_; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Bound to the render thread. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ThreadChecker thread_checker_; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Bound to the render thread. 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // NOTE: Weak pointers must be invalidated before all other member variables. 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::WeakPtrFactory<VideoCaptureImplManager> weak_factory_; 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplManager); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_MANAGER_H_ 134