Chromium Code Reviews| Index: content/renderer/media/rtc_video_encoder_factory.cc |
| diff --git a/content/renderer/media/rtc_video_encoder_factory.cc b/content/renderer/media/rtc_video_encoder_factory.cc |
| index ec92f5572f9bd7c1877985cd1e1f3f073186e7f0..880ca843b4c78a76ff2462e13d79fae4b7e3caac 100644 |
| --- a/content/renderer/media/rtc_video_encoder_factory.cc |
| +++ b/content/renderer/media/rtc_video_encoder_factory.cc |
| @@ -4,43 +4,53 @@ |
| #include "content/renderer/media/rtc_video_encoder_factory.h" |
| +#include "base/bind.h" |
| #include "base/command_line.h" |
| +#include "base/location.h" |
| +#include "base/message_loop/message_loop_proxy.h" |
| +#include "base/synchronization/waitable_event.h" |
| #include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" |
| #include "content/public/common/content_switches.h" |
| +#include "content/public/renderer/video_encode_accelerator.h" |
| #include "content/renderer/media/rtc_video_encoder.h" |
| #include "media/filters/gpu_video_accelerator_factories.h" |
| -#include "media/video/video_encode_accelerator.h" |
| namespace content { |
| -namespace { |
| - |
| // Translate from media::VideoEncodeAccelerator::SupportedProfile to |
| // one or more instances of cricket::WebRtcVideoEncoderFactory::VideoCodec |
| -void VEAToWebRTCCodecs( |
| - std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>* codecs, |
| - const media::VideoEncodeAccelerator::SupportedProfile& profile) { |
| - int width = profile.max_resolution.width(); |
| - int height = profile.max_resolution.height(); |
| - int fps = profile.max_framerate.numerator; |
| - DCHECK_EQ(profile.max_framerate.denominator, 1U); |
| - |
| - const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| - if (profile.profile >= media::VP8PROFILE_MIN && |
| - profile.profile <= media::VP8PROFILE_MAX) { |
| - if (cmd_line->HasSwitch(switches::kEnableWebRtcHWVp8Encoding)) { |
| - codecs->push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( |
| - webrtc::kVideoCodecVP8, "VP8", width, height, fps)); |
| - } |
| - } else if (profile.profile >= media::H264PROFILE_MIN && |
| - profile.profile <= media::H264PROFILE_MAX) { |
| - if (cmd_line->HasSwitch(switches::kEnableWebRtcHWH264Encoding)) { |
| - codecs->push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( |
| - webrtc::kVideoCodecH264, "H264", width, height, fps)); |
| +void RTCVideoEncoderFactory::VEAToWebRTCCodecs(const std::vector< |
| + media::VideoEncodeAccelerator::SupportedProfile>& profiles) { |
| + for (size_t i = 0; i < profiles.size(); i++) { |
| + const media::VideoEncodeAccelerator::SupportedProfile& profile = |
| + profiles[i]; |
| + int width = profile.max_resolution.width(); |
| + int height = profile.max_resolution.height(); |
| + int fps = profile.max_framerate_numerator; |
| + DCHECK_EQ(profile.max_framerate_denominator, 1U); |
| + |
| + const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| + if (profile.profile >= media::VP8PROFILE_MIN && |
| + profile.profile <= media::VP8PROFILE_MAX) { |
| + if (cmd_line->HasSwitch(switches::kEnableWebRtcHWVp8Encoding)) { |
| + codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( |
| + webrtc::kVideoCodecVP8, "VP8", width, height, fps)); |
| + } |
| + } else if (profile.profile >= media::H264PROFILE_MIN && |
| + profile.profile <= media::H264PROFILE_MAX) { |
| + if (cmd_line->HasSwitch(switches::kEnableWebRtcHWH264Encoding)) { |
| + codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( |
| + webrtc::kVideoCodecH264, "H264", width, height, fps)); |
| + } |
| + // TODO(hshi): remove the generic codec type after CASTv1 deprecation. |
| + codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( |
| + webrtc::kVideoCodecGeneric, "CAST1", width, height, fps)); |
| } |
| - // TODO(hshi): remove the generic codec type after CASTv1 deprecation. |
| - codecs->push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( |
| - webrtc::kVideoCodecGeneric, "CAST1", width, height, fps)); |
| + } |
| + for (std::list<Observer*>::iterator it = observers_.begin(); |
| + it != observers_.end(); |
| + it++) { |
|
kcwu
2014/09/19 11:15:54
++it
|
| + (*it)->OnCodecsAvailable(); |
| } |
| } |
| @@ -59,19 +69,23 @@ media::VideoCodecProfile WebRTCCodecToVideoCodecProfile( |
| } |
| } |
| -} // anonymous namespace |
| - |
| RTCVideoEncoderFactory::RTCVideoEncoderFactory( |
| const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories) |
| - : gpu_factories_(gpu_factories) { |
| - // Query media::VideoEncodeAccelerator (statically) for our supported codecs. |
| - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles = |
| - GpuVideoEncodeAcceleratorHost::GetSupportedProfiles(); |
| - for (size_t i = 0; i < profiles.size(); ++i) |
| - VEAToWebRTCCodecs(&codecs_, profiles[i]); |
| + : gpu_factories_(gpu_factories), |
| + get_supported_profiles_waiter_(true, false), |
| + weak_factory_(this) { |
| + // Query media::VideoEncodeAccelerator for our supported codecs. |
| + gpu_factories_->GetTaskRunner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&RTCVideoEncoderFactory::GetSupportedCodecs, |
| + base::Unretained(this), |
|
wuchengli
2014/09/19 14:27:24
The constructor and destructor run on the child th
|
| + base::MessageLoopProxy::current())); |
| } |
| -RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {} |
| +RTCVideoEncoderFactory::~RTCVideoEncoderFactory() { |
| + weak_factory_.InvalidateWeakPtrs(); |
|
wuchengli
2014/09/19 14:27:24
Invalidate the weak pointer in case the codecs_ ha
|
| + get_supported_profiles_waiter_.Wait(); |
| +} |
| webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder( |
| webrtc::VideoCodecType type) { |
| @@ -89,10 +103,12 @@ webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder( |
| } |
| void RTCVideoEncoderFactory::AddObserver(Observer* observer) { |
| - // No-op: our codec list is populated on installation. |
| + observers_.push_back(observer); |
| } |
| -void RTCVideoEncoderFactory::RemoveObserver(Observer* observer) {} |
| +void RTCVideoEncoderFactory::RemoveObserver(Observer* observer) { |
| + observers_.remove(observer); |
| +} |
| const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>& |
| RTCVideoEncoderFactory::codecs() const { |
| @@ -104,4 +120,19 @@ void RTCVideoEncoderFactory::DestroyVideoEncoder( |
| delete encoder; |
| } |
| +void RTCVideoEncoderFactory::GetSupportedCodecs( |
| + const scoped_refptr<base::MessageLoopProxy>& message_loop) { |
| + std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; |
| + scoped_ptr<media::VideoEncodeAccelerator> video_encoder = |
| + gpu_factories_->CreateVideoEncodeAccelerator(); |
| + if (video_encoder) |
| + profiles = video_encoder->GetSupportedProfiles(); |
| + video_encoder.reset(); |
| + message_loop->PostTask(FROM_HERE, |
| + base::Bind(&RTCVideoEncoderFactory::VEAToWebRTCCodecs, |
| + weak_factory_.GetWeakPtr(), |
| + profiles)); |
| + get_supported_profiles_waiter_.Signal(); |
| +} |
| + |
| } // namespace content |