summaryrefslogtreecommitdiffstats
path: root/remoting/codec
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 02:16:22 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 02:16:22 +0000
commit19fa2d9552faf1fb8c505e69f4683579239cd94f (patch)
treec672266b2f753d9c558e4c69c8a23a7bd309d5a1 /remoting/codec
parent22d2209e2359574649fe2ce52f3290c931b19209 (diff)
downloadchromium_src-19fa2d9552faf1fb8c505e69f4683579239cd94f.zip
chromium_src-19fa2d9552faf1fb8c505e69f4683579239cd94f.tar.gz
chromium_src-19fa2d9552faf1fb8c505e69f4683579239cd94f.tar.bz2
Clean up common parts of VPX codec initialization.
This includes some improvements & fixes: - VP9 is now initialized for multi-threaded encode. - Frame timestamp base is correctly set to milliseconds. - Frame timestamps are now set based on elapsed time. Review URL: https://codereview.chromium.org/265113002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269151 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/codec')
-rw-r--r--remoting/codec/video_encoder_vpx.cc72
-rw-r--r--remoting/codec/video_encoder_vpx.h3
2 files changed, 41 insertions, 34 deletions
diff --git a/remoting/codec/video_encoder_vpx.cc b/remoting/codec/video_encoder_vpx.cc
index cee7994..59bb5dc 100644
--- a/remoting/codec/video_encoder_vpx.cc
+++ b/remoting/codec/video_encoder_vpx.cc
@@ -7,7 +7,6 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/sys_info.h"
-#include "base/time/time.h"
#include "media/base/yuv_convert.h"
#include "remoting/base/util.h"
#include "remoting/proto/video.pb.h"
@@ -29,6 +28,30 @@ namespace {
// map for the encoder.
const int kMacroBlockSize = 16;
+void SetCommonCodecParameters(const webrtc::DesktopSize& size,
+ vpx_codec_enc_cfg_t* config) {
+ // Use millisecond granularity time base.
+ config->g_timebase.num = 1;
+ config->g_timebase.den = 1000;
+
+ // Adjust default target bit-rate to account for actual desktop size.
+ config->rc_target_bitrate = size.width() * size.height() *
+ config->rc_target_bitrate / config->g_w / config->g_h;
+
+ config->g_w = size.width();
+ config->g_h = size.height();
+ config->g_pass = VPX_RC_ONE_PASS;
+
+ // Start emitting packets immediately.
+ config->g_lag_in_frames = 0;
+
+ // Using 2 threads gives a great boost in performance for most systems with
+ // adequate processing power. NB: Going to multiple threads on low end
+ // windows systems can really hurt performance.
+ // http://crbug.com/99179
+ config->g_threads = (base::SysInfo::NumberOfProcessors() > 2) ? 2 : 1;
+}
+
ScopedVpxCodec CreateVP8Codec(const webrtc::DesktopSize& size) {
ScopedVpxCodec codec(new vpx_codec_ctx_t);
@@ -40,26 +63,16 @@ ScopedVpxCodec CreateVP8Codec(const webrtc::DesktopSize& size) {
if (ret != VPX_CODEC_OK)
return ScopedVpxCodec();
- config.rc_target_bitrate = size.width() * size.height() *
- config.rc_target_bitrate / config.g_w / config.g_h;
- config.g_w = size.width();
- config.g_h = size.height();
- config.g_pass = VPX_RC_ONE_PASS;
+ SetCommonCodecParameters(size, &config);
// Value of 2 means using the real time profile. This is basically a
// redundant option since we explicitly select real time mode when doing
// encoding.
config.g_profile = 2;
- // Using 2 threads gives a great boost in performance for most systems with
- // adequate processing power. NB: Going to multiple threads on low end
- // windows systems can really hurt performance.
- // http://crbug.com/99179
- config.g_threads = (base::SysInfo::NumberOfProcessors() > 2) ? 2 : 1;
+ // Clamping the quantizer constrains the worst-case quality and CPU usage.
config.rc_min_quantizer = 20;
config.rc_max_quantizer = 30;
- config.g_timebase.num = 1;
- config.g_timebase.den = 20;
if (vpx_codec_enc_init(codec.get(), algo, &config, 0))
return ScopedVpxCodec();
@@ -88,19 +101,13 @@ ScopedVpxCodec CreateVP9Codec(const webrtc::DesktopSize& size) {
if (ret != VPX_CODEC_OK)
return ScopedVpxCodec();
- //config.rc_target_bitrate = size.width() * size.height() *
- // config.rc_target_bitrate / config.g_w / config.g_h;
- config.g_w = size.width();
- config.g_h = size.height();
- config.g_pass = VPX_RC_ONE_PASS;
+ SetCommonCodecParameters(size, &config);
- // Only the default profile is currently supported for VP9 encoding.
+ // Configure VP9 for I420 source frames.
config.g_profile = 0;
- // Start emitting packets immediately.
- config.g_lag_in_frames = 0;
-
- // Prevent VP9 from ruining output quality with quantization.
+ // Disable quantization entirely, putting the encoder in "lossless" mode.
+ config.rc_min_quantizer = 0;
config.rc_max_quantizer = 0;
if (vpx_codec_enc_init(codec.get(), algo, &config, 0))
@@ -142,13 +149,16 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
DCHECK_LE(32, frame.size().width());
DCHECK_LE(32, frame.size().height());
- base::Time encode_start_time = base::Time::Now();
+ base::TimeTicks encode_start_time = base::TimeTicks::Now();
if (!codec_ ||
!frame.size().equals(webrtc::DesktopSize(image_->w, image_->h))) {
bool ret = Initialize(frame.size());
// TODO(hclam): Handle error better.
CHECK(ret) << "Initialization of encoder failed";
+
+ // Set now as the base for timestamp calculation.
+ timestamp_base_ = encode_start_time;
}
// Convert the updated capture data ready for encode.
@@ -168,17 +178,14 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
}
// Do the actual encoding.
- vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
- last_timestamp_,
- 1, 0, VPX_DL_REALTIME);
+ int timestamp = (encode_start_time - timestamp_base_).InMilliseconds();
+ vpx_codec_err_t ret = vpx_codec_encode(
+ codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME);
DCHECK_EQ(ret, VPX_CODEC_OK)
<< "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
<< "Details: " << vpx_codec_error(codec_.get()) << "\n"
<< vpx_codec_error_detail(codec_.get());
- // TODO(hclam): Apply the proper timestamp here.
- last_timestamp_ += 50;
-
// Read the encoded data.
vpx_codec_iter_t iter = NULL;
bool got_data = false;
@@ -209,7 +216,7 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
packet->mutable_format()->set_screen_height(frame.size().height());
packet->set_capture_time_ms(frame.capture_time_ms());
packet->set_encode_time_ms(
- (base::Time::Now() - encode_start_time).InMillisecondsRoundedUp());
+ (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp());
if (!frame.dpi().is_zero()) {
packet->mutable_format()->set_x_dpi(frame.dpi().x());
packet->mutable_format()->set_y_dpi(frame.dpi().y());
@@ -229,8 +236,7 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
VideoEncoderVpx::VideoEncoderVpx(const InitializeCodecCallback& init_codec)
: init_codec_(init_codec),
active_map_width_(0),
- active_map_height_(0),
- last_timestamp_(0) {
+ active_map_height_(0) {
}
bool VideoEncoderVpx::Initialize(const webrtc::DesktopSize& size) {
diff --git a/remoting/codec/video_encoder_vpx.h b/remoting/codec/video_encoder_vpx.h
index 286745f..dd7fb2e 100644
--- a/remoting/codec/video_encoder_vpx.h
+++ b/remoting/codec/video_encoder_vpx.h
@@ -6,6 +6,7 @@
#define REMOTING_CODEC_VIDEO_ENCODER_VPX_H_
#include "base/callback.h"
+#include "base/time/time.h"
#include "remoting/codec/scoped_vpx_codec.h"
#include "remoting/codec/video_encoder.h"
@@ -55,7 +56,7 @@ class VideoEncoderVpx : public VideoEncoder {
scoped_ptr<uint8[]> active_map_;
int active_map_width_;
int active_map_height_;
- int last_timestamp_;
+ base::TimeTicks timestamp_base_;
// Buffer for storing the yuv image.
scoped_ptr<uint8[]> yuv_image_;