| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/video_encoder_shim.h" | 5 #include "content/renderer/pepper/video_encoder_shim.h" |
| 6 | 6 |
| 7 #include <inttypes.h> | 7 #include <inttypes.h> |
| 8 | 8 |
| 9 #include <deque> | 9 #include <deque> |
| 10 | 10 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 int32_t* min_quantizer, | 67 int32_t* min_quantizer, |
| 68 int32_t* max_quantizer, | 68 int32_t* max_quantizer, |
| 69 int32_t* cpu_used) { | 69 int32_t* cpu_used) { |
| 70 switch (codec) { | 70 switch (codec) { |
| 71 case media::VP8PROFILE_ANY: | 71 case media::VP8PROFILE_ANY: |
| 72 *vpx_codec = vpx_codec_vp8_cx(); | 72 *vpx_codec = vpx_codec_vp8_cx(); |
| 73 *min_quantizer = kVp8DefaultMinQuantizer; | 73 *min_quantizer = kVp8DefaultMinQuantizer; |
| 74 *max_quantizer = kVp8DefaultMaxQuantizer; | 74 *max_quantizer = kVp8DefaultMaxQuantizer; |
| 75 *cpu_used = kVp8DefaultCpuUsed; | 75 *cpu_used = kVp8DefaultCpuUsed; |
| 76 break; | 76 break; |
| 77 case media::VP9PROFILE_ANY: | 77 // Only VP9 profile 0 is supported by PPAPI at the moment. VP9 profiles 1-3 |
| 78 // are not supported due to backward compatibility. |
| 79 case media::VP9PROFILE_PROFILE0: |
| 78 *vpx_codec = vpx_codec_vp9_cx(); | 80 *vpx_codec = vpx_codec_vp9_cx(); |
| 79 *min_quantizer = kVp9DefaultMinQuantizer; | 81 *min_quantizer = kVp9DefaultMinQuantizer; |
| 80 *max_quantizer = kVp9DefaultMaxQuantizer; | 82 *max_quantizer = kVp9DefaultMaxQuantizer; |
| 81 *cpu_used = kVp9DefaultCpuUsed; | 83 *cpu_used = kVp9DefaultCpuUsed; |
| 82 break; | 84 break; |
| 83 default: | 85 default: |
| 84 *vpx_codec = nullptr; | 86 *vpx_codec = nullptr; |
| 85 *min_quantizer = 0; | 87 *min_quantizer = 0; |
| 86 *max_quantizer = 0; | 88 *max_quantizer = 0; |
| 87 *cpu_used = 0; | 89 *cpu_used = 0; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 } | 160 } |
| 159 | 161 |
| 160 void VideoEncoderShim::EncoderImpl::Initialize( | 162 void VideoEncoderShim::EncoderImpl::Initialize( |
| 161 media::VideoPixelFormat input_format, | 163 media::VideoPixelFormat input_format, |
| 162 const gfx::Size& input_visible_size, | 164 const gfx::Size& input_visible_size, |
| 163 media::VideoCodecProfile output_profile, | 165 media::VideoCodecProfile output_profile, |
| 164 uint32_t initial_bitrate) { | 166 uint32_t initial_bitrate) { |
| 165 gfx::Size coded_size = | 167 gfx::Size coded_size = |
| 166 media::VideoFrame::PlaneSize(input_format, 0, input_visible_size); | 168 media::VideoFrame::PlaneSize(input_format, 0, input_visible_size); |
| 167 | 169 |
| 170 // Only VP9 profile 0 is supported by PPAPI at the moment. VP9 profiles 1-3 |
| 171 // are not supported due to backward compatibility. |
| 172 DCHECK_NE(output_profile, media::VP9PROFILE_PROFILE1); |
| 173 DCHECK_NE(output_profile, media::VP9PROFILE_PROFILE2); |
| 174 DCHECK_NE(output_profile, media::VP9PROFILE_PROFILE3); |
| 175 |
| 168 vpx_codec_iface_t* vpx_codec; | 176 vpx_codec_iface_t* vpx_codec; |
| 169 int32_t min_quantizer, max_quantizer, cpu_used; | 177 int32_t min_quantizer, max_quantizer, cpu_used; |
| 170 GetVpxCodecParameters(output_profile, &vpx_codec, &min_quantizer, | 178 GetVpxCodecParameters(output_profile, &vpx_codec, &min_quantizer, |
| 171 &max_quantizer, &cpu_used); | 179 &max_quantizer, &cpu_used); |
| 172 | 180 |
| 173 // Populate encoder configuration with default values. | 181 // Populate encoder configuration with default values. |
| 174 if (vpx_codec_enc_config_default(vpx_codec, &config_, 0) != VPX_CODEC_OK) { | 182 if (vpx_codec_enc_config_default(vpx_codec, &config_, 0) != VPX_CODEC_OK) { |
| 175 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 183 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 176 return; | 184 return; |
| 177 } | 185 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 189 config_.rc_max_quantizer = max_quantizer; | 197 config_.rc_max_quantizer = max_quantizer; |
| 190 // Do not saturate CPU utilization just for encoding. On a lower-end system | 198 // Do not saturate CPU utilization just for encoding. On a lower-end system |
| 191 // with only 1 or 2 cores, use only one thread for encoding. On systems with | 199 // with only 1 or 2 cores, use only one thread for encoding. On systems with |
| 192 // more cores, allow half of the cores to be used for encoding. | 200 // more cores, allow half of the cores to be used for encoding. |
| 193 config_.g_threads = | 201 config_.g_threads = |
| 194 std::min(kMaxNumThreads, (base::SysInfo::NumberOfProcessors() + 1) / 2); | 202 std::min(kMaxNumThreads, (base::SysInfo::NumberOfProcessors() + 1) / 2); |
| 195 | 203 |
| 196 // Use Q/CQ mode if no target bitrate is given. Note that in the VP8/CQ case | 204 // Use Q/CQ mode if no target bitrate is given. Note that in the VP8/CQ case |
| 197 // the meaning of rc_target_bitrate changes to target maximum rate. | 205 // the meaning of rc_target_bitrate changes to target maximum rate. |
| 198 if (initial_bitrate == 0) { | 206 if (initial_bitrate == 0) { |
| 199 if (output_profile == media::VP9PROFILE_ANY) { | 207 if (output_profile == media::VP9PROFILE_PROFILE0) { |
| 200 config_.rc_end_usage = VPX_Q; | 208 config_.rc_end_usage = VPX_Q; |
| 201 } else if (output_profile == media::VP8PROFILE_ANY) { | 209 } else if (output_profile == media::VP8PROFILE_ANY) { |
| 202 config_.rc_end_usage = VPX_CQ; | 210 config_.rc_end_usage = VPX_CQ; |
| 203 config_.rc_target_bitrate = kVp8MaxCQBitrate; | 211 config_.rc_target_bitrate = kVp8MaxCQBitrate; |
| 204 } | 212 } |
| 205 } | 213 } |
| 206 | 214 |
| 207 vpx_codec_flags_t flags = 0; | 215 vpx_codec_flags_t flags = 0; |
| 208 if (vpx_codec_enc_init(&encoder_, vpx_codec, &config_, flags) != | 216 if (vpx_codec_enc_init(&encoder_, vpx_codec, &config_, flags) != |
| 209 VPX_CODEC_OK) { | 217 VPX_CODEC_OK) { |
| 210 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 218 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 211 return; | 219 return; |
| 212 } | 220 } |
| 213 initialized_ = true; | 221 initialized_ = true; |
| 214 | 222 |
| 215 if (vpx_codec_enc_config_set(&encoder_, &config_) != VPX_CODEC_OK) { | 223 if (vpx_codec_enc_config_set(&encoder_, &config_) != VPX_CODEC_OK) { |
| 216 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 224 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 217 return; | 225 return; |
| 218 } | 226 } |
| 219 | 227 |
| 220 if (vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, cpu_used) != | 228 if (vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, cpu_used) != |
| 221 VPX_CODEC_OK) { | 229 VPX_CODEC_OK) { |
| 222 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 230 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 223 return; | 231 return; |
| 224 } | 232 } |
| 225 | 233 |
| 226 if (output_profile == media::VP9PROFILE_ANY) { | 234 if (output_profile == media::VP9PROFILE_PROFILE0) { |
| 227 if (vpx_codec_control(&encoder_, VP9E_SET_AQ_MODE, | 235 if (vpx_codec_control(&encoder_, VP9E_SET_AQ_MODE, |
| 228 kVp9AqModeCyclicRefresh) != VPX_CODEC_OK) { | 236 kVp9AqModeCyclicRefresh) != VPX_CODEC_OK) { |
| 229 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 237 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 230 return; | 238 return; |
| 231 } | 239 } |
| 232 } | 240 } |
| 233 | 241 |
| 234 renderer_task_runner_->PostTask( | 242 renderer_task_runner_->PostTask( |
| 235 FROM_HERE, | 243 FROM_HERE, |
| 236 base::Bind(&VideoEncoderShim::OnRequireBitstreamBuffers, shim_, | 244 base::Bind(&VideoEncoderShim::OnRequireBitstreamBuffers, shim_, |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 // Libvpx and media::VideoEncodeAccelerator are using opposite | 390 // Libvpx and media::VideoEncodeAccelerator are using opposite |
| 383 // notions of denominator/numerator. | 391 // notions of denominator/numerator. |
| 384 profile.max_framerate_numerator = config.g_timebase.den; | 392 profile.max_framerate_numerator = config.g_timebase.den; |
| 385 profile.max_framerate_denominator = config.g_timebase.num; | 393 profile.max_framerate_denominator = config.g_timebase.num; |
| 386 profiles.push_back(profile); | 394 profiles.push_back(profile); |
| 387 } | 395 } |
| 388 | 396 |
| 389 ret = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &config, 0); | 397 ret = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &config, 0); |
| 390 if (ret == VPX_CODEC_OK) { | 398 if (ret == VPX_CODEC_OK) { |
| 391 media::VideoEncodeAccelerator::SupportedProfile profile; | 399 media::VideoEncodeAccelerator::SupportedProfile profile; |
| 392 profile.profile = media::VP9PROFILE_ANY; | |
| 393 profile.max_resolution = gfx::Size(kMaxWidth, kMaxHeight); | 400 profile.max_resolution = gfx::Size(kMaxWidth, kMaxHeight); |
| 394 profile.max_framerate_numerator = config.g_timebase.den; | 401 profile.max_framerate_numerator = config.g_timebase.den; |
| 395 profile.max_framerate_denominator = config.g_timebase.num; | 402 profile.max_framerate_denominator = config.g_timebase.num; |
| 403 profile.profile = media::VP9PROFILE_PROFILE0; |
| 396 profiles.push_back(profile); | 404 profiles.push_back(profile); |
| 397 } | 405 } |
| 398 | 406 |
| 399 return profiles; | 407 return profiles; |
| 400 } | 408 } |
| 401 | 409 |
| 402 bool VideoEncoderShim::Initialize( | 410 bool VideoEncoderShim::Initialize( |
| 403 media::VideoPixelFormat input_format, | 411 media::VideoPixelFormat input_format, |
| 404 const gfx::Size& input_visible_size, | 412 const gfx::Size& input_visible_size, |
| 405 media::VideoCodecProfile output_profile, | 413 media::VideoCodecProfile output_profile, |
| 406 uint32_t initial_bitrate, | 414 uint32_t initial_bitrate, |
| 407 media::VideoEncodeAccelerator::Client* client) { | 415 media::VideoEncodeAccelerator::Client* client) { |
| 408 DCHECK(RenderThreadImpl::current()); | 416 DCHECK(RenderThreadImpl::current()); |
| 409 DCHECK_EQ(client, host_); | 417 DCHECK_EQ(client, host_); |
| 410 | 418 |
| 411 if (input_format != media::PIXEL_FORMAT_I420) | 419 if (input_format != media::PIXEL_FORMAT_I420) |
| 412 return false; | 420 return false; |
| 413 | 421 |
| 414 if (output_profile != media::VP8PROFILE_ANY && | 422 if (output_profile != media::VP8PROFILE_ANY && |
| 415 output_profile != media::VP9PROFILE_ANY) | 423 output_profile != media::VP9PROFILE_PROFILE0) |
| 416 return false; | 424 return false; |
| 417 | 425 |
| 418 media_task_runner_->PostTask( | 426 media_task_runner_->PostTask( |
| 419 FROM_HERE, | 427 FROM_HERE, |
| 420 base::Bind(&VideoEncoderShim::EncoderImpl::Initialize, | 428 base::Bind(&VideoEncoderShim::EncoderImpl::Initialize, |
| 421 base::Unretained(encoder_impl_.get()), input_format, | 429 base::Unretained(encoder_impl_.get()), input_format, |
| 422 input_visible_size, output_profile, initial_bitrate)); | 430 input_visible_size, output_profile, initial_bitrate)); |
| 423 | 431 |
| 424 return true; | 432 return true; |
| 425 } | 433 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 } | 491 } |
| 484 | 492 |
| 485 void VideoEncoderShim::OnNotifyError( | 493 void VideoEncoderShim::OnNotifyError( |
| 486 media::VideoEncodeAccelerator::Error error) { | 494 media::VideoEncodeAccelerator::Error error) { |
| 487 DCHECK(RenderThreadImpl::current()); | 495 DCHECK(RenderThreadImpl::current()); |
| 488 | 496 |
| 489 host_->NotifyError(error); | 497 host_->NotifyError(error); |
| 490 } | 498 } |
| 491 | 499 |
| 492 } // namespace content | 500 } // namespace content |
| OLD | NEW |