Chromium Code Reviews| Index: content/common/gpu/media/gpu_video_encode_accelerator.cc |
| diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc |
| index 12b473fcce23a5bd61f98c28a9b98d5e6419475e..5533873d98fac7fd0fc4a195cb0090d72fe9c5ad 100644 |
| --- a/content/common/gpu/media/gpu_video_encode_accelerator.cc |
| +++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc |
| @@ -22,6 +22,7 @@ |
| #if defined(ARCH_CPU_ARMEL) |
| #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" |
| #elif defined(ARCH_CPU_X86_FAMILY) |
| +#include "content/common/gpu/media/v4l2_video_encode_accelerator.h" |
| #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" |
| #include "ui/gfx/x/x11_types.h" |
| #endif |
| @@ -95,26 +96,33 @@ void GpuVideoEncodeAccelerator::Initialize( |
| return; |
| } |
| - encoder_ = CreateEncoder(); |
| - if (!encoder_) { |
| + std::vector<media::VideoEncodeAccelerator*> encoders = CreateEncoders(); |
| + if (encoders.empty()) { |
| DLOG(ERROR) |
| << "GpuVideoEncodeAccelerator::Initialize(): VEA creation failed"; |
| SendCreateEncoderReply(init_done_msg, false); |
| return; |
| } |
| - if (!encoder_->Initialize(input_format, |
| - input_visible_size, |
| - output_profile, |
| - initial_bitrate, |
| - this)) { |
| + for (size_t i = 0; i < encoders.size(); ++i) { |
|
Pawel Osciak
2014/12/28 23:28:03
Please add comments what's going on here.
henryhsu
2014/12/29 09:43:26
Done.
|
| + if (encoders[i]->Initialize(input_format, |
| + input_visible_size, |
| + output_profile, |
| + initial_bitrate, |
| + this)) { |
| + encoder_.reset(encoders[i]); |
|
Pawel Osciak
2014/12/28 23:28:03
We keep looping even if successful and overwrite t
henryhsu
2014/12/29 09:43:26
ok. let us keep the first successful encoder.
|
| + input_format_ = input_format; |
|
Pawel Osciak
2014/12/28 23:28:03
This could still stay outside of the loop.
henryhsu
2014/12/29 09:43:26
will return directly if initialization succeeded.
|
| + input_visible_size_ = input_visible_size; |
| + } else { |
| + encoders[i]->Destroy(); |
|
Pawel Osciak
2014/12/28 23:28:03
This assumes Destroy() deletes this, which it does
henryhsu
2014/12/29 09:43:26
back to scoped_ptr
|
| + } |
| + } |
| + if (!encoder_.get()) { |
| DLOG(ERROR) |
| << "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed"; |
| SendCreateEncoderReply(init_done_msg, false); |
| - return; |
| + } else { |
| + SendCreateEncoderReply(init_done_msg, true); |
| } |
| - input_format_ = input_format; |
| - input_visible_size_ = input_visible_size; |
| - SendCreateEncoderReply(init_done_msg, true); |
| } |
| bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { |
| @@ -165,12 +173,24 @@ void GpuVideoEncodeAccelerator::OnWillDestroyStub() { |
| // static |
| std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> |
| GpuVideoEncodeAccelerator::GetSupportedProfiles() { |
|
Pawel Osciak
2014/12/28 23:28:03
Can we keep the profile list for later in a single
henryhsu
2014/12/29 09:43:26
GetSupportedProfiels is only called one time when
|
| - scoped_ptr<media::VideoEncodeAccelerator> encoder = CreateEncoder(); |
| - if (!encoder) |
| + std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; |
| + std::vector<media::VideoEncodeAccelerator*> encoders = CreateEncoders(); |
|
Pawel Osciak
2014/12/28 23:28:03
Scopers please.
henryhsu
2014/12/29 09:43:26
SocopedVector doesn't support DefaultDeleter. I'll
|
| + if (encoders.empty()) |
| return std::vector<gpu::VideoEncodeAcceleratorSupportedProfile>(); |
| - return ConvertMediaToGpuProfiles(encoder->GetSupportedProfiles()); |
| + |
| + std::set<media::VideoEncodeAccelerator::SupportedProfile> profile_set; |
| + for (size_t i = 0; i < encoders.size(); ++i) { |
| + std::vector<media::VideoEncodeAccelerator::SupportedProfile> |
| + vea_profiles = encoders[i]->GetSupportedProfiles(); |
| + for (size_t j = 0; j < vea_profiles.size(); ++j) |
| + profile_set.insert(vea_profiles[j]); |
| + encoders[i]->Destroy(); |
|
Pawel Osciak
2014/12/28 23:28:03
Please don't depend on delete this in Destroy().
henryhsu
2014/12/29 09:43:26
Done.
|
| + } |
| + profiles.assign(profile_set.begin(), profile_set.end()); |
| + return ConvertMediaToGpuProfiles(profiles); |
| } |
| +// static |
| std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> |
| GpuVideoEncodeAccelerator::ConvertMediaToGpuProfiles(const std::vector< |
| media::VideoEncodeAccelerator::SupportedProfile>& media_profiles) { |
| @@ -188,23 +208,23 @@ GpuVideoEncodeAccelerator::ConvertMediaToGpuProfiles(const std::vector< |
| return profiles; |
| } |
| -scoped_ptr<media::VideoEncodeAccelerator> |
| -GpuVideoEncodeAccelerator::CreateEncoder() { |
| - scoped_ptr<media::VideoEncodeAccelerator> encoder; |
| +// static |
| +std::vector<media::VideoEncodeAccelerator*> |
| +GpuVideoEncodeAccelerator::CreateEncoders() { |
| + std::vector<media::VideoEncodeAccelerator*> encoders; |
| #if defined(OS_CHROMEOS) && defined(USE_X11) |
| -#if defined(ARCH_CPU_ARMEL) |
| scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); |
| if (device) |
| - encoder.reset(new V4L2VideoEncodeAccelerator(device.Pass())); |
| -#elif defined(ARCH_CPU_X86_FAMILY) |
| + encoders.push_back(new V4L2VideoEncodeAccelerator(device.Pass())); |
| +#if defined(ARCH_CPU_X86_FAMILY) |
| const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| if (!cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode)) |
| - encoder.reset(new VaapiVideoEncodeAccelerator(gfx::GetXDisplay())); |
| + encoders.push_back(new VaapiVideoEncodeAccelerator(gfx::GetXDisplay())); |
| #endif |
| #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) |
| - encoder.reset(new AndroidVideoEncodeAccelerator()); |
| + encoders.push_back(new AndroidVideoEncodeAccelerator()); |
| #endif |
| - return encoder.Pass(); |
| + return encoders; |
| } |
| void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id, |