summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/common/media/encoded_video_capture_messages.h7
-rw-r--r--content/renderer/media/rtc_encoding_video_capturer.cc40
-rw-r--r--content/renderer/media/video_capture_impl.cc4
-rw-r--r--content/renderer/media/video_capture_impl.h1
-rw-r--r--content/renderer/media/video_capture_impl_unittest.cc4
-rw-r--r--media/video/encoded_video_source.h3
-rw-r--r--media/video/video_encode_types.h14
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