diff options
author | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-23 17:04:45 +0000 |
---|---|---|
committer | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-23 17:04:45 +0000 |
commit | 348baf5a7b91cc4801dca5eae2921072055f35bc (patch) | |
tree | 5a5d0be56db613c9fef29ead4711abe7518eea5f | |
parent | 4f17b6707312cd857f888ea2e2e10fe994e76d92 (diff) | |
download | chromium_src-348baf5a7b91cc4801dca5eae2921072055f35bc.zip chromium_src-348baf5a7b91cc4801dca5eae2921072055f35bc.tar.gz chromium_src-348baf5a7b91cc4801dca5eae2921072055f35bc.tar.bz2 |
Encoded video capture: wire up key frame and bitrate settings.
Define RequestKeyFrame in IPC message header.
Wire up RequestKeyFrame and TrySetBitstreamConfig with the corresponding entry points
in WebRTC video encoder.
BUG=221441
TEST=trybot
Review URL: https://chromiumcodereview.appspot.com/19860002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213143 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/common/media/encoded_video_capture_messages.h | 7 | ||||
-rw-r--r-- | content/renderer/media/rtc_encoding_video_capturer.cc | 40 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl.cc | 4 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl.h | 1 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl_unittest.cc | 4 | ||||
-rw-r--r-- | media/video/encoded_video_source.h | 3 | ||||
-rw-r--r-- | media/video/video_encode_types.h | 14 |
7 files changed, 63 insertions, 10 deletions
diff --git a/content/common/media/encoded_video_capture_messages.h b/content/common/media/encoded_video_capture_messages.h index 8de6fb9..6313f72 100644 --- a/content/common/media/encoded_video_capture_messages.h +++ b/content/common/media/encoded_video_capture_messages.h @@ -77,6 +77,13 @@ IPC_MESSAGE_CONTROL2(EncodedVideoCaptureHostMsg_TryConfigureBitstream, int /* device_id */, media::RuntimeVideoEncodingParameters /* params */) +// Requests a key frame in the encoded bitstream. Upon receiving this request, +// browser will try to encode an upcoming captured frame as a key frame. This +// allows the receiver to quickly recover from data loss. The request is served +// on a best-effort basis and there is no explicit acknowledgement. +IPC_MESSAGE_CONTROL1(EncodedVideoCaptureHostMsg_RequestKeyFrame, + int /* device_id */) + // Notifies that the data within a buffer has been processed and it can be // reused to encode upcoming bitstream. IPC_MESSAGE_CONTROL2(EncodedVideoCaptureHostMsg_BitstreamBufferConsumed, diff --git a/content/renderer/media/rtc_encoding_video_capturer.cc b/content/renderer/media/rtc_encoding_video_capturer.cc index ff022d4..9561c83 100644 --- a/content/renderer/media/rtc_encoding_video_capturer.cc +++ b/content/renderer/media/rtc_encoding_video_capturer.cc @@ -9,6 +9,12 @@ namespace content { +namespace { + +static const unsigned int kMaxBitrateKbps = 50 * 1000; + +} // namespace + // Client of EncodedVideoSource. This object is created and owned by the // RtcEncodingVideoCapturer. class RtcEncodingVideoCapturer::EncodedVideoSourceClient : @@ -34,6 +40,12 @@ class RtcEncodingVideoCapturer::EncodedVideoSourceClient : void set_round_trip_time(base::TimeDelta round_trip_time); void set_callback(webrtc::EncodedImageCallback* callback); + // Sets target bitrate and framerate. + void SetRates(uint32_t target_bitrate, uint32_t frame_rate); + + // Requests key frame. + void RequestKeyFrame(); + private: // Convert buffer to webrtc types and invoke encode complete callback. void ReportEncodedFrame( @@ -112,6 +124,17 @@ void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnConfigChanged( params_.runtime_params = params; } +void RtcEncodingVideoCapturer::EncodedVideoSourceClient::SetRates( + uint32_t target_bitrate, uint32_t frame_rate) { + params_.runtime_params.target_bitrate = target_bitrate; + params_.runtime_params.frames_per_second = frame_rate; + encoded_video_source_->TrySetBitstreamConfig(params_.runtime_params); +} + +void RtcEncodingVideoCapturer::EncodedVideoSourceClient::RequestKeyFrame() { + encoded_video_source_->RequestKeyFrame(); +} + void RtcEncodingVideoCapturer::EncodedVideoSourceClient::ReportEncodedFrame( scoped_refptr<const media::EncodedBitstreamBuffer> buffer) { if (!callback_) @@ -173,13 +196,16 @@ int32_t RtcEncodingVideoCapturer::InitEncode( DCHECK(!encoded_video_source_client_); if (codecSettings->codecType != rtc_codec_type_) return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; + if (codecSettings->startBitrate > kMaxBitrateKbps || + codecSettings->maxBitrate > kMaxBitrateKbps) + 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.target_bitrate = codecSettings->startBitrate * 1000; + params.runtime_params.max_bitrate = codecSettings->maxBitrate * 1000; params.runtime_params.frames_per_second = codecSettings->maxFramerate; encoded_video_source_client_.reset(new EncodedVideoSourceClient( encoded_video_source_, params, rtc_codec_type_)); @@ -190,7 +216,11 @@ 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. + if (frame_types && !frame_types->empty()) { + webrtc::VideoFrameType type = frame_types->front(); + if (type == webrtc::kKeyFrame) + encoded_video_source_client_->RequestKeyFrame(); + } return WEBRTC_VIDEO_CODEC_OK; } @@ -221,7 +251,9 @@ 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. + if (newBitRate > kMaxBitrateKbps) + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; + encoded_video_source_client_->SetRates(newBitRate * 1000, frameRate); return WEBRTC_VIDEO_CODEC_OK; } diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index 3df7b61..2edd664 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc @@ -143,6 +143,10 @@ void VideoCaptureImpl::TrySetBitstreamConfig( device_id_, params)); } +void VideoCaptureImpl::RequestKeyFrame() { + Send(new EncodedVideoCaptureHostMsg_RequestKeyFrame(device_id_)); +} + void VideoCaptureImpl::OnEncodingCapabilitiesAvailable( const media::VideoEncodingCapabilities& capabilities) { capture_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h index d184fce..b0ac059 100644 --- a/content/renderer/media/video_capture_impl.h +++ b/content/renderer/media/video_capture_impl.h @@ -97,6 +97,7 @@ class CONTENT_EXPORT VideoCaptureImpl scoped_refptr<const media::EncodedBitstreamBuffer> buffer) OVERRIDE; virtual void TrySetBitstreamConfig( const media::RuntimeVideoEncodingParameters& params) OVERRIDE; + virtual void RequestKeyFrame() OVERRIDE; // Stop/resume delivering video frames to clients, based on flag |suspend|. virtual void SuspendCapture(bool suspend); diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc index 86c5eb1..22f645a 100644 --- a/content/renderer/media/video_capture_impl_unittest.cc +++ b/content/renderer/media/video_capture_impl_unittest.cc @@ -88,6 +88,8 @@ class VideoCaptureImplTest : public ::testing::Test { DeviceCloseEncodedBitstream) IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_TryConfigureBitstream, DeviceSetEncodingConfig) + IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_RequestKeyFrame, + DeviceRequestKeyFrame) IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_BitstreamBufferConsumed, DeviceReturnEncodedBuffer) IPC_MESSAGE_UNHANDLED(handled = false) @@ -123,6 +125,8 @@ class VideoCaptureImplTest : public ::testing::Test { void DeviceSetEncodingConfig( int device_id, media::RuntimeVideoEncodingParameters params) {} + void DeviceRequestKeyFrame(int device_id) {} + void DeviceReturnEncodedBuffer(int device_id, int buffer_id) {} }; diff --git a/media/video/encoded_video_source.h b/media/video/encoded_video_source.h index e2ce201..f0c9a13 100644 --- a/media/video/encoded_video_source.h +++ b/media/video/encoded_video_source.h @@ -68,6 +68,9 @@ class EncodedVideoSource { // signaling successful change. virtual void TrySetBitstreamConfig( const RuntimeVideoEncodingParameters& params) = 0; + + // RequestKeyFrame requests a key frame. + virtual void RequestKeyFrame() = 0; }; } // namespace media diff --git a/media/video/video_encode_types.h b/media/video/video_encode_types.h index 0372019..15effab 100644 --- a/media/video/video_encode_types.h +++ b/media/video/video_encode_types.h @@ -15,22 +15,24 @@ namespace media { // Data to represent limitations for a particular encoder config. +// The |max_bitrate| value is in bits per second. struct VideoEncodingConfig { VideoCodec codec_type; std::string codec_name; gfx::Size max_resolution; - int max_frames_per_second; - int max_bitrate; + uint32 max_frames_per_second; + uint32 max_bitrate; }; typedef std::vector<VideoEncodingConfig> VideoEncodingCapabilities; // Encoding parameters that can be configured during streaming without removing -// the bitstream first. +// the bitstream first. The |target_bitrate| and |max_bitrate| values are in +// bits per second. struct RuntimeVideoEncodingParameters { - int target_bitrate; - int max_bitrate; - int frames_per_second; + uint32 target_bitrate; + uint32 max_bitrate; + uint32 frames_per_second; }; // Generic video encoding parameters to be configured during initialization |