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 <array> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... | |
29 #include "media/base/pipeline_status.h" | 29 #include "media/base/pipeline_status.h" |
30 #include "media/base/surface_manager.h" | 30 #include "media/base/surface_manager.h" |
31 #include "media/base/video_decoder_config.h" | 31 #include "media/base/video_decoder_config.h" |
32 #include "media/renderers/gpu_video_accelerator_factories.h" | 32 #include "media/renderers/gpu_video_accelerator_factories.h" |
33 #include "third_party/skia/include/core/SkBitmap.h" | 33 #include "third_party/skia/include/core/SkBitmap.h" |
34 | 34 |
35 #if defined(USE_PROPRIETARY_CODECS) | 35 #if defined(USE_PROPRIETARY_CODECS) |
36 #include "media/formats/mp4/box_definitions.h" | 36 #include "media/formats/mp4/box_definitions.h" |
37 #endif | 37 #endif |
38 | 38 |
39 #if defined(OS_ANDROID) | |
40 #include "base/android/build_info.h" | |
41 #endif | |
42 | |
39 namespace media { | 43 namespace media { |
40 namespace { | 44 namespace { |
41 | 45 |
42 // Size of shared-memory segments we allocate. Since we reuse them we let them | 46 // Size of shared-memory segments we allocate. Since we reuse them we let them |
43 // be on the beefy side. | 47 // be on the beefy side. |
44 static const size_t kSharedMemorySegmentBytes = 100 << 10; | 48 static const size_t kSharedMemorySegmentBytes = 100 << 10; |
45 | 49 |
46 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) | 50 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
47 // Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed | 51 // 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 | 52 // with 0x0001, the Annex B framing bytes. The out parameters are not modified |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 media_log_(media_log), | 123 media_log_(media_log), |
120 state_(kNormal), | 124 state_(kNormal), |
121 decoder_texture_target_(0), | 125 decoder_texture_target_(0), |
122 pixel_format_(PIXEL_FORMAT_UNKNOWN), | 126 pixel_format_(PIXEL_FORMAT_UNKNOWN), |
123 next_picture_buffer_id_(0), | 127 next_picture_buffer_id_(0), |
124 next_bitstream_buffer_id_(0), | 128 next_bitstream_buffer_id_(0), |
125 available_pictures_(0), | 129 available_pictures_(0), |
126 needs_all_picture_buffers_to_decode_(false), | 130 needs_all_picture_buffers_to_decode_(false), |
127 supports_deferred_initialization_(false), | 131 supports_deferred_initialization_(false), |
128 requires_texture_copy_(false), | 132 requires_texture_copy_(false), |
133 cdm_id_(CdmContext::kInvalidCdmId), | |
129 weak_factory_(this) { | 134 weak_factory_(this) { |
130 DCHECK(factories_); | 135 DCHECK(factories_); |
131 } | 136 } |
132 | 137 |
133 void GpuVideoDecoder::Reset(const base::Closure& closure) { | 138 void GpuVideoDecoder::Reset(const base::Closure& closure) { |
134 DVLOG(3) << "Reset()"; | 139 DVLOG(3) << "Reset()"; |
135 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 140 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
136 | 141 |
137 if (state_ == kDrainingDecoder) { | 142 if (state_ == kDrainingDecoder) { |
138 base::ThreadTaskRunnerHandle::Get()->PostTask( | 143 base::ThreadTaskRunnerHandle::Get()->PostTask( |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 const InitCB& init_cb, | 210 const InitCB& init_cb, |
206 const OutputCB& output_cb) { | 211 const OutputCB& output_cb) { |
207 DVLOG(3) << "Initialize()"; | 212 DVLOG(3) << "Initialize()"; |
208 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 213 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
209 DCHECK(config.IsValidConfig()); | 214 DCHECK(config.IsValidConfig()); |
210 | 215 |
211 InitCB bound_init_cb = | 216 InitCB bound_init_cb = |
212 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, | 217 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, |
213 BindToCurrentLoop(init_cb), media_log_); | 218 BindToCurrentLoop(init_cb), media_log_); |
214 | 219 |
220 bool requires_restart_for_external_output_surface = false; | |
215 #if !defined(OS_ANDROID) | 221 #if !defined(OS_ANDROID) |
216 if (config.is_encrypted()) { | 222 if (config.is_encrypted()) { |
217 DVLOG(1) << "Encrypted stream not supported."; | 223 DVLOG(1) << "Encrypted stream not supported."; |
218 bound_init_cb.Run(false); | 224 bound_init_cb.Run(false); |
219 return; | 225 return; |
220 } | 226 } |
227 #else | |
228 requires_restart_for_external_output_surface = | |
229 base::android::BuildInfo::GetInstance()->sdk_int() < 23; | |
221 #endif | 230 #endif |
222 | 231 |
223 bool previously_initialized = config_.IsValidConfig(); | 232 bool previously_initialized = config_.IsValidConfig(); |
224 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing") | 233 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing") |
225 << " GVD with config: " << config.AsHumanReadableString(); | 234 << " GVD with config: " << config.AsHumanReadableString(); |
226 | 235 |
227 // Disallow codec changes between configuration changes. | 236 // Disallow codec changes between configuration changes. |
228 if (previously_initialized && config_.codec() != config.codec()) { | 237 if (previously_initialized && config_.codec() != config.codec()) { |
229 DVLOG(1) << "Codec changed, cannot reinitialize."; | 238 DVLOG(1) << "Codec changed, cannot reinitialize."; |
230 bound_init_cb.Run(false); | 239 bound_init_cb.Run(false); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 return; | 290 return; |
282 } | 291 } |
283 | 292 |
284 vda_ = factories_->CreateVideoDecodeAccelerator(); | 293 vda_ = factories_->CreateVideoDecodeAccelerator(); |
285 if (!vda_) { | 294 if (!vda_) { |
286 DVLOG(1) << "Failed to create a VDA."; | 295 DVLOG(1) << "Failed to create a VDA."; |
287 bound_init_cb.Run(false); | 296 bound_init_cb.Run(false); |
288 return; | 297 return; |
289 } | 298 } |
290 | 299 |
291 int cdm_id = CdmContext::kInvalidCdmId; | |
292 if (config.is_encrypted()) { | 300 if (config.is_encrypted()) { |
293 DCHECK(cdm_context); | 301 DCHECK(cdm_context); |
294 cdm_id = cdm_context->GetCdmId(); | 302 cdm_id_ = cdm_context->GetCdmId(); |
295 // No need to store |cdm_context| since it's not needed in reinitialization. | 303 // No need to store |cdm_context| since it's not needed in reinitialization. |
296 if (cdm_id == CdmContext::kInvalidCdmId) { | 304 if (cdm_id_ == CdmContext::kInvalidCdmId) { |
297 DVLOG(1) << "CDM ID not available."; | 305 DVLOG(1) << "CDM ID not available."; |
298 bound_init_cb.Run(false); | 306 bound_init_cb.Run(false); |
299 return; | 307 return; |
300 } | 308 } |
301 } | 309 } |
302 | 310 |
303 init_cb_ = bound_init_cb; | 311 init_cb_ = bound_init_cb; |
304 | 312 |
305 const bool supports_external_output_surface = | 313 const bool supports_external_output_surface = |
306 (capabilities.flags & VideoDecodeAccelerator::Capabilities:: | 314 (capabilities.flags & VideoDecodeAccelerator::Capabilities:: |
307 SUPPORTS_EXTERNAL_OUTPUT_SURFACE) != 0; | 315 SUPPORTS_EXTERNAL_OUTPUT_SURFACE) != 0; |
308 if (supports_external_output_surface && !request_surface_cb_.is_null()) { | 316 if (supports_external_output_surface && !request_surface_cb_.is_null()) { |
309 // If we have a surface request callback we should call it and complete | 317 // If we have a surface request callback we should call it and complete |
310 // initialization with the returned surface. | 318 // initialization with the returned surface. |
311 request_surface_cb_.Run( | 319 request_surface_cb_.Run( |
312 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::CompleteInitialization, | 320 requires_restart_for_external_output_surface, |
313 weak_factory_.GetWeakPtr(), cdm_id))); | 321 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::OnSurfaceAvailable, |
322 weak_factory_.GetWeakPtr()))); | |
314 return; | 323 return; |
315 } | 324 } |
316 | 325 |
317 // If we don't have to wait for a surface complete initialization with a null | 326 // If external surfaces are not supported we can complete initialization now. |
318 // surface. | 327 CompleteInitialization(); |
319 CompleteInitialization(cdm_id, SurfaceManager::kNoSurfaceID); | |
320 } | 328 } |
321 | 329 |
322 void GpuVideoDecoder::CompleteInitialization(int cdm_id, int surface_id) { | 330 void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) { |
323 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 331 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
324 DCHECK(!init_cb_.is_null()); | |
325 | 332 |
326 // It's possible for the vda to become null if NotifyError is called. | 333 // It's possible for the vda to become null if NotifyError is called. |
327 if (!vda_) { | 334 if (!vda_) { |
328 base::ResetAndReturn(&init_cb_).Run(false); | 335 base::ResetAndReturn(&init_cb_).Run(false); |
watk
2016/11/09 00:56:36
Need to check init_cb_ is not null before running
DaleCurtis
2016/11/09 01:12:15
Good catch, done.
| |
329 return; | 336 return; |
330 } | 337 } |
331 | 338 |
339 vda_->SetSurface(surface_id); | |
340 | |
341 // If initialization has already completed, there's nothing left to do. | |
342 if (init_cb_.is_null()) | |
343 return; | |
344 | |
345 // Otherwise initialization was waiting for the surface, so complete it now. | |
346 CompleteInitialization(); | |
347 } | |
348 | |
349 void GpuVideoDecoder::CompleteInitialization() { | |
350 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | |
351 DCHECK(vda_); | |
352 DCHECK(!init_cb_.is_null()); | |
353 | |
332 VideoDecodeAccelerator::Config vda_config; | 354 VideoDecodeAccelerator::Config vda_config; |
333 vda_config.profile = config_.profile(); | 355 vda_config.profile = config_.profile(); |
334 vda_config.cdm_id = cdm_id; | 356 vda_config.cdm_id = cdm_id_; |
335 vda_config.is_encrypted = config_.is_encrypted(); | 357 vda_config.is_encrypted = config_.is_encrypted(); |
336 vda_config.surface_id = surface_id; | |
337 vda_config.is_deferred_initialization_allowed = true; | 358 vda_config.is_deferred_initialization_allowed = true; |
338 vda_config.initial_expected_coded_size = config_.coded_size(); | 359 vda_config.initial_expected_coded_size = config_.coded_size(); |
339 | 360 |
340 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) | 361 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) |
341 // We pass the SPS and PPS on Android because it lets us initialize | 362 // We pass the SPS and PPS on Android because it lets us initialize |
342 // MediaCodec more reliably (http://crbug.com/649185). | 363 // MediaCodec more reliably (http://crbug.com/649185). |
343 if (config_.codec() == kCodecH264) | 364 if (config_.codec() == kCodecH264) |
344 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); | 365 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); |
345 #endif | 366 #endif |
346 | 367 |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
778 DVLOG(3) << __func__; | 799 DVLOG(3) << __func__; |
779 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 800 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
780 | 801 |
781 if (vda_) | 802 if (vda_) |
782 DestroyVDA(); | 803 DestroyVDA(); |
783 DCHECK(assigned_picture_buffers_.empty()); | 804 DCHECK(assigned_picture_buffers_.empty()); |
784 | 805 |
785 if (!init_cb_.is_null()) | 806 if (!init_cb_.is_null()) |
786 base::ResetAndReturn(&init_cb_).Run(false); | 807 base::ResetAndReturn(&init_cb_).Run(false); |
787 if (!request_surface_cb_.is_null()) | 808 if (!request_surface_cb_.is_null()) |
788 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); | 809 base::ResetAndReturn(&request_surface_cb_).Run(false, SurfaceCreatedCB()); |
789 | 810 |
790 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 811 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
791 delete available_shm_segments_[i]; | 812 delete available_shm_segments_[i]; |
792 } | 813 } |
793 available_shm_segments_.clear(); | 814 available_shm_segments_.clear(); |
794 | 815 |
795 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = | 816 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = |
796 bitstream_buffers_in_decoder_.begin(); | 817 bitstream_buffers_in_decoder_.begin(); |
797 it != bitstream_buffers_in_decoder_.end(); ++it) { | 818 it != bitstream_buffers_in_decoder_.end(); ++it) { |
798 delete it->second.shm_buffer; | 819 delete it->second.shm_buffer; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
870 } | 891 } |
871 return false; | 892 return false; |
872 } | 893 } |
873 | 894 |
874 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 895 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
875 const { | 896 const { |
876 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 897 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
877 } | 898 } |
878 | 899 |
879 } // namespace media | 900 } // namespace media |
OLD | NEW |