Chromium Code Reviews| Index: content/renderer/pepper/video_encoder_shim.cc |
| diff --git a/content/renderer/pepper/video_encoder_shim.cc b/content/renderer/pepper/video_encoder_shim.cc |
| index d28744fd76fdced6433c43cea3315bb3aacaaf20..e4c0c95179beac46a7eaacde4089061b307ecf12 100644 |
| --- a/content/renderer/pepper/video_encoder_shim.cc |
| +++ b/content/renderer/pepper/video_encoder_shim.cc |
| @@ -30,20 +30,67 @@ namespace content { |
| const int32_t kMaxWidth = 1920; |
| const int32_t kMaxHeight = 1088; |
| -// Default speed for the encoder (same as WebRTC). Increases the CPU |
| -// usage as the value is more negative (VP8 valid range: -16..16). |
| -const int32_t kDefaultCpuUsed = -6; |
| - |
| -// Default quantizer min/max values. |
| -const int32_t kDefaultMinQuantizer = 2; |
| -const int32_t kDefaultMaxQuantizer = 52; |
| - |
| // Bitstream buffer size. |
| const uint32_t kBitstreamBufferSize = 2 * 1024 * 1024; |
| // Number of frames needs at any given time. |
| const uint32_t kInputFrameCount = 1; |
| +// Magic encoder constants for VP9 adaptive quantization strategy. |
|
bbudge
2015/08/05 17:04:41
nit: s/constants/constant
Or do you want to move m
llandwerlin-old
2015/08/05 17:35:55
Done.
|
| +const int kVp9AqModeCyclicRefresh = 3; |
| + |
| +namespace { |
| + |
| +struct CodecDescription { |
|
bbudge
2015/08/05 17:04:41
This class just holds parameter values, and some s
llandwerlin-old
2015/08/05 17:35:55
Replaced with a function that does the switch on r
|
| + CodecDescription() |
| + : codec(media::VIDEO_CODEC_PROFILE_UNKNOWN), |
| + vpx_codec(nullptr), |
| + cpu_used(0), |
| + min_quantizer(0), |
| + max_quantizer(0) {} |
| + CodecDescription(media::VideoCodecProfile codec, |
| + vpx_codec_iface_t* vpx_codec, |
| + int32_t cpu_used, |
| + uint32_t min_quantizer, |
| + uint32_t max_quantizer) |
| + : codec(codec), |
| + vpx_codec(vpx_codec), |
| + cpu_used(cpu_used), |
| + min_quantizer(min_quantizer), |
| + max_quantizer(max_quantizer) {} |
| + ~CodecDescription() {} |
| + |
| + bool IsValid() { return vpx_codec != nullptr; } |
| + |
| + media::VideoCodecProfile codec; |
| + |
| + // Libvpx codec interface. |
| + vpx_codec_iface_t* vpx_codec; |
| + |
| + // Default speed for the encoder. Increases the CPU usage as the |
| + // value is more negative (VP8 valid range: -16..16, VP9 valid |
| + // range: -8..8). |
| + int32_t cpu_used; |
| + |
| + // Default quantizer min/max values. |
| + uint32_t min_quantizer; |
| + uint32_t max_quantizer; |
| +}; |
| + |
| +CodecDescription PP_ToVpxVideoCodecIface(media::VideoCodecProfile codec) { |
| + switch (codec) { |
| + case media::VP8PROFILE_ANY: |
| + // Using same parameters as WebRTC (see media/cast/sender). |
| + return CodecDescription(codec, vpx_codec_vp8_cx(), -6, 2, 52); |
| + case media::VP9PROFILE_ANY: |
| + return CodecDescription(codec, vpx_codec_vp9_cx(), 6, 20, 30); |
| + default: |
| + return CodecDescription(); |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| class VideoEncoderShim::EncoderImpl { |
| public: |
| explicit EncoderImpl(const base::WeakPtr<VideoEncoderShim>& shim); |
| @@ -51,7 +98,7 @@ class VideoEncoderShim::EncoderImpl { |
| void Initialize(media::VideoPixelFormat input_format, |
| const gfx::Size& input_visible_size, |
| - media::VideoCodecProfile output_profile, |
| + const CodecDescription& codec_descr, |
| uint32 initial_bitrate); |
| void Encode(const scoped_refptr<media::VideoFrame>& frame, |
| bool force_keyframe); |
| @@ -113,19 +160,18 @@ VideoEncoderShim::EncoderImpl::~EncoderImpl() { |
| void VideoEncoderShim::EncoderImpl::Initialize( |
| media::VideoPixelFormat input_format, |
| const gfx::Size& input_visible_size, |
| - media::VideoCodecProfile output_profile, |
| + const CodecDescription& codec_descr, |
|
bbudge
2015/08/05 17:04:41
nit: desc is a more common abbreviation for descri
llandwerlin-old
2015/08/05 17:35:55
Done.
|
| uint32 initial_bitrate) { |
| gfx::Size coded_size = |
| media::VideoFrame::PlaneSize(input_format, 0, input_visible_size); |
| // Populate encoder configuration with default values. |
| - if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config_, 0) != |
| + if (vpx_codec_enc_config_default(codec_descr.vpx_codec, &config_, 0) != |
| VPX_CODEC_OK) { |
| NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| return; |
| } |
| - config_.g_threads = 1; |
| config_.g_w = input_visible_size.width(); |
| config_.g_h = input_visible_size.height(); |
| @@ -135,11 +181,11 @@ void VideoEncoderShim::EncoderImpl::Initialize( |
| config_.g_timebase.num = 1; |
| config_.g_timebase.den = base::Time::kMicrosecondsPerSecond; |
| config_.rc_target_bitrate = initial_bitrate / 1000; |
| - config_.rc_min_quantizer = kDefaultMinQuantizer; |
| - config_.rc_max_quantizer = kDefaultMaxQuantizer; |
| + config_.rc_min_quantizer = codec_descr.min_quantizer; |
| + config_.rc_max_quantizer = codec_descr.max_quantizer; |
| vpx_codec_flags_t flags = 0; |
| - if (vpx_codec_enc_init(&encoder_, vpx_codec_vp8_cx(), &config_, flags) != |
| + if (vpx_codec_enc_init(&encoder_, codec_descr.vpx_codec, &config_, flags) != |
| VPX_CODEC_OK) { |
| NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| return; |
| @@ -151,12 +197,20 @@ void VideoEncoderShim::EncoderImpl::Initialize( |
| return; |
| } |
| - if (vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, kDefaultCpuUsed) != |
| + if (vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, codec_descr.cpu_used) != |
| VPX_CODEC_OK) { |
| NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| return; |
| } |
| + if (codec_descr.codec == media::VP9PROFILE_ANY) { |
| + if (vpx_codec_control(&encoder_, VP9E_SET_AQ_MODE, |
| + kVp9AqModeCyclicRefresh) != VPX_CODEC_OK) { |
| + NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| + return; |
| + } |
| + } |
| + |
| renderer_task_runner_->PostTask( |
| FROM_HERE, |
| base::Bind(&VideoEncoderShim::OnRequireBitstreamBuffers, shim_, |
| @@ -312,6 +366,16 @@ VideoEncoderShim::GetSupportedProfiles() { |
| profiles.push_back(profile); |
| } |
| + ret = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &config, 0); |
| + if (ret == VPX_CODEC_OK) { |
| + media::VideoEncodeAccelerator::SupportedProfile profile; |
| + profile.profile = media::VP9PROFILE_ANY; |
| + profile.max_resolution = gfx::Size(kMaxWidth, kMaxHeight); |
| + profile.max_framerate_numerator = config.g_timebase.den; |
| + profile.max_framerate_denominator = config.g_timebase.num; |
| + profiles.push_back(profile); |
| + } |
| + |
| return profiles; |
| } |
| @@ -327,11 +391,14 @@ bool VideoEncoderShim::Initialize( |
| if (input_format != media::PIXEL_FORMAT_I420) |
| return false; |
| + CodecDescription codec_desc = PP_ToVpxVideoCodecIface(output_profile); |
| + if (!codec_desc.IsValid()) |
| + return false; |
| + |
| media_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoEncoderShim::EncoderImpl::Initialize, |
| - base::Unretained(encoder_impl_.get()), input_format, |
| - input_visible_size, output_profile, initial_bitrate)); |
| + FROM_HERE, base::Bind(&VideoEncoderShim::EncoderImpl::Initialize, |
| + base::Unretained(encoder_impl_.get()), input_format, |
| + input_visible_size, codec_desc, initial_bitrate)); |
| return true; |
| } |