| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <array> |
| 8 #include <utility> | 9 #include <utility> |
| 9 | 10 |
| 10 #include "base/bind.h" | 11 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 13 #include "base/cpu.h" | 14 #include "base/cpu.h" |
| 14 #include "base/location.h" | 15 #include "base/location.h" |
| 15 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 18 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 19 #include "base/task_runner_util.h" | 20 #include "base/task_runner_util.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" | 21 #include "base/threading/thread_task_runner_handle.h" |
| 21 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 22 #include "gpu/command_buffer/common/mailbox_holder.h" | 23 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 23 #include "media/base/bind_to_current_loop.h" | 24 #include "media/base/bind_to_current_loop.h" |
| 24 #include "media/base/cdm_context.h" | 25 #include "media/base/cdm_context.h" |
| 25 #include "media/base/decoder_buffer.h" | 26 #include "media/base/decoder_buffer.h" |
| 26 #include "media/base/media_log.h" | 27 #include "media/base/media_log.h" |
| 27 #include "media/base/media_switches.h" | 28 #include "media/base/media_switches.h" |
| 28 #include "media/base/pipeline_status.h" | 29 #include "media/base/pipeline_status.h" |
| 29 #include "media/base/surface_manager.h" | 30 #include "media/base/surface_manager.h" |
| 30 #include "media/base/video_decoder_config.h" | 31 #include "media/base/video_decoder_config.h" |
| 31 #include "media/renderers/gpu_video_accelerator_factories.h" | 32 #include "media/renderers/gpu_video_accelerator_factories.h" |
| 32 #include "third_party/skia/include/core/SkBitmap.h" | 33 #include "third_party/skia/include/core/SkBitmap.h" |
| 33 | 34 |
| 35 #if defined(USE_PROPRIETARY_CODECS) |
| 36 #include "media/formats/mp4/box_definitions.h" |
| 37 #endif |
| 38 |
| 34 namespace media { | 39 namespace media { |
| 40 namespace { |
| 41 |
| 42 // Size of shared-memory segments we allocate. Since we reuse them we let them |
| 43 // be on the beefy side. |
| 44 static const size_t kSharedMemorySegmentBytes = 100 << 10; |
| 45 |
| 46 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
| 47 // Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed |
| 48 // with 0x0001, the Annex B framing bytes. The out parameters are not modified |
| 49 // on failure. |
| 50 void ExtractSpsAndPps(const std::vector<uint8_t>& extra_data, |
| 51 std::vector<uint8_t>* sps_out, |
| 52 std::vector<uint8_t>* pps_out) { |
| 53 mp4::AVCDecoderConfigurationRecord record; |
| 54 if (!record.Parse(extra_data.data(), extra_data.size())) { |
| 55 DVLOG(1) << "Failed to extract the SPS and PPS from extra_data"; |
| 56 return; |
| 57 } |
| 58 |
| 59 constexpr std::array<uint8_t, 4> prefix = {{0, 0, 0, 1}}; |
| 60 for (const std::vector<uint8_t>& sps : record.sps_list) { |
| 61 sps_out->insert(sps_out->end(), prefix.begin(), prefix.end()); |
| 62 sps_out->insert(sps_out->end(), sps.begin(), sps.end()); |
| 63 } |
| 64 |
| 65 for (const std::vector<uint8_t>& pps : record.pps_list) { |
| 66 pps_out->insert(pps_out->end(), prefix.begin(), prefix.end()); |
| 67 pps_out->insert(pps_out->end(), pps.begin(), pps.end()); |
| 68 } |
| 69 } |
| 70 #endif |
| 71 |
| 72 } // namespace |
| 35 | 73 |
| 36 const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder"; | 74 const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder"; |
| 37 | 75 |
| 38 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. | 76 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. |
| 39 // Higher values allow better pipelining in the GPU, but also require more | 77 // Higher values allow better pipelining in the GPU, but also require more |
| 40 // resources. | 78 // resources. |
| 41 enum { kMaxInFlightDecodes = 4 }; | 79 enum { kMaxInFlightDecodes = 4 }; |
| 42 | 80 |
| 43 // Size of shared-memory segments we allocate. Since we reuse them we let them | |
| 44 // be on the beefy side. | |
| 45 static const size_t kSharedMemorySegmentBytes = 100 << 10; | |
| 46 | |
| 47 GpuVideoDecoder::SHMBuffer::SHMBuffer(std::unique_ptr<base::SharedMemory> m, | 81 GpuVideoDecoder::SHMBuffer::SHMBuffer(std::unique_ptr<base::SharedMemory> m, |
| 48 size_t s) | 82 size_t s) |
| 49 : shm(std::move(m)), size(s) {} | 83 : shm(std::move(m)), size(s) {} |
| 50 | 84 |
| 51 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} | 85 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} |
| 52 | 86 |
| 53 GpuVideoDecoder::PendingDecoderBuffer::PendingDecoderBuffer( | 87 GpuVideoDecoder::PendingDecoderBuffer::PendingDecoderBuffer( |
| 54 SHMBuffer* s, | 88 SHMBuffer* s, |
| 55 const scoped_refptr<DecoderBuffer>& b, | 89 const scoped_refptr<DecoderBuffer>& b, |
| 56 const DecodeCB& done_cb) | 90 const DecodeCB& done_cb) |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 return; | 326 return; |
| 293 } | 327 } |
| 294 | 328 |
| 295 VideoDecodeAccelerator::Config vda_config; | 329 VideoDecodeAccelerator::Config vda_config; |
| 296 vda_config.profile = config_.profile(); | 330 vda_config.profile = config_.profile(); |
| 297 vda_config.cdm_id = cdm_id; | 331 vda_config.cdm_id = cdm_id; |
| 298 vda_config.is_encrypted = config_.is_encrypted(); | 332 vda_config.is_encrypted = config_.is_encrypted(); |
| 299 vda_config.surface_id = surface_id; | 333 vda_config.surface_id = surface_id; |
| 300 vda_config.is_deferred_initialization_allowed = true; | 334 vda_config.is_deferred_initialization_allowed = true; |
| 301 vda_config.initial_expected_coded_size = config_.coded_size(); | 335 vda_config.initial_expected_coded_size = config_.coded_size(); |
| 336 |
| 337 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
| 338 // We pass the SPS and PPS on Android because it lets us initialize |
| 339 // MediaCodec more reliably (http://crbug.com/649185). |
| 340 if (config_.codec() == kCodecH264) |
| 341 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); |
| 342 #endif |
| 343 |
| 302 if (!vda_->Initialize(vda_config, this)) { | 344 if (!vda_->Initialize(vda_config, this)) { |
| 303 DVLOG(1) << "VDA::Initialize failed."; | 345 DVLOG(1) << "VDA::Initialize failed."; |
| 304 base::ResetAndReturn(&init_cb_).Run(false); | 346 base::ResetAndReturn(&init_cb_).Run(false); |
| 305 return; | 347 return; |
| 306 } | 348 } |
| 307 | 349 |
| 308 // If deferred initialization is not supported, initialization is complete. | 350 // If deferred initialization is not supported, initialization is complete. |
| 309 // Otherwise, a call to NotifyInitializationComplete will follow with the | 351 // Otherwise, a call to NotifyInitializationComplete will follow with the |
| 310 // result of deferred initialization. | 352 // result of deferred initialization. |
| 311 if (!supports_deferred_initialization_) | 353 if (!supports_deferred_initialization_) |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 } | 870 } |
| 829 return false; | 871 return false; |
| 830 } | 872 } |
| 831 | 873 |
| 832 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 874 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
| 833 const { | 875 const { |
| 834 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 876 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 835 } | 877 } |
| 836 | 878 |
| 837 } // namespace media | 879 } // namespace media |
| OLD | NEW |