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 |