diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-07 04:11:39 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-07 04:11:39 +0000 |
commit | 2362015c5ba54deae8e362ed55aa3aa2ecb3a449 (patch) | |
tree | 899c7f011676adb111c80df27c494cc28a864d17 /media/video | |
parent | ccf558a6e8f20d21f71d98d9f3e8986edcdc25d0 (diff) | |
download | chromium_src-2362015c5ba54deae8e362ed55aa3aa2ecb3a449.zip chromium_src-2362015c5ba54deae8e362ed55aa3aa2ecb3a449.tar.gz chromium_src-2362015c5ba54deae8e362ed55aa3aa2ecb3a449.tar.bz2 |
New API in VideoCaptureDevice::EventHandler which allows shared-memory output buffers to be written directly by a VideoCaptureDevice.
Implement this API in VideoCaptureController. As part of the implementation, split all the DIB-management logic out of the VideoCaptureController, and into a new class with a well-defined interface, VideoCaptureBufferPool. In essence, VideoCaptureBufferPool gets all the code that previously lived behind the DIB lock in VideoCaptureController.
VideoCaptureBufferPool must be refcounted so as to extend the lifetime of the shared memory buffers until both the VideoCaptureController and VideoCaptureDevices are done with them.
TBR=jam@chromium.org
BUG=174520
TEST=content_unittests
Review URL: https://chromiumcodereview.appspot.com/12321092
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186607 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/video')
-rw-r--r-- | media/video/capture/screen/screen_capture_device_unittest.cc | 6 | ||||
-rw-r--r-- | media/video/capture/video_capture_device.h | 57 | ||||
-rw-r--r-- | media/video/capture/video_capture_device_unittest.cc | 6 |
3 files changed, 58 insertions, 11 deletions
diff --git a/media/video/capture/screen/screen_capture_device_unittest.cc b/media/video/capture/screen/screen_capture_device_unittest.cc index b39283b..0d502f5 100644 --- a/media/video/capture/screen/screen_capture_device_unittest.cc +++ b/media/video/capture/screen/screen_capture_device_unittest.cc @@ -33,6 +33,7 @@ const int kFrameRate = 30; class MockFrameObserver : public VideoCaptureDevice::EventHandler { public: + MOCK_METHOD0(ReserveOutputBuffer, scoped_refptr<media::VideoFrame>()); MOCK_METHOD0(OnError, void()); MOCK_METHOD1(OnFrameInfo, void(const VideoCaptureCapability& info)); MOCK_METHOD6(OnIncomingCapturedFrame, void(const uint8* data, @@ -41,8 +42,9 @@ class MockFrameObserver : public VideoCaptureDevice::EventHandler { int rotation, bool flip_vert, bool flip_horiz)); - MOCK_METHOD2(OnIncomingCapturedVideoFrame, void(media::VideoFrame* frame, - base::Time timestamp)); + MOCK_METHOD2(OnIncomingCapturedVideoFrame, + void(const scoped_refptr<media::VideoFrame>& frame, + base::Time timestamp)); }; // TODO(sergeyu): Move this to a separate file where it can be reused. diff --git a/media/video/capture/video_capture_device.h b/media/video/capture/video_capture_device.h index d879223..9177302 100644 --- a/media/video/capture/video_capture_device.h +++ b/media/video/capture/video_capture_device.h @@ -6,7 +6,7 @@ // device support in Chromium. It provides the interface for OS dependent // implementations. // The class is created and functions are invoked on a thread owned by -// VideoCaptureManager. Capturing is done on other threads depended on the OS +// VideoCaptureManager. Capturing is done on other threads, depending on the OS // specific implementation. #ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ @@ -36,24 +36,66 @@ class MEDIA_EXPORT VideoCaptureDevice { class MEDIA_EXPORT EventHandler { public: + + // Reserve an output buffer into which a video frame can be captured + // directly. If all buffers are currently busy, returns NULL. + // + // The returned VideoFrames will always be allocated with a YV12 format. The + // size will match that specified by an earlier call to OnFrameInfo. It is + // the VideoCaptureDevice's responsibility to obey whatever stride and + // memory layout are indicated on the returned VideoFrame object. + // + // The output buffer stays reserved for use by the calling + // VideoCaptureDevice until either the last reference to the VideoFrame is + // released, or until the buffer is passed back to the EventHandler's + // OnIncomingCapturedFrame() method. + // + // Threading note: After VideoCaptureDevice::DeAllocate() occurs, the + // VideoCaptureDevice is not permitted to make any additional calls through + // its EventHandler. However, any VideoFrames returned from the EventHandler + // DO remain valid after DeAllocate(). The VideoCaptureDevice must still + // eventually release them, but it may do so later -- e.g., after a queued + // capture operation completes. + virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() = 0; + // Captured a new video frame as a raw buffer. The size, color format, and // layout are taken from the parameters specified by an earlier call to // OnFrameInfo(). |data| must be packed, with no padding between rows and/or // color planes. + // + // This method will try to reserve an output buffer and copy from |data| + // into the output buffer. If no output buffer is available, the frame will + // be silently dropped. virtual void OnIncomingCapturedFrame(const uint8* data, int length, base::Time timestamp, int rotation, // Clockwise. bool flip_vert, bool flip_horiz) = 0; - // Captured a new video frame, held in a VideoFrame container. |frame| must - // be allocated as RGB32, YV12 or I420, and the size must match that - // specified by an earlier call to OnFrameInfo(). - virtual void OnIncomingCapturedVideoFrame(media::VideoFrame* frame, - base::Time timestamp) = 0; + + // Captured a new video frame, held in a VideoFrame container. + // + // If |frame| was created via the ReserveOutputBuffer() mechanism, then the + // frame delivery is guaranteed (it will not be silently dropped), and + // delivery will require no additional copies in the browser process. For + // such frames, the VideoCaptureDevice's reservation on the output buffer + // ends immediately. The VideoCaptureDevice may not read or write the + // underlying memory afterwards, and it should release its references to + // |frame| as soon as possible, to allow buffer reuse. + // + // If |frame| was NOT created via ReserveOutputBuffer(), then this method + // will try to reserve an output buffer and copy from |frame| into the + // output buffer. If no output buffer is available, the frame will be + // silently dropped. |frame| must be allocated as RGB32, YV12 or I420, and + // the size must match that specified by an earlier call to OnFrameInfo(). + virtual void OnIncomingCapturedVideoFrame( + const scoped_refptr<media::VideoFrame>& frame, + base::Time timestamp) = 0; + // An error has occurred that cannot be handled and VideoCaptureDevice must // be DeAllocate()-ed. virtual void OnError() = 0; + // Called when VideoCaptureDevice::Allocate() has been called to inform of // the resulting frame size. virtual void OnFrameInfo(const VideoCaptureCapability& info) = 0; @@ -87,7 +129,8 @@ class MEDIA_EXPORT VideoCaptureDevice { // Deallocates the camera. This means other applications can use it. After // this function has been called the capture device is reset to the state it - // was when created. + // was when created. After DeAllocate() is called, the VideoCaptureDevice is + // not permitted to make any additional calls to its EventHandler. virtual void DeAllocate() = 0; // Get the name of the capture device. diff --git a/media/video/capture/video_capture_device_unittest.cc b/media/video/capture/video_capture_device_unittest.cc index 1b5745e..37821e5 100644 --- a/media/video/capture/video_capture_device_unittest.cc +++ b/media/video/capture/video_capture_device_unittest.cc @@ -58,6 +58,7 @@ namespace media { class MockFrameObserver : public media::VideoCaptureDevice::EventHandler { public: + MOCK_METHOD0(ReserveOutputBuffer, scoped_refptr<media::VideoFrame>()); MOCK_METHOD0(OnErr, void()); MOCK_METHOD4(OnFrameInfo, void(int width, int height, int frame_rate, VideoCaptureCapability::Format format)); @@ -84,8 +85,9 @@ class MockFrameObserver : public media::VideoCaptureDevice::EventHandler { wait_event_->Signal(); } - virtual void OnIncomingCapturedVideoFrame(media::VideoFrame* frame, - base::Time timestamp) OVERRIDE { + virtual void OnIncomingCapturedVideoFrame( + const scoped_refptr<media::VideoFrame>& frame, + base::Time timestamp) OVERRIDE { wait_event_->Signal(); } |