summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/login/chrome_restart_request.cc1
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc3
-rw-r--r--content/common/content_message_generator.h1
-rw-r--r--content/common/media/encoded_video_capture_messages.h128
-rw-r--r--content/content_common.gypi1
-rw-r--r--content/content_renderer.gypi4
-rw-r--r--content/public/common/content_switches.cc5
-rw-r--r--content/public/common/content_switches.h3
-rw-r--r--content/renderer/media/media_stream_dependency_factory.cc18
-rw-r--r--content/renderer/media/rtc_encoding_video_capturer.cc228
-rw-r--r--content/renderer/media/rtc_encoding_video_capturer.h56
-rw-r--r--content/renderer/media/rtc_encoding_video_capturer_factory.cc100
-rw-r--r--content/renderer/media/rtc_encoding_video_capturer_factory.h61
-rw-r--r--content/renderer/media/video_capture_impl.cc198
-rw-r--r--content/renderer/media/video_capture_impl.h64
-rw-r--r--content/renderer/media/video_capture_impl_manager.cc6
-rw-r--r--content/renderer/media/video_capture_impl_manager.h14
-rw-r--r--content/renderer/media/video_capture_impl_unittest.cc25
-rw-r--r--content/renderer/media/video_capture_message_filter.cc97
-rw-r--r--content/renderer/media/video_capture_message_filter.h50
-rw-r--r--content/renderer/media/video_capture_message_filter_unittest.cc15
-rw-r--r--ipc/ipc_message_start.h3
-rw-r--r--media/base/encoded_bitstream_buffer.cc50
-rw-r--r--media/base/encoded_bitstream_buffer.h52
-rw-r--r--media/media.gyp4
-rw-r--r--media/video/encoded_video_source.h76
-rw-r--r--media/video/video_encode_types.h51
27 files changed, 1295 insertions, 19 deletions
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 8809966..5096919 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -90,6 +90,7 @@ std::string DeriveCommandLine(const GURL& start_url,
::switches::kEnableBeginFrameScheduling,
::switches::kEnableBrowserInputController,
::switches::kEnableCompositingForFixedPosition,
+ ::switches::kEnableEncodedScreenCapture,
::switches::kEnableEncryptedMedia,
::switches::kEnableGestureTapHighlight,
::switches::kDisableGestureTapHighlight,
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 03f28d7..4a7c8b8 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -954,6 +954,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDefaultTileHeight,
switches::kMaxUntiledLayerWidth,
switches::kMaxUntiledLayerHeight,
+#if defined(OS_CHROMEOS)
+ switches::kEnableEncodedScreenCapture,
+#endif
switches::kEnableViewport,
switches::kEnableInbandTextTracks,
switches::kEnableOpusPlayback,
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index 174a63b..e7f0786 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -31,6 +31,7 @@
#include "content/common/input_messages.h"
#include "content/common/java_bridge_messages.h"
#include "content/common/media/audio_messages.h"
+#include "content/common/media/encoded_video_capture_messages.h"
#include "content/common/media/midi_messages.h"
#if defined(OS_ANDROID)
#include "content/common/media/media_player_messages_android.h"
diff --git a/content/common/media/encoded_video_capture_messages.h b/content/common/media/encoded_video_capture_messages.h
new file mode 100644
index 0000000..8de6fb9
--- /dev/null
+++ b/content/common/media/encoded_video_capture_messages.h
@@ -0,0 +1,128 @@
+// Copyright 2013 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.
+
+#include "base/memory/shared_memory.h"
+#include "ipc/ipc_message_macros.h"
+#include "media/video/capture/video_capture_types.h"
+#include "media/video/video_encode_types.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+#define IPC_MESSAGE_START EncodedVideoCaptureMsgStart
+
+#if !defined(OS_ANDROID)
+IPC_ENUM_TRAITS(media::VideoCodec)
+#endif // !defined(OS_ANDROID)
+
+IPC_STRUCT_TRAITS_BEGIN(media::VideoEncodingConfig)
+ IPC_STRUCT_TRAITS_MEMBER(codec_type)
+ IPC_STRUCT_TRAITS_MEMBER(codec_name)
+ IPC_STRUCT_TRAITS_MEMBER(max_resolution)
+ IPC_STRUCT_TRAITS_MEMBER(max_frames_per_second)
+ IPC_STRUCT_TRAITS_MEMBER(max_bitrate)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(media::RuntimeVideoEncodingParameters)
+ IPC_STRUCT_TRAITS_MEMBER(target_bitrate)
+ IPC_STRUCT_TRAITS_MEMBER(max_bitrate)
+ IPC_STRUCT_TRAITS_MEMBER(frames_per_second)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(media::VideoEncodingParameters)
+ IPC_STRUCT_TRAITS_MEMBER(codec_name)
+ IPC_STRUCT_TRAITS_MEMBER(resolution)
+ IPC_STRUCT_TRAITS_MEMBER(runtime_params)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(media::BufferEncodingMetadata)
+ IPC_STRUCT_TRAITS_MEMBER(timestamp)
+ IPC_STRUCT_TRAITS_MEMBER(key_frame)
+IPC_STRUCT_TRAITS_END()
+
+//------------------------------------------------------------------------------
+// Renderer Source Messages
+// These are messages from the renderer to the browser process.
+
+// Queries the encoding capabilities for the device. A successful request
+// results in EncoderVideoSourceMessage_CapabilitiesAvailable message.
+IPC_MESSAGE_CONTROL2(EncodedVideoCaptureHostMsg_GetCapabilities,
+ int /* device_id */,
+ media::VideoCaptureSessionId /* session_id */)
+
+// Message from renderer to browser process to create a bitstream with specific
+// parameters. A successful request results in beginning of streaming and
+// EncoderVideoCaptureMsg_BitstreamCreated message to renderer. A failed request
+// triggers EncodedVideoCaptureMsg_BitstreamDestroyed message. |session_id| is
+// the capture session id returned by the MediaStreamManager. The renderer is
+// responsible for generating unique |device_id| within its context that will be
+// used to identify bitstreams in IPC.
+IPC_MESSAGE_CONTROL3(EncodedVideoCaptureHostMsg_OpenBitstream,
+ int /* device_id */,
+ media::VideoCaptureSessionId /* session_id */,
+ media::VideoEncodingParameters /* params */)
+
+// Stops streaming a bitstream. When browser has finalized the bitstream it will
+// trigger EncodedVideoCaptureMsg_BitstreamClosed message back to renderer.
+// Renderer must be prepared to receive EncodedVideoCaptureMsg_BitstreamReady
+// messages until it receives EncodedVideoCaptureMsg_BitstreamClosed message.
+IPC_MESSAGE_CONTROL1(EncodedVideoCaptureHostMsg_CloseBitstream,
+ int /* device_id */)
+
+// Sets a stream's bitstream configuration. Will always result in
+// EncodedVideoCaptureMsg_BitstreamConfigChanged message containing
+// currently active parameters, regardless of whether this call succeeded or
+// not.
+IPC_MESSAGE_CONTROL2(EncodedVideoCaptureHostMsg_TryConfigureBitstream,
+ int /* device_id */,
+ media::RuntimeVideoEncodingParameters /* params */)
+
+// Notifies that the data within a buffer has been processed and it can be
+// reused to encode upcoming bitstream.
+IPC_MESSAGE_CONTROL2(EncodedVideoCaptureHostMsg_BitstreamBufferConsumed,
+ int /* device_id */,
+ int /* buffer_id */)
+
+//------------------------------------------------------------------------------
+// Renderer Messages
+// These are messages from the browser to the renderer process.
+
+// Reports the encoding capabilities of the device.
+IPC_MESSAGE_CONTROL2(EncodedVideoCaptureMsg_CapabilitiesAvailable,
+ int /* device_id */,
+ media::VideoEncodingCapabilities /* capabilities */)
+
+// Acknowledges a request to open an encoded video bitstream. When this message
+// occurs, bitstream can be considered to be streaming, and renderer should be
+// ready to start accepting EncodedVideoCaptureMsg_BitstreamReady messages and
+// buffers contained within them. Shared memory buffers used to deliver the
+// bitstream are assigned with buffer IDs as specified by the buffers parameter.
+// All buffers have the same size as indicated by |buffer_size|.
+IPC_MESSAGE_CONTROL4(EncodedVideoCaptureMsg_BitstreamOpened,
+ int /* device_id */,
+ media::VideoEncodingParameters /* params */,
+ std::vector<base::SharedMemoryHandle> /* buffers */,
+ uint32 /* buffer_size */)
+
+// Acknowledges a request to close an encoded video bitstream.
+IPC_MESSAGE_CONTROL1(EncodedVideoCaptureMsg_BitstreamClosed,
+ int /* device_id */)
+
+// Informs the clients of the current encoding parameters, regardless of whether
+// the previous request to change them has been successful or not. It is usually
+// called in response to EncodedVideoCaptureHostMsg_TryConfigureBitstream
+// at runtime, but can occur also as a result of config change initiated by
+// encoder or other clients in the system, e.g. if there are multiple clients
+// and bitstream config change is requested from one client, all clients should
+// be prepared to handle the configuration change.
+IPC_MESSAGE_CONTROL2(EncodedVideoCaptureMsg_BitstreamConfigChanged,
+ int /* device_id */,
+ media::RuntimeVideoEncodingParameters /* current_params */)
+
+// Indicates that a bitstream buffer is available for the stream. The value of
+// |size| indicates the amount of valid bitstream data (in bytes).
+IPC_MESSAGE_CONTROL4(EncodedVideoCaptureMsg_BitstreamReady,
+ int /* device_id */,
+ int /* buffer_id */,
+ uint32 /* size */,
+ media::BufferEncodingMetadata /* metadata */)
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 85762d1..c029c29 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -259,6 +259,7 @@
'common/mac/font_loader.h',
'common/mac/font_loader.mm',
'common/media/audio_messages.h',
+ 'common/media/encoded_video_capture_messages.h',
'common/media/media_param_traits.cc',
'common/media/media_param_traits.h',
'common/media/media_player_messages_android.h',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 0c70df5..4cd7c39 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -447,6 +447,10 @@
'renderer/media/rtc_data_channel_handler.h',
'renderer/media/rtc_dtmf_sender_handler.cc',
'renderer/media/rtc_dtmf_sender_handler.h',
+ 'renderer/media/rtc_encoding_video_capturer.cc',
+ 'renderer/media/rtc_encoding_video_capturer.h',
+ 'renderer/media/rtc_encoding_video_capturer_factory.cc',
+ 'renderer/media/rtc_encoding_video_capturer_factory.h',
'renderer/media/rtc_media_constraints.cc',
'renderer/media/rtc_media_constraints.h',
'renderer/media/rtc_peer_connection_handler.cc',
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 6e1f7b9..aaad345 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -318,6 +318,11 @@ const char kEnableDeviceMotion[] = "enable-device-motion";
// Enables restarting interrupted downloads.
const char kEnableDownloadResumption[] = "enable-download-resumption";
+#if defined(OS_CHROMEOS)
+// Enables hardware-encoded screen capture.
+const char kEnableEncodedScreenCapture[] = "enable-encoded-screen-capture";
+#endif
+
// Enables WebKit features that are in development.
const char kEnableExperimentalWebKitFeatures[] =
"enable-experimental-webkit-features";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 2edb22e..7218b239 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -35,6 +35,9 @@ extern const char kDisableBackingStoreLimit[];
CONTENT_EXPORT extern const char kDisableDatabases[];
extern const char kDisableDesktopNotifications[];
CONTENT_EXPORT extern const char kDisableDeviceOrientation[];
+#if defined(OS_CHROMEOS)
+CONTENT_EXPORT extern const char kEnableEncodedScreenCapture[];
+#endif
#if defined(OS_ANDROID)
CONTENT_EXPORT extern const char kEnableExperimentalWebGL[];
#else
diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc
index e334a04..8a6558e 100644
--- a/content/renderer/media/media_stream_dependency_factory.cc
+++ b/content/renderer/media/media_stream_dependency_factory.cc
@@ -11,6 +11,7 @@
#include "base/synchronization/waitable_event.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/media/media_stream_source_extra_data.h"
+#include "content/renderer/media/rtc_encoding_video_capturer_factory.h"
#include "content/renderer/media/rtc_media_constraints.h"
#include "content/renderer/media/rtc_peer_connection_handler.h"
#include "content/renderer/media/rtc_video_capturer.h"
@@ -487,17 +488,32 @@ bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() {
audio_device_ = new WebRtcAudioDeviceImpl();
cricket::WebRtcVideoDecoderFactory* decoder_factory = NULL;
+ cricket::WebRtcVideoEncoderFactory* encoder_factory = NULL;
+
#if defined(GOOGLE_TV)
// PeerConnectionFactory will hold the ownership of this
// VideoDecoderFactory.
decoder_factory = decoder_factory_tv_ = new RTCVideoDecoderFactoryTv;
#endif
+#if defined(OS_CHROMEOS)
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kEnableEncodedScreenCapture)) {
+ // PeerConnectionFactory owns the encoder factory. Pass a weak pointer of
+ // encoder factory to |vc_manager_| because the manager outlives it.
+ RtcEncodingVideoCapturerFactory* rtc_encoding_capturer_factory =
+ new RtcEncodingVideoCapturerFactory();
+ encoder_factory = rtc_encoding_capturer_factory;
+ vc_manager_->set_encoding_capturer_factory(
+ rtc_encoding_capturer_factory->AsWeakPtr());
+ }
+#endif
+
scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory(
webrtc::CreatePeerConnectionFactory(worker_thread_,
signaling_thread_,
audio_device_.get(),
- NULL,
+ encoder_factory,
decoder_factory));
if (factory.get())
pc_factory_ = factory;
diff --git a/content/renderer/media/rtc_encoding_video_capturer.cc b/content/renderer/media/rtc_encoding_video_capturer.cc
new file mode 100644
index 0000000..87367ef
--- /dev/null
+++ b/content/renderer/media/rtc_encoding_video_capturer.cc
@@ -0,0 +1,228 @@
+// Copyright 2013 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.
+
+#include "content/renderer/media/rtc_encoding_video_capturer.h"
+
+#include "base/logging.h"
+#include "media/base/encoded_bitstream_buffer.h"
+
+namespace content {
+
+// Client of EncodedVideoSource. This object is created and owned by the
+// RtcEncodingVideoCapturer.
+class RtcEncodingVideoCapturer::EncodedVideoSourceClient :
+ public media::EncodedVideoSource::Client {
+ public:
+ EncodedVideoSourceClient(
+ media::EncodedVideoSource* encoded_video_source,
+ media::VideoEncodingParameters params,
+ webrtc::VideoCodecType rtc_codec_type);
+ virtual ~EncodedVideoSourceClient();
+
+ // media::EncodedVideoSource::Client implementation.
+ virtual void OnOpened(
+ const media::VideoEncodingParameters& params) OVERRIDE;
+ virtual void OnClosed() OVERRIDE;
+ virtual void OnBufferReady(
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) OVERRIDE;
+ virtual void OnConfigChanged(
+ const media::RuntimeVideoEncodingParameters& params) OVERRIDE;
+
+ // Getters and setters for bitstream properties.
+ media::RuntimeVideoEncodingParameters runtime_params() const;
+ void set_round_trip_time(base::TimeDelta round_trip_time);
+ void set_callback(webrtc::EncodedImageCallback* callback);
+
+ private:
+ // Convert buffer to webrtc types and invoke encode complete callback.
+ void ReportEncodedFrame(
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer);
+
+ media::VideoEncodingParameters params_;
+ webrtc::VideoCodecType rtc_codec_type_;
+ bool finished_;
+
+ base::Time time_base_;
+ base::TimeDelta round_trip_time_;
+ media::EncodedVideoSource* encoded_video_source_;
+ webrtc::EncodedImageCallback* callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(EncodedVideoSourceClient);
+};
+
+RtcEncodingVideoCapturer::EncodedVideoSourceClient::EncodedVideoSourceClient(
+ media::EncodedVideoSource* encoded_video_source,
+ media::VideoEncodingParameters params,
+ webrtc::VideoCodecType rtc_codec_type)
+ : params_(params),
+ rtc_codec_type_(rtc_codec_type),
+ finished_(false),
+ encoded_video_source_(encoded_video_source),
+ callback_(NULL) {
+ DCHECK(encoded_video_source_);
+ encoded_video_source_->OpenBitstream(this, params);
+}
+
+RtcEncodingVideoCapturer::EncodedVideoSourceClient::
+ ~EncodedVideoSourceClient() {
+ if (!finished_)
+ encoded_video_source_->CloseBitstream();
+}
+
+media::RuntimeVideoEncodingParameters
+ RtcEncodingVideoCapturer::EncodedVideoSourceClient::runtime_params() const {
+ return params_.runtime_params;
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::set_round_trip_time(
+ base::TimeDelta round_trip_time) {
+ round_trip_time_ = round_trip_time;
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::set_callback(
+ webrtc::EncodedImageCallback* callback) {
+ DCHECK(!callback_);
+ callback_ = callback;
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnOpened(
+ const media::VideoEncodingParameters& params) {
+ params_ = params;
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnClosed() {
+ finished_ = true;
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnBufferReady(
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) {
+ DCHECK(!finished_ && buffer);
+
+ // First buffer constitutes the origin of the time for this bitstream context.
+ if (time_base_.is_null())
+ time_base_ = buffer->metadata().timestamp;
+
+ ReportEncodedFrame(buffer);
+ encoded_video_source_->ReturnBitstreamBuffer(buffer);
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnConfigChanged(
+ const media::RuntimeVideoEncodingParameters& params) {
+ params_.runtime_params = params;
+}
+
+void RtcEncodingVideoCapturer::EncodedVideoSourceClient::ReportEncodedFrame(
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) {
+ if (!callback_)
+ return;
+
+ webrtc::EncodedImage image;
+ webrtc::CodecSpecificInfo codecInfo;
+ webrtc::RTPFragmentationHeader fragHeader;
+
+ // TODO(hshi): remove this const_cast. Unfortunately webrtc::EncodedImage
+ // defines member |_buffer| of type uint8_t* even though webrtc never modifies
+ // the buffer contents.
+ image._buffer = const_cast<uint8_t*>(buffer->buffer());
+ image._length = buffer->size();
+ image._size = image._length;
+
+ const media::BufferEncodingMetadata& metadata = buffer->metadata();
+ base::TimeDelta capture_time = metadata.timestamp - time_base_;
+ image.capture_time_ms_ = capture_time.InMilliseconds();
+ // Convert capture time to 90 kHz RTP timestamp.
+ image._timeStamp = (capture_time * 90000).InSeconds();
+ if (metadata.key_frame) {
+ image._frameType = webrtc::kKeyFrame;
+ } else {
+ image._frameType = webrtc::kDeltaFrame;
+ }
+ image._completeFrame = true;
+ image._encodedWidth = params_.resolution.width();
+ image._encodedHeight = params_.resolution.height();
+
+ // TODO(hshi): generate codec specific info for VP8.
+ codecInfo.codecType = rtc_codec_type_;
+
+ // Generate header containing a single fragmentation.
+ fragHeader.VerifyAndAllocateFragmentationHeader(1);
+ fragHeader.fragmentationOffset[0] = 0;
+ fragHeader.fragmentationLength[0] = buffer->size();
+ fragHeader.fragmentationPlType[0] = 0;
+ fragHeader.fragmentationTimeDiff[0] = 0;
+
+ callback_->Encoded(image, &codecInfo, &fragHeader);
+}
+
+// RtcEncodingVideoCapturer
+RtcEncodingVideoCapturer::RtcEncodingVideoCapturer(
+ media::EncodedVideoSource* encoded_video_source,
+ webrtc::VideoCodecType codec_type)
+ : encoded_video_source_(encoded_video_source),
+ rtc_codec_type_(codec_type) {
+}
+
+RtcEncodingVideoCapturer::~RtcEncodingVideoCapturer() {
+}
+
+int32_t RtcEncodingVideoCapturer::InitEncode(
+ const webrtc::VideoCodec* codecSettings,
+ int32_t numberOfCores,
+ uint32_t maxPayloadSize) {
+ DCHECK(!encoded_video_source_client_);
+ if (codecSettings->codecType != rtc_codec_type_)
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+
+ // Convert |codecSettings| to |params|.
+ media::VideoEncodingParameters params;
+ params.codec_name = codecSettings->plName;
+ params.resolution = gfx::Size(codecSettings->width, codecSettings->height);
+ params.runtime_params.target_bitrate = codecSettings->startBitrate;
+ params.runtime_params.max_bitrate = codecSettings->maxBitrate;
+ params.runtime_params.frames_per_second = codecSettings->maxFramerate;
+ encoded_video_source_client_.reset(new EncodedVideoSourceClient(
+ encoded_video_source_, params, rtc_codec_type_));
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RtcEncodingVideoCapturer::Encode(
+ const webrtc::I420VideoFrame& /* inputImage */,
+ const webrtc::CodecSpecificInfo* codecSpecificInfo,
+ const std::vector<webrtc::VideoFrameType>* frame_types) {
+ // TODO(hshi): request specific frame type.
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RtcEncodingVideoCapturer::RegisterEncodeCompleteCallback(
+ webrtc::EncodedImageCallback* callback) {
+ DCHECK(encoded_video_source_client_);
+ encoded_video_source_client_->set_callback(callback);
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RtcEncodingVideoCapturer::Release() {
+ DCHECK(encoded_video_source_client_);
+ encoded_video_source_client_.reset(NULL);
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RtcEncodingVideoCapturer::SetChannelParameters(
+ uint32_t /* packetLoss */,
+ int rtt_in_ms) {
+ if (!encoded_video_source_client_)
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ encoded_video_source_client_->set_round_trip_time(
+ base::TimeDelta::FromMilliseconds(rtt_in_ms));
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int32_t RtcEncodingVideoCapturer::SetRates(uint32_t newBitRate,
+ uint32_t frameRate) {
+ if (!encoded_video_source_client_)
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ // TODO(hshi): wire up runtime rate control.
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+} // namespace content
diff --git a/content/renderer/media/rtc_encoding_video_capturer.h b/content/renderer/media/rtc_encoding_video_capturer.h
new file mode 100644
index 0000000..77f9626
--- /dev/null
+++ b/content/renderer/media/rtc_encoding_video_capturer.h
@@ -0,0 +1,56 @@
+// Copyright 2013 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_RENDERER_MEDIA_RTC_ENCODING_VIDEO_CAPTURER_H_
+#define CONTENT_RENDERER_MEDIA_RTC_ENCODING_VIDEO_CAPTURER_H_
+
+#include "base/memory/ref_counted.h"
+#include "media/video/encoded_video_source.h"
+#include "media/video/video_encode_types.h"
+#include "third_party/libjingle/source/talk/media/webrtc/webrtcvie.h"
+
+namespace content {
+
+// Class to represent an encoding capable video capture interface for the
+// WebRTC component. This class expects to be registered as an encoder with
+// an internal source to the WebRTC stack and will not be able to function as
+// an encoder for uncompressed video frames.
+class RtcEncodingVideoCapturer : public webrtc::VideoEncoder {
+ public:
+ RtcEncodingVideoCapturer(media::EncodedVideoSource* encoded_video_source,
+ webrtc::VideoCodecType codec_type);
+ virtual ~RtcEncodingVideoCapturer();
+
+ // webrtc::VideoEncoder implementation.
+ virtual int32_t InitEncode(const webrtc::VideoCodec* codecSettings,
+ int32_t numberOfCores,
+ uint32_t maxPayloadSize) OVERRIDE;
+ virtual int32_t Encode(
+ const webrtc::I420VideoFrame& /* inputImage */,
+ const webrtc::CodecSpecificInfo* codecSpecificInfo,
+ const std::vector<webrtc::VideoFrameType>* frame_types) OVERRIDE;
+ virtual int32_t RegisterEncodeCompleteCallback(
+ webrtc::EncodedImageCallback* callback) OVERRIDE;
+ virtual int32_t Release() OVERRIDE;
+ virtual int32_t SetChannelParameters(uint32_t /* packetLoss */,
+ int rtt_in_ms) OVERRIDE;
+ virtual int32_t SetRates(uint32_t newBitRate,
+ uint32_t frameRate) OVERRIDE;
+ private:
+ // Forward declaration for private implementation to represent the
+ // encoded video source client;
+ class EncodedVideoSourceClient;
+ scoped_ptr<EncodedVideoSourceClient> encoded_video_source_client_;
+
+ // Pointer to the underlying EncodedVideoSource object. It is guaranteed to
+ // outlive the RtcEncodingVideoCapturer.
+ media::EncodedVideoSource* encoded_video_source_;
+ webrtc::VideoCodecType rtc_codec_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(RtcEncodingVideoCapturer);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_RTC_ENCODING_VIDEO_CAPTURER_H_
diff --git a/content/renderer/media/rtc_encoding_video_capturer_factory.cc b/content/renderer/media/rtc_encoding_video_capturer_factory.cc
new file mode 100644
index 0000000..a699aed
--- /dev/null
+++ b/content/renderer/media/rtc_encoding_video_capturer_factory.cc
@@ -0,0 +1,100 @@
+// Copyright 2013 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.
+
+#include "content/renderer/media/rtc_encoding_video_capturer_factory.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "content/renderer/media/rtc_encoding_video_capturer.h"
+#include "media/base/encoded_bitstream_buffer.h"
+
+namespace content {
+
+RtcEncodingVideoCapturerFactory::RtcEncodingVideoCapturerFactory()
+ : encoded_video_source_(NULL) {
+}
+
+RtcEncodingVideoCapturerFactory::~RtcEncodingVideoCapturerFactory() {
+ DCHECK(encoder_set_.empty());
+}
+
+void RtcEncodingVideoCapturerFactory::OnEncodedVideoSourceAdded(
+ media::EncodedVideoSource* source) {
+ // TODO(hshi): support multiple encoded video sources.
+ // For now we only support one instance of encoded video source at a time.
+ DCHECK(!encoded_video_source_);
+ encoded_video_source_ = source;
+ source->RequestCapabilities(base::Bind(
+ &RtcEncodingVideoCapturerFactory::OnCapabilitiesAvailable,
+ AsWeakPtr()));
+}
+
+void RtcEncodingVideoCapturerFactory::OnEncodedVideoSourceRemoved(
+ media::EncodedVideoSource* source) {
+ encoded_video_source_ = NULL;
+}
+
+webrtc::VideoEncoder* RtcEncodingVideoCapturerFactory::CreateVideoEncoder(
+ webrtc::VideoCodecType type) {
+ for (size_t i = 0; i < codecs_.size(); ++i) {
+ if (codecs_[i].type == type) {
+ RtcEncodingVideoCapturer* capturer =
+ new RtcEncodingVideoCapturer(encoded_video_source_, type);
+ encoder_set_.insert(capturer);
+ return capturer;
+ }
+ }
+ return NULL;
+}
+
+void RtcEncodingVideoCapturerFactory::DestroyVideoEncoder(
+ webrtc::VideoEncoder* encoder) {
+ EncoderSet::iterator it = encoder_set_.find(encoder);
+ if (it != encoder_set_.end()) {
+ delete encoder;
+ encoder_set_.erase(it);
+ }
+}
+
+void RtcEncodingVideoCapturerFactory::AddObserver(
+ WebRtcVideoEncoderFactory::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void RtcEncodingVideoCapturerFactory::RemoveObserver(
+ WebRtcVideoEncoderFactory::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>&
+RtcEncodingVideoCapturerFactory::codecs() const {
+ return codecs_;
+}
+
+void RtcEncodingVideoCapturerFactory::OnCapabilitiesAvailable(
+ const media::VideoEncodingCapabilities& caps) {
+ codecs_.clear();
+
+ for (size_t i = 0; i < caps.size(); ++i) {
+ webrtc::VideoCodecType webrtc_codec_type = webrtc::kVideoCodecGeneric;
+ switch (caps[i].codec_type) {
+ case media::kCodecVP8:
+ webrtc_codec_type = webrtc::kVideoCodecVP8;
+ break;
+ default:
+ break;
+ }
+ codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec(
+ webrtc_codec_type,
+ caps[i].codec_name,
+ caps[i].max_resolution.width(),
+ caps[i].max_resolution.height(),
+ caps[i].max_frames_per_second));
+ }
+
+ FOR_EACH_OBSERVER(WebRtcVideoEncoderFactory::Observer, observers_,
+ OnCodecsAvailable());
+}
+
+} // namespace content
diff --git a/content/renderer/media/rtc_encoding_video_capturer_factory.h b/content/renderer/media/rtc_encoding_video_capturer_factory.h
new file mode 100644
index 0000000..1fdf4f5
--- /dev/null
+++ b/content/renderer/media/rtc_encoding_video_capturer_factory.h
@@ -0,0 +1,61 @@
+// Copyright 2013 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_RENDERER_MEDIA_RTC_ENCODING_VIDEO_CAPTURER_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_RTC_ENCODING_VIDEO_CAPTURER_FACTORY_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "media/video/encoded_video_source.h"
+#include "media/video/video_encode_types.h"
+#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoencoderfactory.h"
+
+namespace content {
+
+class RtcEncodingVideoCapturer;
+
+class RtcEncodingVideoCapturerFactory :
+ public cricket::WebRtcVideoEncoderFactory,
+ public base::SupportsWeakPtr<RtcEncodingVideoCapturerFactory> {
+ public:
+ RtcEncodingVideoCapturerFactory();
+
+ // WebRtcVideoEncoderFactory interface.
+ virtual webrtc::VideoEncoder* CreateVideoEncoder(
+ webrtc::VideoCodecType type) OVERRIDE;
+ virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) OVERRIDE;
+
+ virtual const std::vector<VideoCodec>& codecs() const OVERRIDE;
+
+ virtual void AddObserver(
+ WebRtcVideoEncoderFactory::Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(
+ WebRtcVideoEncoderFactory::Observer* observer) OVERRIDE;
+
+ // Callback for RequestCapabilities().
+ void OnCapabilitiesAvailable(const media::VideoEncodingCapabilities& caps);
+
+ // Invoked when an EncodedVideoSource is added/removed.
+ void OnEncodedVideoSourceAdded(media::EncodedVideoSource* source);
+ void OnEncodedVideoSourceRemoved(media::EncodedVideoSource* source);
+
+private:
+ virtual ~RtcEncodingVideoCapturerFactory();
+
+ // Set of registered encoding capable video capturers.
+ typedef std::set<webrtc::VideoEncoder*> EncoderSet;
+
+ media::EncodedVideoSource* encoded_video_source_;
+ std::vector<VideoCodec> codecs_;
+
+ EncoderSet encoder_set_;
+
+ ObserverList<WebRtcVideoEncoderFactory::Observer, true> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(RtcEncodingVideoCapturerFactory);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_RTC_ENCODING_VIDEO_CAPTURER_FACTORY_H_
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(&current_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());
diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h
index a7af55b..779aece 100644
--- a/content/renderer/media/video_capture_impl.h
+++ b/content/renderer/media/video_capture_impl.h
@@ -38,6 +38,7 @@
#include "content/renderer/media/video_capture_message_filter.h"
#include "media/video/capture/video_capture.h"
#include "media/video/capture/video_capture_types.h"
+#include "media/video/encoded_video_source.h"
namespace base {
class MessageLoopProxy;
@@ -46,7 +47,9 @@ class MessageLoopProxy;
namespace content {
class CONTENT_EXPORT VideoCaptureImpl
- : public media::VideoCapture, public VideoCaptureMessageFilter::Delegate {
+ : public media::VideoCapture,
+ public VideoCaptureMessageFilter::Delegate,
+ public media::EncodedVideoSource {
public:
// media::VideoCapture interface.
virtual void StartCapture(
@@ -67,6 +70,31 @@ class CONTENT_EXPORT VideoCaptureImpl
virtual void OnDeviceInfoReceived(
const media::VideoCaptureParams& device_info) OVERRIDE;
virtual void OnDelegateAdded(int32 device_id) OVERRIDE;
+ virtual void OnEncodingCapabilitiesAvailable(
+ const media::VideoEncodingCapabilities& capabilities) OVERRIDE;
+ virtual void OnEncodedBitstreamOpened(
+ const media::VideoEncodingParameters& params,
+ const std::vector<base::SharedMemoryHandle>& buffers,
+ uint32 buffer_size) OVERRIDE;
+ virtual void OnEncodedBitstreamClosed() OVERRIDE;
+ virtual void OnEncodingConfigChanged(
+ const media::RuntimeVideoEncodingParameters& params) OVERRIDE;
+ virtual void OnEncodedBufferReady(
+ int buffer_id,
+ uint32 size,
+ const media::BufferEncodingMetadata& metadata) OVERRIDE;
+
+ // media::EncodedVideoSource interface.
+ virtual void RequestCapabilities(
+ const RequestCapabilitiesCallback& callback) OVERRIDE;
+ virtual void OpenBitstream(
+ media::EncodedVideoSource::Client* client,
+ const media::VideoEncodingParameters& params) OVERRIDE;
+ virtual void CloseBitstream() OVERRIDE;
+ virtual void ReturnBitstreamBuffer(
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) OVERRIDE;
+ virtual void TrySetBitstreamConfig(
+ const media::RuntimeVideoEncodingParameters& params) OVERRIDE;
// Stop/resume delivering video frames to clients, based on flag |suspend|.
virtual void SuspendCapture(bool suspend);
@@ -101,6 +129,26 @@ class CONTENT_EXPORT VideoCaptureImpl
void DoSuspendCaptureOnCaptureThread(bool suspend);
+ void StartFetchCapabilities();
+ void DoRequestCapabilitiesOnCaptureThread(
+ const RequestCapabilitiesCallback& callback);
+ void DoOpenBitstreamOnCaptureThread(
+ media::EncodedVideoSource::Client* client,
+ const media::VideoEncodingParameters& params);
+ void DoCloseBitstreamOnCaptureThread();
+ void DoNotifyBitstreamOpenedOnCaptureThread(
+ const media::VideoEncodingParameters& params,
+ const std::vector<base::SharedMemoryHandle>& buffers,
+ uint32 buffer_size);
+ void DoNotifyBitstreamClosedOnCaptureThread();
+ void DoNotifyBitstreamConfigChangedOnCaptureThread(
+ const media::RuntimeVideoEncodingParameters& params);
+ void DoNotifyBitstreamBufferReadyOnCaptureThread(
+ int buffer_id, uint32 size,
+ const media::BufferEncodingMetadata& metadata);
+ void DoNotifyCapabilitiesAvailableOnCaptureThread(
+ const media::VideoEncodingCapabilities& capabilities);
+
void Init();
void DeInit(base::Closure task);
void DoDeInitOnCaptureThread(base::Closure task);
@@ -143,6 +191,20 @@ class CONTENT_EXPORT VideoCaptureImpl
bool suspended_;
VideoCaptureState state_;
+ // Video encoding capabilities as reported by the device.
+ media::VideoEncodingCapabilities encoding_caps_;
+ // Callback for RequestCapabilities().
+ RequestCapabilitiesCallback encoding_caps_callback_;
+ // Pointer to the EVS client.
+ media::EncodedVideoSource::Client* encoded_video_source_client_;
+ // Bitstream buffers returned by the video capture device. Unowned.
+ std::vector<base::SharedMemory*> bitstream_buffers_;
+ // |bitstream_open_| is set to true when renderer receives BitstreamOpened
+ // message acknowledging an OpenBitstream request, and is set to false when
+ // the EVS client requests to close bitstream, or when renderer receives
+ // BitstreamClosed message from the browser procses.
+ bool bitstream_open_;
+
DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl);
};
diff --git a/content/renderer/media/video_capture_impl_manager.cc b/content/renderer/media/video_capture_impl_manager.cc
index 672fbd4..cd49543 100644
--- a/content/renderer/media/video_capture_impl_manager.cc
+++ b/content/renderer/media/video_capture_impl_manager.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/stl_util.h"
+#include "content/renderer/media/rtc_encoding_video_capturer_factory.h"
#include "content/renderer/media/video_capture_impl.h"
#include "content/renderer/media/video_capture_message_filter.h"
@@ -30,6 +31,8 @@ media::VideoCapture* VideoCaptureImplManager::AddDevice(
new VideoCaptureImpl(id, message_loop_proxy_.get(), filter_.get());
devices_[id] = new Device(vc, handler);
vc->Init();
+ if (encoding_capturer_factory_)
+ encoding_capturer_factory_->OnEncodedVideoSourceAdded(vc);
return vc;
}
@@ -59,6 +62,9 @@ void VideoCaptureImplManager::RemoveDevice(
if (size == it->second->clients.size() || size > 1)
return;
+ if (encoding_capturer_factory_)
+ encoding_capturer_factory_->OnEncodedVideoSourceRemoved(devices_[id]->vc);
+
devices_[id]->vc->DeInit(base::Bind(&VideoCaptureImplManager::FreeDevice,
this, devices_[id]->vc));
delete devices_[id];
diff --git a/content/renderer/media/video_capture_impl_manager.h b/content/renderer/media/video_capture_impl_manager.h
index e942201..9b26b20 100644
--- a/content/renderer/media/video_capture_impl_manager.h
+++ b/content/renderer/media/video_capture_impl_manager.h
@@ -13,14 +13,17 @@
#include <list>
#include <map>
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/thread.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "media/video/capture/video_capture.h"
+#include "media/video/encoded_video_source.h"
namespace content {
+class RtcEncodingVideoCapturerFactory;
class VideoCaptureImpl;
class VideoCaptureMessageFilter;
@@ -50,6 +53,11 @@ class CONTENT_EXPORT VideoCaptureImplManager
return filter_.get();
}
+ void set_encoding_capturer_factory(base::WeakPtr<
+ RtcEncodingVideoCapturerFactory> encoding_capturer_factory) {
+ encoding_capturer_factory_ = encoding_capturer_factory;
+ }
+
protected:
virtual ~VideoCaptureImplManager();
@@ -74,6 +82,12 @@ class CONTENT_EXPORT VideoCaptureImplManager
base::Thread thread_;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ // The encoding capturer factory is created by MediaStreamDependencyFactory
+ // and owned by its PeerConnectionFactory. It is passed to the manager
+ // as a weak pointer at CreatePeerConnectionFactory time because the
+ // PeerConnectionFactory may be released earlier than the manager.
+ base::WeakPtr<RtcEncodingVideoCapturerFactory> encoding_capturer_factory_;
+
DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplManager);
};
diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc
index 8befed0..0c64190 100644
--- a/content/renderer/media/video_capture_impl_unittest.cc
+++ b/content/renderer/media/video_capture_impl_unittest.cc
@@ -4,6 +4,7 @@
#include "base/message_loop.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 "content/renderer/media/video_capture_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -79,6 +80,16 @@ class VideoCaptureImplTest : public ::testing::Test {
IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture)
IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
DeviceReceiveEmptyBuffer)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_GetCapabilities,
+ DeviceGetEncodingCapabilities)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_OpenBitstream,
+ DeviceOpenEncodedBitstream)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_CloseBitstream,
+ DeviceCloseEncodedBitstream)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_TryConfigureBitstream,
+ DeviceSetEncodingConfig)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_BitstreamBufferConsumed,
+ DeviceReturnEncodedBuffer)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
EXPECT_TRUE(handled);
@@ -99,6 +110,20 @@ class VideoCaptureImplTest : public ::testing::Test {
}
void DeviceReceiveEmptyBuffer(int device_id, int buffer_id) {}
+
+ void DeviceGetEncodingCapabilities(
+ int device_id, media::VideoCaptureSessionId session_id) {}
+
+ void DeviceOpenEncodedBitstream(int device_id,
+ media::VideoCaptureSessionId session_id,
+ media::VideoEncodingParameters params) {}
+
+ void DeviceCloseEncodedBitstream(int device_id) {}
+
+ void DeviceSetEncodingConfig(
+ int device_id, media::RuntimeVideoEncodingParameters params) {}
+
+ void DeviceReturnEncodedBuffer(int device_id, int buffer_id) {}
};
VideoCaptureImplTest() {
diff --git a/content/renderer/media/video_capture_message_filter.cc b/content/renderer/media/video_capture_message_filter.cc
index 4d59729..0a4bb61 100644
--- a/content/renderer/media/video_capture_message_filter.cc
+++ b/content/renderer/media/video_capture_message_filter.cc
@@ -4,6 +4,7 @@
#include "content/renderer/media/video_capture_message_filter.h"
+#include "content/common/media/encoded_video_capture_messages.h"
#include "content/common/media/video_capture_messages.h"
#include "content/common/view_messages.h"
@@ -61,7 +62,17 @@ bool VideoCaptureMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnDeviceStateChanged)
IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnBufferCreated)
IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceInfo, OnDeviceInfoReceived)
- IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureMsg_CapabilitiesAvailable,
+ OnCapabilitiesAvailable)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureMsg_BitstreamOpened,
+ OnBitstreamOpened)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureMsg_BitstreamClosed,
+ OnBitstreamClosed)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureMsg_BitstreamConfigChanged,
+ OnBitstreamConfigChanged)
+ IPC_MESSAGE_HANDLER(EncodedVideoCaptureMsg_BitstreamReady,
+ OnBitstreamReady);
+ IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
@@ -90,15 +101,18 @@ void VideoCaptureMessageFilter::OnChannelClosing() {
VideoCaptureMessageFilter::~VideoCaptureMessageFilter() {}
+VideoCaptureMessageFilter::Delegate* VideoCaptureMessageFilter::find_delegate(
+ int device_id) const {
+ Delegates::const_iterator i = delegates_.find(device_id);
+ return i != delegates_.end() ? i->second : NULL;
+}
+
void VideoCaptureMessageFilter::OnBufferCreated(
int device_id,
base::SharedMemoryHandle handle,
int length,
int buffer_id) {
- Delegate* delegate = NULL;
- if (delegates_.find(device_id) != delegates_.end())
- delegate = delegates_.find(device_id)->second;
-
+ Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnBufferCreated: Got video frame buffer for a "
"non-existent or removed video capture.";
@@ -117,10 +131,7 @@ void VideoCaptureMessageFilter::OnBufferReceived(
int device_id,
int buffer_id,
base::Time timestamp) {
- Delegate* delegate = NULL;
- if (delegates_.find(device_id) != delegates_.end())
- delegate = delegates_.find(device_id)->second;
-
+ Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnBufferReceived: Got video frame buffer for a "
"non-existent or removed video capture.";
@@ -137,9 +148,7 @@ void VideoCaptureMessageFilter::OnBufferReceived(
void VideoCaptureMessageFilter::OnDeviceStateChanged(
int device_id,
VideoCaptureState state) {
- Delegate* delegate = NULL;
- if (delegates_.find(device_id) != delegates_.end())
- delegate = delegates_.find(device_id)->second;
+ Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnDeviceStateChanged: Got video capture event for a "
"non-existent or removed video capture.";
@@ -151,9 +160,7 @@ void VideoCaptureMessageFilter::OnDeviceStateChanged(
void VideoCaptureMessageFilter::OnDeviceInfoReceived(
int device_id,
const media::VideoCaptureParams& params) {
- Delegate* delegate = NULL;
- if (delegates_.find(device_id) != delegates_.end())
- delegate = delegates_.find(device_id)->second;
+ Delegate* delegate = find_delegate(device_id);
if (!delegate) {
DLOG(WARNING) << "OnDeviceInfoReceived: Got video capture event for a "
"non-existent or removed video capture.";
@@ -162,4 +169,64 @@ void VideoCaptureMessageFilter::OnDeviceInfoReceived(
delegate->OnDeviceInfoReceived(params);
}
+void VideoCaptureMessageFilter::OnCapabilitiesAvailable(
+ int device_id,
+ media::VideoEncodingCapabilities capabilities) {
+ Delegate* delegate = find_delegate(device_id);
+ if (!delegate) {
+ DLOG(WARNING) << "OnCapabilitiesAvailable: Got video capture event for a "
+ "non-existent or removed video capture.";
+ return;
+ }
+ delegate->OnEncodingCapabilitiesAvailable(capabilities);
+}
+
+void VideoCaptureMessageFilter::OnBitstreamOpened(
+ int device_id,
+ media::VideoEncodingParameters params,
+ std::vector<base::SharedMemoryHandle> buffers,
+ uint32 buffer_size) {
+ Delegate* delegate = find_delegate(device_id);
+ if (!delegate) {
+ DLOG(WARNING) << "OnBitstreamOpened: Got video capture event for a "
+ "non-existent or removed video capture.";
+ return;
+ }
+ delegate->OnEncodedBitstreamOpened(params, buffers, buffer_size);
+}
+
+void VideoCaptureMessageFilter::OnBitstreamClosed(int device_id) {
+ Delegate* delegate = find_delegate(device_id);
+ if (!delegate) {
+ DLOG(WARNING) << "OnBitstreamClosed: Got video capture event for a "
+ "non-existent or removed video capture.";
+ return;
+ }
+ delegate->OnEncodedBitstreamClosed();
+}
+
+void VideoCaptureMessageFilter::OnBitstreamConfigChanged(
+ int device_id,
+ media::RuntimeVideoEncodingParameters params) {
+ Delegate* delegate = find_delegate(device_id);
+ if (!delegate) {
+ DLOG(WARNING) << "OnBitstreamConfigChanged: Got video capture event for a "
+ "non-existent or removed video capture.";
+ return;
+ }
+ delegate->OnEncodingConfigChanged(params);
+}
+
+void VideoCaptureMessageFilter::OnBitstreamReady(
+ int device_id, int buffer_id, uint32 size,
+ media::BufferEncodingMetadata metadata) {
+ Delegate* delegate = find_delegate(device_id);
+ if (!delegate) {
+ DLOG(WARNING) << "OnBitstreamReady: Got video capture event for a "
+ "non-existent or removed video capture.";
+ return;
+ }
+ delegate->OnEncodedBufferReady(buffer_id, size, metadata);
+}
+
} // namespace content
diff --git a/content/renderer/media/video_capture_message_filter.h b/content/renderer/media/video_capture_message_filter.h
index 3499540..e4ee732 100644
--- a/content/renderer/media/video_capture_message_filter.h
+++ b/content/renderer/media/video_capture_message_filter.h
@@ -18,6 +18,7 @@
#include "content/common/media/video_capture.h"
#include "ipc/ipc_channel_proxy.h"
#include "media/video/capture/video_capture.h"
+#include "media/video/encoded_video_source.h"
namespace content {
@@ -46,6 +47,31 @@ class CONTENT_EXPORT VideoCaptureMessageFilter
// |device_id| is the device id for the delegate.
virtual void OnDelegateAdded(int32 device_id) = 0;
+ // Called when the encoding capabilities is received from video capture
+ // device in the browser process.
+ virtual void OnEncodingCapabilitiesAvailable(
+ const media::VideoEncodingCapabilities& capabilities) = 0;
+
+ // Called when a bitstream is opened on a video capture device.
+ virtual void OnEncodedBitstreamOpened(
+ const media::VideoEncodingParameters& params,
+ const std::vector<base::SharedMemoryHandle>& buffers,
+ uint32 buffer_size) = 0;
+
+ // Called when a bitstream is closed on a video capture device.
+ virtual void OnEncodedBitstreamClosed() = 0;
+
+ // Called when encoding parameters has changed.
+ virtual void OnEncodingConfigChanged(
+ const media::RuntimeVideoEncodingParameters& params) = 0;
+
+ // Called when an encoded bitstream buffer is received from video capture
+ // device in the browser process.
+ virtual void OnEncodedBufferReady(
+ int buffer_id,
+ uint32 size,
+ const media::BufferEncodingMetadata& metadata) = 0;
+
protected:
virtual ~Delegate() {}
};
@@ -92,6 +118,30 @@ class CONTENT_EXPORT VideoCaptureMessageFilter
void OnDeviceInfoReceived(int device_id,
const media::VideoCaptureParams& params);
+ // Receive encoding capabilities from browser process.
+ void OnCapabilitiesAvailable(int device_id,
+ media::VideoEncodingCapabilities capabilities);
+
+ // Bitstream is opened on video capture device.
+ void OnBitstreamOpened(int device_id,
+ media::VideoEncodingParameters params,
+ std::vector<base::SharedMemoryHandle> buffers,
+ uint32 buffer_size);
+
+ // Bitstream is closed on video capture device.
+ void OnBitstreamClosed(int device_id);
+
+ // Receive current encoding parameters from browser process.
+ void OnBitstreamConfigChanged(int device_id,
+ media::RuntimeVideoEncodingParameters params);
+
+ // Receive an encoded bitstream buffer from browser process.
+ void OnBitstreamReady(int device_id, int buffer_id, uint32 size,
+ media::BufferEncodingMetadata metadata);
+
+ // Finds the delegate associated with |device_id|, NULL if not found.
+ Delegate* find_delegate(int device_id) const;
+
// A map of device ids to delegates.
Delegates delegates_;
Delegates pending_delegates_;
diff --git a/content/renderer/media/video_capture_message_filter_unittest.cc b/content/renderer/media/video_capture_message_filter_unittest.cc
index b0ffbc7..99178ce 100644
--- a/content/renderer/media/video_capture_message_filter_unittest.cc
+++ b/content/renderer/media/video_capture_message_filter_unittest.cc
@@ -50,6 +50,21 @@ class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate {
device_id_ = device_id;
}
+ // TODO(hshi): implement the following methods for encoded video capture.
+ virtual void OnEncodingCapabilitiesAvailable(
+ const media::VideoEncodingCapabilities& capabilities) OVERRIDE {}
+ virtual void OnEncodedBitstreamOpened(
+ const media::VideoEncodingParameters& params,
+ const std::vector<base::SharedMemoryHandle>& buffers,
+ uint32 buffer_size) OVERRIDE {}
+ virtual void OnEncodedBitstreamClosed() OVERRIDE {}
+ virtual void OnEncodingConfigChanged(
+ const media::RuntimeVideoEncodingParameters& params) OVERRIDE {}
+ virtual void OnEncodedBufferReady(
+ int buffer_id,
+ uint32 size,
+ const media::BufferEncodingMetadata& metadata) OVERRIDE {}
+
void Reset() {
buffer_created_ = false;
handle_ = base::SharedMemory::NULLHandle();
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index bf80df0..2ebb832 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -86,7 +86,8 @@ enum IPCMessageStart {
WebSocketMsgStart,
NaClHostMsgStart,
WebRTCIdentityMsgStart,
- LastIPCMsgStart // Must come last.
+ EncodedVideoCaptureMsgStart,
+ LastIPCMsgStart // Must come last.
};
#endif // IPC_IPC_MESSAGE_START_H_
diff --git a/media/base/encoded_bitstream_buffer.cc b/media/base/encoded_bitstream_buffer.cc
new file mode 100644
index 0000000..3689015
--- /dev/null
+++ b/media/base/encoded_bitstream_buffer.cc
@@ -0,0 +1,50 @@
+// Copyright 2013 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.
+
+#include "media/base/encoded_bitstream_buffer.h"
+
+#include "base/logging.h"
+
+namespace media {
+
+EncodedBitstreamBuffer::EncodedBitstreamBuffer(
+ int buffer_id,
+ uint8* buffer,
+ uint32 size,
+ base::SharedMemoryHandle handle,
+ const media::BufferEncodingMetadata& metadata,
+ const base::Closure& destroy_cb)
+ : buffer_id_(buffer_id),
+ buffer_(buffer),
+ size_(size),
+ shared_memory_handle_(handle),
+ metadata_(metadata),
+ destroy_cb_(destroy_cb) {
+}
+
+EncodedBitstreamBuffer::~EncodedBitstreamBuffer() {
+ destroy_cb_.Run();
+}
+
+int EncodedBitstreamBuffer::buffer_id() const {
+ return buffer_id_;
+}
+
+const uint8* EncodedBitstreamBuffer::buffer() const {
+ return buffer_;
+}
+
+uint32 EncodedBitstreamBuffer::size() const {
+ return size_;
+}
+
+base::SharedMemoryHandle EncodedBitstreamBuffer::shared_memory_handle() const {
+ return shared_memory_handle_;
+}
+
+const media::BufferEncodingMetadata& EncodedBitstreamBuffer::metadata() const {
+ return metadata_;
+}
+
+} // namespace media
diff --git a/media/base/encoded_bitstream_buffer.h b/media/base/encoded_bitstream_buffer.h
new file mode 100644
index 0000000..6fe24c8
--- /dev/null
+++ b/media/base/encoded_bitstream_buffer.h
@@ -0,0 +1,52 @@
+// Copyright 2013 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_BASE_ENCODED_BITSTREAM_BUFFER_H_
+#define MEDIA_BASE_ENCODED_BITSTREAM_BUFFER_H_
+
+#include "base/callback_forward.h"
+#include "base/memory/ref_counted.h"
+#include "base/shared_memory.h"
+#include "base/time/time.h"
+#include "media/base/media_export.h"
+#include "media/video/video_encode_types.h"
+
+namespace media {
+
+// General encoded video bitstream buffer.
+class MEDIA_EXPORT EncodedBitstreamBuffer :
+ public base::RefCountedThreadSafe<EncodedBitstreamBuffer> {
+ public:
+ EncodedBitstreamBuffer(int buffer_id,
+ uint8* buffer,
+ uint32 size,
+ base::SharedMemoryHandle handle,
+ const media::BufferEncodingMetadata& metadata,
+ const base::Closure& destroy_cb);
+ // Accessors for properties.
+ int buffer_id() const;
+ const uint8* buffer() const;
+ uint32 size() const;
+ base::SharedMemoryHandle shared_memory_handle() const;
+ const media::BufferEncodingMetadata& metadata() const;
+
+ protected:
+ // Destructor that deallocates the buffers.
+ virtual ~EncodedBitstreamBuffer();
+ friend class base::RefCountedThreadSafe<EncodedBitstreamBuffer>;
+
+ private:
+ int buffer_id_;
+ uint8* buffer_;
+ uint32 size_;
+ const base::SharedMemoryHandle shared_memory_handle_;
+ media::BufferEncodingMetadata metadata_;
+ const base::Closure destroy_cb_;
+
+ DISALLOW_COPY_AND_ASSIGN(EncodedBitstreamBuffer);
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_ENCODED_BITSTREAM_BUFFER_H_
diff --git a/media/media.gyp b/media/media.gyp
index 10ee0f8..88b28dc 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -258,6 +258,8 @@
'base/demuxer_stream.h',
'base/djb2.cc',
'base/djb2.h',
+ 'base/encoded_bitstream_buffer.cc',
+ 'base/encoded_bitstream_buffer.h',
'base/filter_collection.cc',
'base/filter_collection.h',
'base/media.cc',
@@ -413,10 +415,12 @@
'video/capture/win/video_capture_device_mf_win.h',
'video/capture/win/video_capture_device_win.cc',
'video/capture/win/video_capture_device_win.h',
+ 'video/encoded_video_source.h',
'video/picture.cc',
'video/picture.h',
'video/video_decode_accelerator.cc',
'video/video_decode_accelerator.h',
+ 'video/video_encode_types.h',
'webm/webm_audio_client.cc',
'webm/webm_audio_client.h',
'webm/webm_cluster_parser.cc',
diff --git a/media/video/encoded_video_source.h b/media/video/encoded_video_source.h
new file mode 100644
index 0000000..e2ce201
--- /dev/null
+++ b/media/video/encoded_video_source.h
@@ -0,0 +1,76 @@
+// Copyright 2013 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_ENCODED_VIDEO_SOURCE_H_
+#define MEDIA_VIDEO_ENCODED_VIDEO_SOURCE_H_
+
+#include "base/memory/ref_counted.h"
+#include "media/base/encoded_bitstream_buffer.h"
+#include "media/video/video_encode_types.h"
+
+namespace media {
+
+// Class to represent any encoded video source. Anything that provides encoded
+// video can be an EncodedVideoSource. Notable examples of this can be video
+// encoder and webcam that has encoding capabilities.
+// TODO(hshi): merge this with VEA interface. http://crbug.com/248334.
+class EncodedVideoSource {
+ public:
+ class Client {
+ public:
+ // Notifies client that bitstream is opened successfully. The |params|
+ // contains the actual encoding parameters chosen by the browser process.
+ // It may be different from the params requested in OpenBitstream().
+ virtual void OnOpened(const VideoEncodingParameters& params) = 0;
+
+ // Notifies client that bitstream is closed. After this call it is
+ // guaranteed that client will not receive further calls.
+ virtual void OnClosed() = 0;
+
+ // Delivers an encoded bitstream buffer to the client.
+ virtual void OnBufferReady(
+ scoped_refptr<const EncodedBitstreamBuffer> buffer) = 0;
+
+ // Notifies client that encoding parameters has changed. The |params|
+ // contains the current encoding parameters chosen by the browser process.
+ // It may be different from the params requested in TrySetBitstreamConfig().
+ virtual void OnConfigChanged(
+ const RuntimeVideoEncodingParameters& params) = 0;
+ };
+
+ // Callback is invoked once RequestCapabilities() is complete.
+ typedef base::Callback<void(const VideoEncodingCapabilities& capabilities)>
+ RequestCapabilitiesCallback;
+
+ // RequestCapabilities initiates an asynchronous query for the types of
+ // encoded bitstream supported by the encoder. This call should be invoked
+ // only once. EncodedVideoSource will invoke |callback| when capabilities
+ // become available.
+ virtual void RequestCapabilities(
+ const RequestCapabilitiesCallback& callback) = 0;
+
+ // OpenBitstream opens the bitstream on the encoded video source. Only one
+ // bitstream can be opened for an encoded video source.
+ virtual void OpenBitstream(Client* client,
+ const VideoEncodingParameters& params) = 0;
+
+ // CloseBitstream closes the bitstream.
+ virtual void CloseBitstream() = 0;
+
+ // ReturnBitstreamBuffer notifies that the data within the buffer has been
+ // processed and it can be reused to encode upcoming bitstream.
+ virtual void ReturnBitstreamBuffer(
+ scoped_refptr<const media::EncodedBitstreamBuffer> buffer) = 0;
+
+ // TrySetBitstreamConfig requests to change encoding parameters. Old config
+ // must be considered valid until OnConfigChanged is invoked on the client
+ // signaling successful change.
+ virtual void TrySetBitstreamConfig(
+ const RuntimeVideoEncodingParameters& params) = 0;
+};
+
+} // namespace media
+
+#endif // MEDIA_VIDEO_ENCODED_VIDEO_SOURCE_H_
+
diff --git a/media/video/video_encode_types.h b/media/video/video_encode_types.h
new file mode 100644
index 0000000..0372019
--- /dev/null
+++ b/media/video/video_encode_types.h
@@ -0,0 +1,51 @@
+// Copyright 2013 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_VIDEO_ENCODE_TYPES_H_
+#define MEDIA_VIDEO_VIDEO_ENCODE_TYPES_H_
+
+#include <map>
+#include <ostream>
+#include <vector>
+
+#include "base/time/time.h"
+#include "media/base/video_decoder_config.h"
+#include "ui/gfx/size.h"
+
+namespace media {
+
+// Data to represent limitations for a particular encoder config.
+struct VideoEncodingConfig {
+ VideoCodec codec_type;
+ std::string codec_name;
+ gfx::Size max_resolution;
+ int max_frames_per_second;
+ int max_bitrate;
+};
+
+typedef std::vector<VideoEncodingConfig> VideoEncodingCapabilities;
+
+// Encoding parameters that can be configured during streaming without removing
+// the bitstream first.
+struct RuntimeVideoEncodingParameters {
+ int target_bitrate;
+ int max_bitrate;
+ int frames_per_second;
+};
+
+// Generic video encoding parameters to be configured during initialization
+// time.
+struct VideoEncodingParameters {
+ std::string codec_name;
+ gfx::Size resolution;
+ RuntimeVideoEncodingParameters runtime_params;
+};
+
+struct BufferEncodingMetadata {
+ base::Time timestamp;
+ bool key_frame;
+};
+
+} // namespace media
+
+#endif // MEDIA_VIDEO_VIDEO_ENCODE_TYPES_H_