diff options
author | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 20:03:42 +0000 |
---|---|---|
committer | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 20:03:42 +0000 |
commit | 76bf7f58d93256dfa5867b6730e446517ead2a30 (patch) | |
tree | 184a18d6d0ed95cfb13303ca6af1fb3b6ed8d44f /content/renderer/media/video_capture_impl.cc | |
parent | 9c1daf729ceb981ca1650999a15d31d8dc0d1294 (diff) | |
download | chromium_src-76bf7f58d93256dfa5867b6730e446517ead2a30.zip chromium_src-76bf7f58d93256dfa5867b6730e446517ead2a30.tar.gz chromium_src-76bf7f58d93256dfa5867b6730e446517ead2a30.tar.bz2 |
Define EncodedVideoSource and RtcCapturedEncodingVideoCapturer.
Defined the interfaces for EVS (EncodedVideoSource) and related IPC messages
between renderer and browser processes for the purpose of encoded screen capture.
Added RtcCapturedEncodingVideoCapturerFactory which implements the
libjingle::WebRtcVideoEncoderFactory class, and the corresponding
RtcCapturedEncodingVideoCapturer which implements the webrtc::VideoEncoder.
Modify MediaStreamDependencyFactory and inject RtcCapturedEncodingVideoCaptureFactory
in PeerConnectionFactory. For the time being, the factory will only be instantiated
for Chrome OS and ARM.
BUG=238515
TEST=trybot
Review URL: https://chromiumcodereview.appspot.com/16320005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209760 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/media/video_capture_impl.cc')
-rw-r--r-- | content/renderer/media/video_capture_impl.cc | 198 |
1 files changed, 197 insertions, 1 deletions
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index c6b7bf2..0dbf696 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc @@ -5,8 +5,10 @@ #include "content/renderer/media/video_capture_impl.h" #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/stl_util.h" #include "content/child/child_process.h" +#include "content/common/media/encoded_video_capture_messages.h" #include "content/common/media/video_capture_messages.h" #include "media/base/limits.h" @@ -58,7 +60,9 @@ VideoCaptureImpl::VideoCaptureImpl( video_type_(media::VideoCaptureCapability::kI420), device_info_available_(false), suspended_(false), - state_(VIDEO_CAPTURE_STATE_STOPPED) { + state_(VIDEO_CAPTURE_STATE_STOPPED), + encoded_video_source_client_(NULL), + bitstream_open_(false) { DCHECK(filter); memset(¤t_params_, 0, sizeof(current_params_)); memset(&device_info_, 0, sizeof(device_info_)); @@ -101,6 +105,83 @@ void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { base::Unretained(this), handler)); } +void VideoCaptureImpl::RequestCapabilities( + const media::EncodedVideoSource::RequestCapabilitiesCallback& callback) { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::DoRequestCapabilitiesOnCaptureThread, + base::Unretained(this), callback)); +} + +void VideoCaptureImpl::StartFetchCapabilities() { + Send(new EncodedVideoCaptureHostMsg_GetCapabilities( + device_id_, current_params_.session_id)); +} + +void VideoCaptureImpl::OpenBitstream( + media::EncodedVideoSource::Client* client, + const media::VideoEncodingParameters& params) { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::DoOpenBitstreamOnCaptureThread, + base::Unretained(this), client, params)); +} + +void VideoCaptureImpl::CloseBitstream() { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::DoCloseBitstreamOnCaptureThread, + base::Unretained(this))); +} + +void VideoCaptureImpl::ReturnBitstreamBuffer( + scoped_refptr<const media::EncodedBitstreamBuffer> buffer) { + Send(new EncodedVideoCaptureHostMsg_BitstreamBufferConsumed( + device_id_, buffer->buffer_id())); +} + +void VideoCaptureImpl::TrySetBitstreamConfig( + const media::RuntimeVideoEncodingParameters& params) { + Send(new EncodedVideoCaptureHostMsg_TryConfigureBitstream( + device_id_, params)); +} + +void VideoCaptureImpl::OnEncodingCapabilitiesAvailable( + const media::VideoEncodingCapabilities& capabilities) { + capture_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( + &VideoCaptureImpl::DoNotifyCapabilitiesAvailableOnCaptureThread, + base::Unretained(this), capabilities)); +} + +void VideoCaptureImpl::OnEncodedBitstreamOpened( + const media::VideoEncodingParameters& params, + const std::vector<base::SharedMemoryHandle>& buffers, + uint32 buffer_size) { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::DoNotifyBitstreamOpenedOnCaptureThread, + base::Unretained(this), params, buffers, buffer_size)); +} + +void VideoCaptureImpl::OnEncodedBitstreamClosed() { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::DoNotifyBitstreamClosedOnCaptureThread, + base::Unretained(this))); +} + +void VideoCaptureImpl::OnEncodingConfigChanged( + const media::RuntimeVideoEncodingParameters& params) { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind( + &VideoCaptureImpl::DoNotifyBitstreamConfigChangedOnCaptureThread, + base::Unretained(this), params)); +} + +void VideoCaptureImpl::OnEncodedBufferReady( + int buffer_id, + uint32 size, + const media::BufferEncodingMetadata& metadata) { + capture_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::DoNotifyBitstreamBufferReadyOnCaptureThread, + base::Unretained(this), buffer_id, size, metadata)); +} + void VideoCaptureImpl::FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { capture_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(&VideoCaptureImpl::DoFeedBufferOnCaptureThread, @@ -306,6 +387,9 @@ void VideoCaptureImpl::DoStateChangedOnCaptureThread(VideoCaptureState state) { switch (state) { case VIDEO_CAPTURE_STATE_STARTED: + if (!encoding_caps_callback_.is_null()) { + StartFetchCapabilities(); + } break; case VIDEO_CAPTURE_STATE_STOPPED: state_ = VIDEO_CAPTURE_STATE_STOPPED; @@ -380,6 +464,118 @@ void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) { suspended_ = suspend; } +void VideoCaptureImpl::DoRequestCapabilitiesOnCaptureThread( + const RequestCapabilitiesCallback& callback) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + DCHECK(encoding_caps_callback_.is_null()); + encoding_caps_callback_ = callback; + + // Invoke callback immediately if capabilities are already available. + if (!encoding_caps_.empty()) + base::ResetAndReturn(&encoding_caps_callback_).Run(encoding_caps_); +} + +void VideoCaptureImpl::DoOpenBitstreamOnCaptureThread( + media::EncodedVideoSource::Client* client, + const media::VideoEncodingParameters& params) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + DCHECK(!encoded_video_source_client_); + encoded_video_source_client_ = client; + Send(new EncodedVideoCaptureHostMsg_OpenBitstream( + device_id_, current_params_.session_id, params)); +} + +void VideoCaptureImpl::DoCloseBitstreamOnCaptureThread() { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + DCHECK(bitstream_open_); + + // Immediately clear EVS client pointer and release bitstream buffers if the + // client requests to close bitstream. Any further encoded capture messages + // from the browser process will be ignored. + bitstream_open_ = false; + for (size_t i = 0; i < bitstream_buffers_.size(); ++i) { + bitstream_buffers_[i]->Close(); + delete bitstream_buffers_[i]; + } + bitstream_buffers_.clear(); + encoded_video_source_client_ = NULL; + + Send(new EncodedVideoCaptureHostMsg_CloseBitstream(device_id_)); +} + +void VideoCaptureImpl::DoNotifyBitstreamOpenedOnCaptureThread( + const media::VideoEncodingParameters& params, + const std::vector<base::SharedMemoryHandle>& buffers, + uint32 buffer_size) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + DCHECK(!bitstream_open_ && bitstream_buffers_.empty()); + if (!encoded_video_source_client_) + return; + bitstream_open_ = true; + for (size_t i = 0; i < buffers.size(); ++i) { + base::SharedMemory* shm = new base::SharedMemory(buffers[i], true); + CHECK(shm->Map(buffer_size)); + bitstream_buffers_.push_back(shm); + } + encoded_video_source_client_->OnOpened(params); +} + +void VideoCaptureImpl::DoNotifyBitstreamClosedOnCaptureThread() { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + + // Ignore the BitstreamClosed message if bitstream has already been closed + // by the EVS client. + if (!bitstream_open_) + return; + + // The bitstream may still be open when we receive BitstreamClosed message + // if the request to close bitstream comes from the browser process. + bitstream_open_ = false; + for (size_t i = 0; i < bitstream_buffers_.size(); ++i) { + bitstream_buffers_[i]->Close(); + delete bitstream_buffers_[i]; + } + bitstream_buffers_.clear(); + if (encoded_video_source_client_) { + encoded_video_source_client_->OnClosed(); + encoded_video_source_client_ = NULL; + } +} + +void VideoCaptureImpl::DoNotifyBitstreamConfigChangedOnCaptureThread( + const media::RuntimeVideoEncodingParameters& params) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + if (!encoded_video_source_client_) + return; + encoded_video_source_client_->OnConfigChanged(params); +} + +void VideoCaptureImpl::DoNotifyBitstreamBufferReadyOnCaptureThread( + int buffer_id, + uint32 size, + const media::BufferEncodingMetadata& metadata) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + if (!encoded_video_source_client_) + return; + if (buffer_id >= 0 && + static_cast<size_t>(buffer_id) < bitstream_buffers_.size()) { + base::SharedMemory* shm = bitstream_buffers_.at(buffer_id); + scoped_refptr<media::EncodedBitstreamBuffer> buffer = + new media::EncodedBitstreamBuffer( + buffer_id, (uint8*)shm->memory(), size, shm->handle(), + metadata, base::Bind(&base::DoNothing)); + encoded_video_source_client_->OnBufferReady(buffer); + } +} + +void VideoCaptureImpl::DoNotifyCapabilitiesAvailableOnCaptureThread( + const media::VideoEncodingCapabilities& capabilities) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + encoding_caps_ = capabilities; + if (!encoding_caps_callback_.is_null()) + base::ResetAndReturn(&encoding_caps_callback_).Run(encoding_caps_); +} + void VideoCaptureImpl::StopDevice() { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |