summaryrefslogtreecommitdiffstats
path: root/media/video/capture/video_capture_proxy.h
blob: 3e51fd42826fb15aeee0c5d503abba63cdacf363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_PROXY_H_
#define MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_PROXY_H_

#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/task.h"
#include "media/video/capture/video_capture.h"

namespace base {
class MessageLoopProxy;
}

namespace media {

// This is a helper class to proxy a VideoCapture::EventHandler. In the renderer
// process, the VideoCaptureImpl calls its handler on a "Video Capture" thread,
// this class allows seamless proxying to another thread ("main thread"), which
// would be the thread where the instance of this class is created. The
// "proxied" handler is then called on that thread.
// Since the VideoCapture is living on the "Video Capture" thread, querying its
// state from the "main thread" is fundamentally racy. Instead this class keeps
// track of the state every time it is called by the VideoCapture (on the VC
// thread), and forwards that information to the main thread.
class VideoCaptureHandlerProxy : public VideoCapture::EventHandler {
 public:
  struct VideoCaptureState {
    VideoCaptureState() : started(false), width(0), height(0), frame_rate(0) {}
    bool started;
    int width;
    int height;
    int frame_rate;
  };

  // Called on main thread.
  VideoCaptureHandlerProxy(
      VideoCapture::EventHandler* proxied,
      scoped_refptr<base::MessageLoopProxy> main_message_loop);
  virtual ~VideoCaptureHandlerProxy();

  // Retrieves the state of the VideoCapture. Must be called on main thread.
  const VideoCaptureState& state() const { return state_; }
  VideoCapture::EventHandler* proxied() const { return proxied_; }

  // VideoCapture::EventHandler implementation, called on VC thread.
  virtual void OnStarted(VideoCapture* capture) OVERRIDE;
  virtual void OnStopped(VideoCapture* capture) OVERRIDE;
  virtual void OnPaused(VideoCapture* capture) OVERRIDE;
  virtual void OnError(VideoCapture* capture, int error_code) OVERRIDE;
  virtual void OnBufferReady(
      VideoCapture* capture,
      scoped_refptr<VideoCapture::VideoFrameBuffer> buffer) OVERRIDE;
  virtual void OnDeviceInfoReceived(
      VideoCapture* capture,
      const VideoCaptureParams& device_info) OVERRIDE;

 private:
  // Called on main thread.
  void OnStartedOnMainThread(
      VideoCapture* capture,
      const VideoCaptureState& state);
  void OnStoppedOnMainThread(
      VideoCapture* capture,
      const VideoCaptureState& state);
  void OnPausedOnMainThread(
      VideoCapture* capture,
      const VideoCaptureState& state);
  void OnErrorOnMainThread(
      VideoCapture* capture,
      const VideoCaptureState& state,
      int error_code);
  void OnBufferReadyOnMainThread(
      VideoCapture* capture,
      const VideoCaptureState& state,
      scoped_refptr<VideoCapture::VideoFrameBuffer> buffer);
  void OnDeviceInfoReceivedOnMainThread(
      VideoCapture* capture,
      const VideoCaptureState& state,
      const VideoCaptureParams& device_info);

  // Only accessed from main thread.
  VideoCapture::EventHandler* proxied_;
  VideoCaptureState state_;

  scoped_refptr<base::MessageLoopProxy> main_message_loop_;
};

}  // namespace media
DISABLE_RUNNABLE_METHOD_REFCOUNT(media::VideoCaptureHandlerProxy);

#endif  // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_PROXY_H_