summaryrefslogtreecommitdiffstats
path: root/remoting/codec/video_encoder_vpx.cc
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-30 07:21:20 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-30 07:21:20 +0000
commita516f1e0a9fa2648ba2c3ef50cbce4ee8bcf0f3c (patch)
treed520cb43b33b10961e6e1c92da6acb0a14878d52 /remoting/codec/video_encoder_vpx.cc
parente9ff69854e96d7e750242651134110c9ad5b7bed (diff)
downloadchromium_src-a516f1e0a9fa2648ba2c3ef50cbce4ee8bcf0f3c.zip
chromium_src-a516f1e0a9fa2648ba2c3ef50cbce4ee8bcf0f3c.tar.gz
chromium_src-a516f1e0a9fa2648ba2c3ef50cbce4ee8bcf0f3c.tar.bz2
Extend VideoControl to allow clients to request lossless modes.
- Lossless encode/color requests may be ignored by codecs. - VideoEncoderVpx supports lossless color when using VP9. - The --enable-i444 flag now controls the default color mode for VP9. BUG=260879,134202 Review URL: https://codereview.chromium.org/304653002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273752 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/codec/video_encoder_vpx.cc')
-rw-r--r--remoting/codec/video_encoder_vpx.cc82
1 files changed, 57 insertions, 25 deletions
diff --git a/remoting/codec/video_encoder_vpx.cc b/remoting/codec/video_encoder_vpx.cc
index 3b27172..fba110a 100644
--- a/remoting/codec/video_encoder_vpx.cc
+++ b/remoting/codec/video_encoder_vpx.cc
@@ -5,6 +5,7 @@
#include "remoting/codec/video_encoder_vpx.h"
#include "base/bind.h"
+#include "base/command_line.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "remoting/base/util.h"
@@ -24,6 +25,9 @@ namespace remoting {
namespace {
+// Name of command-line flag to enable VP9 to use I444 by default.
+const char kEnableI444SwitchName[] = "enable-i444";
+
// Number of bytes in an RGBx pixel.
const int kBytesPerRgbPixel = 4;
@@ -97,7 +101,9 @@ ScopedVpxCodec CreateVP8Codec(const webrtc::DesktopSize& size) {
return codec.Pass();
}
-ScopedVpxCodec CreateVP9Codec(bool use_i444, const webrtc::DesktopSize& size) {
+ScopedVpxCodec CreateVP9Codec(const webrtc::DesktopSize& size,
+ bool lossless_color,
+ bool lossless_encode) {
ScopedVpxCodec codec(new vpx_codec_ctx_t);
// Configure the encoder.
@@ -111,11 +117,18 @@ ScopedVpxCodec CreateVP9Codec(bool use_i444, const webrtc::DesktopSize& size) {
SetCommonCodecParameters(size, &config);
// Configure VP9 for I420 or I444 source frames.
- config.g_profile = use_i444 ? kVp9I444ProfileNumber : kVp9I420ProfileNumber;
-
- // Disable quantization entirely, putting the encoder in "lossless" mode.
- config.rc_min_quantizer = 0;
- config.rc_max_quantizer = 0;
+ config.g_profile =
+ lossless_color ? kVp9I444ProfileNumber : kVp9I420ProfileNumber;
+
+ if (lossless_encode) {
+ // Disable quantization entirely, putting the encoder in "lossless" mode.
+ config.rc_min_quantizer = 0;
+ config.rc_max_quantizer = 0;
+ } else {
+ // Lossy encode using the same settings as for VP8.
+ config.rc_min_quantizer = 20;
+ config.rc_max_quantizer = 30;
+ }
if (vpx_codec_enc_init(codec.get(), algo, &config, 0))
return ScopedVpxCodec();
@@ -202,26 +215,29 @@ void CreateImage(bool use_i444,
// static
scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP8() {
- return scoped_ptr<VideoEncoderVpx>(
- new VideoEncoderVpx(base::Bind(&CreateVP8Codec),
- base::Bind(&CreateImage, false)));
+ return scoped_ptr<VideoEncoderVpx>(new VideoEncoderVpx(false));
}
// static
-scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP9I420() {
- return scoped_ptr<VideoEncoderVpx>(
- new VideoEncoderVpx(base::Bind(&CreateVP9Codec, false),
- base::Bind(&CreateImage, false)));
+scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP9() {
+ return scoped_ptr<VideoEncoderVpx>(new VideoEncoderVpx(true));
}
-// static
-scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP9I444() {
- return scoped_ptr<VideoEncoderVpx>(
- new VideoEncoderVpx(base::Bind(&CreateVP9Codec, true),
- base::Bind(&CreateImage, true)));
+VideoEncoderVpx::~VideoEncoderVpx() {}
+
+void VideoEncoderVpx::SetLosslessEncode(bool want_lossless) {
+ if (use_vp9_ && (want_lossless != lossless_encode_)) {
+ lossless_encode_ = want_lossless;
+ codec_.reset(); // Force encoder re-initialization.
+ }
}
-VideoEncoderVpx::~VideoEncoderVpx() {}
+void VideoEncoderVpx::SetLosslessColor(bool want_lossless) {
+ if (use_vp9_ && (want_lossless != lossless_color_)) {
+ lossless_color_ = want_lossless;
+ codec_.reset(); // Force encoder re-initialization.
+ }
+}
scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
const webrtc::DesktopFrame& frame) {
@@ -312,19 +328,31 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
return packet.Pass();
}
-VideoEncoderVpx::VideoEncoderVpx(const CreateCodecCallback& create_codec,
- const CreateImageCallback& create_image)
- : create_codec_(create_codec),
- create_image_(create_image),
+VideoEncoderVpx::VideoEncoderVpx(bool use_vp9)
+ : use_vp9_(use_vp9),
+ lossless_encode_(false),
+ lossless_color_(false),
active_map_width_(0),
active_map_height_(0) {
+ if (use_vp9_) {
+ // Use lossless encoding mode by default.
+ SetLosslessEncode(true);
+
+ // Use I444 colour space, by default, if specified on the command-line.
+ if (CommandLine::ForCurrentProcess()->HasSwitch(kEnableI444SwitchName)) {
+ SetLosslessColor(true);
+ }
+ }
}
bool VideoEncoderVpx::Initialize(const webrtc::DesktopSize& size) {
+ DCHECK(use_vp9_ || !lossless_color_);
+ DCHECK(use_vp9_ || !lossless_encode_);
+
codec_.reset();
// (Re)Create the VPX image structure and pixel buffer.
- create_image_.Run(size, &image_, &image_buffer_);
+ CreateImage(lossless_color_, size, &image_, &image_buffer_);
// Initialize active map.
active_map_width_ = (image_->w + kMacroBlockSize - 1) / kMacroBlockSize;
@@ -332,7 +360,11 @@ bool VideoEncoderVpx::Initialize(const webrtc::DesktopSize& size) {
active_map_.reset(new uint8[active_map_width_ * active_map_height_]);
// (Re)Initialize the codec.
- codec_ = create_codec_.Run(size);
+ if (use_vp9_) {
+ codec_ = CreateVP9Codec(size, lossless_color_, lossless_encode_);
+ } else {
+ codec_ = CreateVP8Codec(size);
+ }
return codec_;
}