summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/media/capture/content_video_capture_device_core.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/media/capture/content_video_capture_device_core.h')
-rw-r--r--chromium/content/browser/media/capture/content_video_capture_device_core.h204
1 files changed, 204 insertions, 0 deletions
diff --git a/chromium/content/browser/media/capture/content_video_capture_device_core.h b/chromium/content/browser/media/capture/content_video_capture_device_core.h
new file mode 100644
index 00000000000..3a7e6974ae7
--- /dev/null
+++ b/chromium/content/browser/media/capture/content_video_capture_device_core.h
@@ -0,0 +1,204 @@
+// Copyright 2014 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 CONTENT_BROWSER_MEDIA_CAPTURE_CONTENT_VIDEO_CAPTURE_DEVICE_CORE_H_
+#define CONTENT_BROWSER_MEDIA_CAPTURE_CONTENT_VIDEO_CAPTURE_DEVICE_CORE_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_checker.h"
+#include "content/browser/media/capture/video_capture_oracle.h"
+#include "content/common/content_export.h"
+#include "media/base/video_frame.h"
+#include "media/video/capture/video_capture_device.h"
+
+namespace media {
+class VideoCaptureParams;
+class VideoFrame;
+} // namespace media
+
+namespace content {
+
+const int kMinFrameWidth = 2;
+const int kMinFrameHeight = 2;
+
+// Returns the nearest even integer closer to zero.
+template<typename IntType>
+IntType MakeEven(IntType x) {
+ return x & static_cast<IntType>(-2);
+}
+
+// TODO(nick): Remove this once frame subscription is supported on Aura and
+// Linux.
+#if (defined(OS_WIN) || defined(OS_MACOSX)) || defined(USE_AURA)
+const bool kAcceleratedSubscriberIsSupported = true;
+#else
+const bool kAcceleratedSubscriberIsSupported = false;
+#endif
+
+class VideoCaptureMachine;
+
+// Thread-safe, refcounted proxy to the VideoCaptureOracle. This proxy wraps
+// the VideoCaptureOracle, which decides which frames to capture, and a
+// VideoCaptureDevice::Client, which allocates and receives the captured
+// frames, in a lock to synchronize state between the two.
+class ThreadSafeCaptureOracle
+ : public base::RefCountedThreadSafe<ThreadSafeCaptureOracle> {
+ public:
+ ThreadSafeCaptureOracle(scoped_ptr<media::VideoCaptureDevice::Client> client,
+ scoped_ptr<VideoCaptureOracle> oracle,
+ const media::VideoCaptureParams& params);
+
+ // Called when a captured frame is available or an error has occurred.
+ // If |success| is true then |frame| is valid and |timestamp| indicates when
+ // the frame was painted.
+ // If |success| is false, all other parameters are invalid.
+ typedef base::Callback<void(const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks timestamp,
+ bool success)> CaptureFrameCallback;
+
+ bool ObserveEventAndDecideCapture(VideoCaptureOracle::Event event,
+ base::TimeTicks event_time,
+ scoped_refptr<media::VideoFrame>* storage,
+ CaptureFrameCallback* callback);
+
+ base::TimeDelta capture_period() const {
+ return oracle_->capture_period();
+ }
+
+ // Returns the current capture resolution.
+ gfx::Size GetCaptureSize() const;
+
+ // Updates capture resolution based on the supplied source size and the
+ // maximum frame size.
+ void UpdateCaptureSize(const gfx::Size& source_size);
+
+ // Stop new captures from happening (but doesn't forget the client).
+ void Stop();
+
+ // Signal an error to the client.
+ void ReportError(const std::string& reason);
+
+ private:
+ friend class base::RefCountedThreadSafe<ThreadSafeCaptureOracle>;
+ virtual ~ThreadSafeCaptureOracle();
+
+ // Callback invoked on completion of all captures.
+ void DidCaptureFrame(
+ int frame_number,
+ const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
+ const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks timestamp,
+ bool success);
+
+ // Protects everything below it.
+ mutable base::Lock lock_;
+
+ // Recipient of our capture activity.
+ scoped_ptr<media::VideoCaptureDevice::Client> client_;
+
+ // Makes the decision to capture a frame.
+ const scoped_ptr<VideoCaptureOracle> oracle_;
+
+ // The video capture parameters used to construct the oracle proxy.
+ media::VideoCaptureParams params_;
+
+ // Indicates if capture size has been updated after construction.
+ bool capture_size_updated_;
+
+ // The current capturing format, as a media::VideoFrame::Format.
+ media::VideoFrame::Format video_frame_format_;
+};
+
+// Keeps track of the video capture source frames and executes copying on the
+// UI BrowserThread.
+class VideoCaptureMachine {
+ public:
+ VideoCaptureMachine() : started_(false) {}
+ virtual ~VideoCaptureMachine() {}
+
+ // This should only be checked on the UI thread.
+ bool started() const { return started_; }
+
+ // Starts capturing. Returns true if succeeded.
+ // Must be run on the UI BrowserThread.
+ virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
+ const media::VideoCaptureParams& params) = 0;
+
+ // Stops capturing. Must be run on the UI BrowserThread.
+ // |callback| is invoked after the capturing has stopped.
+ virtual void Stop(const base::Closure& callback) = 0;
+
+ protected:
+ bool started_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoCaptureMachine);
+};
+
+// The "meat" of a content video capturer.
+//
+// Separating this from the "shell classes" WebContentsVideoCaptureDevice and
+// DesktopCaptureDeviceAura allows safe destruction without needing to block any
+// threads (e.g., the IO BrowserThread), as well as code sharing.
+//
+// ContentVideoCaptureDeviceCore manages a simple state machine and the pipeline
+// (see notes at top of this file). It times the start of successive captures
+// and facilitates the processing of each through the stages of the
+// pipeline.
+class CONTENT_EXPORT ContentVideoCaptureDeviceCore
+ : public base::SupportsWeakPtr<ContentVideoCaptureDeviceCore> {
+ public:
+ ContentVideoCaptureDeviceCore(
+ scoped_ptr<VideoCaptureMachine> capture_machine);
+ virtual ~ContentVideoCaptureDeviceCore();
+
+ // Asynchronous requests to change ContentVideoCaptureDeviceCore state.
+ void AllocateAndStart(const media::VideoCaptureParams& params,
+ scoped_ptr<media::VideoCaptureDevice::Client> client);
+ void StopAndDeAllocate();
+
+ private:
+ // Flag indicating current state.
+ enum State {
+ kIdle,
+ kCapturing,
+ kError
+ };
+
+ void TransitionStateTo(State next_state);
+
+ // Called on the IO thread in response to StartCaptureMachine().
+ // |success| is true if capture machine succeeded to start.
+ void CaptureStarted(bool success);
+
+ // Stops capturing and notifies client_ of an error state.
+ void Error(const std::string& reason);
+
+ // Tracks that all activity occurs on the media stream manager's thread.
+ base::ThreadChecker thread_checker_;
+
+ // Current lifecycle state.
+ State state_;
+
+ // Tracks the CaptureMachine that's doing work on our behalf on the UI thread.
+ // This value should never be dereferenced by this class, other than to
+ // create and destroy it on the UI thread.
+ scoped_ptr<VideoCaptureMachine> capture_machine_;
+
+ // Our thread-safe capture oracle which serves as the gateway to the video
+ // capture pipeline. Besides the VideoCaptureDevice itself, it is the only
+ // component of the/ system with direct access to |client_|.
+ scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentVideoCaptureDeviceCore);
+};
+
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_CAPTURE_CONTENT_VIDEO_CAPTURE_DEVICE_CORE_H_