Chromium Code Reviews| Index: content/renderer/media/video_track_recorder.cc |
| diff --git a/content/renderer/media/video_track_recorder.cc b/content/renderer/media/video_track_recorder.cc |
| index 011c633e3d1e90f8db0bf692b6185ad8c67ff4b1..eebcb327fb34d68d82a3b932f459f486c6495947 100644 |
| --- a/content/renderer/media/video_track_recorder.cc |
| +++ b/content/renderer/media/video_track_recorder.cc |
| @@ -60,60 +60,98 @@ const int kVEADefaultBitratePerPixel = 2; |
| // encoders. |
| const int kVEAEncoderOutputBufferCount = 4; |
| -static struct { |
| - VideoTrackRecorder::CodecId codec_id; |
| - media::VideoCodecProfile min_profile; |
| - media::VideoCodecProfile max_profile; |
| -} const kSupportedVideoCodecIdToProfile[] = { |
| - {VideoTrackRecorder::CodecId::VP8, |
| - media::VP8PROFILE_MIN, |
| - media::VP8PROFILE_MAX}, |
| - {VideoTrackRecorder::CodecId::VP9, |
| - media::VP9PROFILE_MIN, |
| - media::VP9PROFILE_MAX}, |
| - {VideoTrackRecorder::CodecId::H264, |
| - media::H264PROFILE_MIN, |
| - media::H264PROFILE_MAX}}; |
| - |
| -// Returns the corresponding codec profile from VEA supported codecs. If no |
| -// profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN. |
| -media::VideoCodecProfile CodecIdToVEAProfile( |
| - content::VideoTrackRecorder::CodecId codec) { |
| - // See https://crbug.com/616659. |
| +using CodecId = VideoTrackRecorder::CodecId; |
| + |
| +// Class to encapsulate the enumeration of CodecIds/VideoCodecProfiles supported |
| +// by the VEA underlying platform. Provides methods to query the preferred |
| +// CodecId and to check if a given CodecId is supported. |
| +class CodecEnumerator { |
| + public: |
| + CodecEnumerator(); |
| + ~CodecEnumerator() = default; |
| + |
| + // Get the first CodecId that has an associated VEA VideoCodecProfile, or VP8. |
| + CodecId GetPreferredCodecId(); |
| + |
| + // Returns the VEA VideoCodedProfile for a given CodecId, if supported, or |
| + // VIDEO_CODEC_PROFILE_UNKNOWN otherwise. |
| + media::VideoCodecProfile CodecIdToVEAProfile(CodecId codec); |
| + |
| + private: |
| + static const struct CodecIdAndVEAProfile { |
| + CodecId codec_id; |
| + media::VideoCodecProfile min_profile; |
| + media::VideoCodecProfile max_profile; |
| + } constexpr kCodecIdAndVEAProfiles[] = { |
| + {CodecId::VP8, media::VP8PROFILE_MIN, media::VP8PROFILE_MAX}, |
| + {CodecId::VP9, media::VP9PROFILE_MIN, media::VP9PROFILE_MAX}, |
| + {CodecId::H264, media::H264PROFILE_MIN, media::H264PROFILE_MAX}}; |
| + |
| + // A map of VEA-supported CodecId-and-VEA-profile pairs. |
| + std::map<CodecId, media::VideoCodecProfile> codec_id_to_profile_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(CodecEnumerator); |
| +}; |
| + |
| +constexpr CodecEnumerator::CodecIdAndVEAProfile |
| + CodecEnumerator::kCodecIdAndVEAProfiles[]; |
| + |
| +static base::LazyInstance<CodecEnumerator>::Leaky g_codec_enumerator = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| +CodecEnumerator::CodecEnumerator() { |
| + static_assert( |
| + arraysize(kCodecIdAndVEAProfiles) == static_cast<int>(CodecId::LAST), |
| + "|kCodecIdAndVEAProfiles| should consider all CodecIds"); |
| #if defined(OS_CHROMEOS) |
| - return media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| -#endif // defined(OS_CHROMEOS) |
| + // See https://crbug.com/616659. |
| + return; |
| +#endif |
| -// See https://crbug.com/653864. |
| #if defined(OS_ANDROID) |
| - return media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| -#endif // defined(OS_ANDROID) |
| + // See https://crbug.com/653864. |
| + return; |
| +#endif |
| content::RenderThreadImpl* const render_thread_impl = |
| content::RenderThreadImpl::current(); |
| if (!render_thread_impl) { |
| - DVLOG(3) << "Couldn't access the render thread"; |
| - return media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| + DVLOG(2) << "Couldn't access the render thread"; |
| + return; |
| } |
| media::GpuVideoAcceleratorFactories* const gpu_factories = |
| render_thread_impl->GetGpuFactories(); |
| if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { |
| - DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories"; |
| - return media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| + DVLOG(2) << "Couldn't initialize GpuVideoAcceleratorFactories"; |
| + return; |
| } |
| const media::VideoEncodeAccelerator::SupportedProfiles& vea_profiles = |
| gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles(); |
| for (const auto& vea_profile : vea_profiles) { |
| - for (const auto& supported_profile : kSupportedVideoCodecIdToProfile) { |
| - if (codec == supported_profile.codec_id && |
| - vea_profile.profile >= supported_profile.min_profile && |
| - vea_profile.profile <= supported_profile.max_profile) |
| - return vea_profile.profile; |
| + for (auto& codec_id_and_profile : kCodecIdAndVEAProfiles) { |
| + if (vea_profile.profile >= codec_id_and_profile.min_profile && |
| + vea_profile.profile <= codec_id_and_profile.max_profile) { |
| + DVLOG(2) << media::GetProfileName(vea_profile.profile) << " supported"; |
| + codec_id_to_profile_.emplace( |
| + std::make_pair(codec_id_and_profile.codec_id, vea_profile.profile)); |
|
emircan
2017/01/11 22:11:05
codec_id_to_profile_.emplace(codec_id_and_profile.
emircan
2017/01/11 22:11:05
Note that this would take the min profile if there
mcasas
2017/01/11 22:30:16
Done.
mcasas
2017/01/11 22:30:16
Gotcha. That's ok for the time being.
We'll be kee
mcasas
2017/01/12 00:20:54
Some bots were unhappy, see e.g. linux_chromium_co
|
| + } |
| } |
| } |
| - return media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| +} |
| + |
| +CodecId CodecEnumerator::GetPreferredCodecId() { |
| + if (codec_id_to_profile_.empty()) |
| + return CodecId::VP8; |
| + return codec_id_to_profile_.begin()->first; |
| +} |
| + |
| +media::VideoCodecProfile CodecEnumerator::CodecIdToVEAProfile(CodecId codec) { |
| + const auto profile = codec_id_to_profile_.find(codec); |
| + return profile == codec_id_to_profile_.end() |
| + ? media::VIDEO_CODEC_PROFILE_UNKNOWN |
| + : profile->second; |
| } |
| } // anonymous namespace |
| @@ -1075,6 +1113,11 @@ void H264Encoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { |
| } // anonymous namespace |
| +// static |
| +VideoTrackRecorder::CodecId VideoTrackRecorder::GetPreferredCodecId() { |
| + return g_codec_enumerator.Get().GetPreferredCodecId(); |
| +} |
| + |
| VideoTrackRecorder::VideoTrackRecorder( |
| CodecId codec, |
| const blink::WebMediaStreamTrack& track, |
| @@ -1143,7 +1186,8 @@ void VideoTrackRecorder::InitializeEncoder( |
| MediaStreamVideoSink::DisconnectFromTrack(); |
| const gfx::Size& input_size = frame->visible_rect().size(); |
| - const auto& vea_supported_profile = CodecIdToVEAProfile(codec); |
| + const auto& vea_supported_profile = |
| + g_codec_enumerator.Get().CodecIdToVEAProfile(codec); |
| if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN && |
| input_size.width() >= kVEAEncoderMinResolutionWidth && |
| input_size.height() >= kVEAEncoderMinResolutionHeight) { |
| @@ -1162,7 +1206,7 @@ void VideoTrackRecorder::InitializeEncoder( |
| encoder_ = new VpxEncoder(codec == CodecId::VP9, |
| on_encoded_video_callback, bits_per_second); |
| break; |
| - default: |
| + case CodecId::LAST: |
| NOTREACHED() << "Unsupported codec"; |
| } |
| } |