| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/gpu/android_video_decode_accelerator.h" | 5 #include "media/gpu/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 constexpr base::TimeDelta DecodePollDelay = | 101 constexpr base::TimeDelta DecodePollDelay = |
| 102 base::TimeDelta::FromMilliseconds(10); | 102 base::TimeDelta::FromMilliseconds(10); |
| 103 | 103 |
| 104 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); | 104 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); |
| 105 | 105 |
| 106 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); | 106 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); |
| 107 | 107 |
| 108 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | 108 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), |
| 109 // defer the surface creation until the codec is actually used if we know no | 109 // defer the surface creation until the codec is actually used if we know no |
| 110 // software fallback exists. | 110 // software fallback exists. |
| 111 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { | 111 bool ShouldDeferSurfaceCreation(AVDACodecAllocator* codec_allocator, |
| 112 int surface_id, |
| 113 VideoCodec codec) { |
| 112 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && | 114 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && |
| 113 AVDACodecAllocator::Instance()->IsAnyRegisteredAVDA() && | 115 codec_allocator->IsAnyRegisteredAVDA() && |
| 114 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || | 116 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || |
| 115 base::SysInfo::IsLowEndDevice()); | 117 base::SysInfo::IsLowEndDevice()); |
| 116 } | 118 } |
| 117 | 119 |
| 118 } // namespace | 120 } // namespace |
| 119 | 121 |
| 120 // AVDAManager manages shared resources for a number of AVDA instances. | 122 // AVDAManager manages shared resources for a number of AVDA instances. |
| 121 // Its responsibilities include: | 123 // Its responsibilities include: |
| 122 // - Starting and stopping a shared "construction" thread for instantiating and | 124 // - Starting and stopping a shared "construction" thread for instantiating and |
| 123 // releasing MediaCodecs. | 125 // releasing MediaCodecs. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 memory.reset(new SharedMemoryRegion(buffer, true)); | 218 memory.reset(new SharedMemoryRegion(buffer, true)); |
| 217 } | 219 } |
| 218 | 220 |
| 219 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 221 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
| 220 BitstreamRecord&& other) | 222 BitstreamRecord&& other) |
| 221 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} | 223 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} |
| 222 | 224 |
| 223 AndroidVideoDecodeAccelerator::BitstreamRecord::~BitstreamRecord() {} | 225 AndroidVideoDecodeAccelerator::BitstreamRecord::~BitstreamRecord() {} |
| 224 | 226 |
| 225 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 227 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
| 228 AVDACodecAllocator* codec_allocator, |
| 226 const MakeGLContextCurrentCallback& make_context_current_cb, | 229 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 227 const GetGLES2DecoderCallback& get_gles2_decoder_cb) | 230 const GetGLES2DecoderCallback& get_gles2_decoder_cb) |
| 228 : client_(NULL), | 231 : client_(nullptr), |
| 232 codec_allocator_(codec_allocator), |
| 229 make_context_current_cb_(make_context_current_cb), | 233 make_context_current_cb_(make_context_current_cb), |
| 230 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 234 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
| 231 state_(BEFORE_SURFACE_ALLOC), | 235 state_(BEFORE_SURFACE_ALLOC), |
| 232 picturebuffers_requested_(false), | 236 picturebuffers_requested_(false), |
| 233 picture_buffer_manager_(this), | 237 picture_buffer_manager_(this), |
| 234 media_drm_bridge_cdm_context_(nullptr), | 238 media_drm_bridge_cdm_context_(nullptr), |
| 235 cdm_registration_id_(0), | 239 cdm_registration_id_(0), |
| 236 pending_input_buf_index_(-1), | 240 pending_input_buf_index_(-1), |
| 237 during_initialize_(false), | 241 during_initialize_(false), |
| 238 deferred_initialization_pending_(false), | 242 deferred_initialization_pending_(false), |
| 239 codec_needs_reset_(false), | 243 codec_needs_reset_(false), |
| 240 defer_surface_creation_(false), | 244 defer_surface_creation_(false), |
| 241 last_release_task_type_(TaskType::AUTO_CODEC), | 245 last_release_task_type_(TaskType::AUTO_CODEC), |
| 242 weak_this_factory_(this) {} | 246 weak_this_factory_(this) {} |
| 243 | 247 |
| 244 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 248 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 245 DCHECK(thread_checker_.CalledOnValidThread()); | 249 DCHECK(thread_checker_.CalledOnValidThread()); |
| 246 GetManager()->StopTimer(this); | 250 GetManager()->StopTimer(this); |
| 247 AVDACodecAllocator::Instance()->StopThread(this); | 251 codec_allocator_->StopThread(this); |
| 248 | 252 |
| 249 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 253 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 250 if (!media_drm_bridge_cdm_context_) | 254 if (!media_drm_bridge_cdm_context_) |
| 251 return; | 255 return; |
| 252 | 256 |
| 253 DCHECK(cdm_registration_id_); | 257 DCHECK(cdm_registration_id_); |
| 254 | 258 |
| 255 // Cancel previously registered callback (if any). | 259 // Cancel previously registered callback (if any). |
| 256 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( | 260 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( |
| 257 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); | 261 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 // SetSurface() can't be called before Initialize(), so we pick up our first | 324 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 321 // surface ID from the codec configuration. | 325 // surface ID from the codec configuration. |
| 322 DCHECK(!pending_surface_id_); | 326 DCHECK(!pending_surface_id_); |
| 323 | 327 |
| 324 // We signaled that we support deferred initialization, so see if the client | 328 // We signaled that we support deferred initialization, so see if the client |
| 325 // does also. | 329 // does also. |
| 326 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 330 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 327 | 331 |
| 328 // If we're low on resources, we may decide to defer creation of the surface | 332 // If we're low on resources, we may decide to defer creation of the surface |
| 329 // until the codec is actually used. | 333 // until the codec is actually used. |
| 330 if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec)) { | 334 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, |
| 335 codec_config_->codec)) { |
| 331 // We should never be here if a SurfaceView is required. | 336 // We should never be here if a SurfaceView is required. |
| 332 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 337 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); |
| 333 defer_surface_creation_ = true; | 338 defer_surface_creation_ = true; |
| 334 } | 339 } |
| 335 | 340 |
| 336 if (!AVDACodecAllocator::Instance()->StartThread(this)) { | 341 if (!codec_allocator_->StartThread(this)) { |
| 337 LOG(ERROR) << "Unable to start thread"; | 342 LOG(ERROR) << "Unable to start thread"; |
| 338 return false; | 343 return false; |
| 339 } | 344 } |
| 340 | 345 |
| 341 // For encrypted media, start by initializing the CDM. Otherwise, start with | 346 // For encrypted media, start by initializing the CDM. Otherwise, start with |
| 342 // the surface. | 347 // the surface. |
| 343 if (config_.is_encrypted()) { | 348 if (config_.is_encrypted()) { |
| 344 if (!deferred_initialization_pending_) { | 349 if (!deferred_initialization_pending_) { |
| 345 DLOG(ERROR) | 350 DLOG(ERROR) |
| 346 << "Deferred initialization must be used for encrypted streams"; | 351 << "Deferred initialization must be used for encrypted streams"; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 366 // decode to save resources, though, we're signaling success now. If we're | 371 // decode to save resources, though, we're signaling success now. If we're |
| 367 // wrong, then decoding might fail when we might have been able to use a | 372 // wrong, then decoding might fail when we might have been able to use a |
| 368 // fallback renderer in WMPI if we failed init. | 373 // fallback renderer in WMPI if we failed init. |
| 369 if (defer_surface_creation_) { | 374 if (defer_surface_creation_) { |
| 370 if (deferred_initialization_pending_) | 375 if (deferred_initialization_pending_) |
| 371 NotifyInitializationSucceeded(); | 376 NotifyInitializationSucceeded(); |
| 372 | 377 |
| 373 return; | 378 return; |
| 374 } | 379 } |
| 375 | 380 |
| 376 if (!AVDACodecAllocator::Instance()->AllocateSurface(this, | 381 if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) { |
| 377 config_.surface_id)) { | |
| 378 // We have to wait for some other AVDA instance to free up the surface. | 382 // We have to wait for some other AVDA instance to free up the surface. |
| 379 // OnSurfaceAvailable will be called when it's available. | 383 // OnSurfaceAvailable will be called when it's available. |
| 380 // Note that if we aren't deferring init, then we'll signal success, and | 384 // Note that if we aren't deferring init, then we'll signal success, and |
| 381 // if we fail later then it will fail decoding instead. However, since | 385 // if we fail later then it will fail decoding instead. However, since |
| 382 // nobody that provides a SurfaceView requires sync init, it doesn't matter. | 386 // nobody that provides a SurfaceView requires sync init, it doesn't matter. |
| 383 return; | 387 return; |
| 384 } | 388 } |
| 385 | 389 |
| 386 // We now own the surface, so finish initialization. | 390 // We now own the surface, so finish initialization. |
| 387 InitializePictureBufferManager(); | 391 InitializePictureBufferManager(); |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 | 927 |
| 924 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 928 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| 925 DCHECK(thread_checker_.CalledOnValidThread()); | 929 DCHECK(thread_checker_.CalledOnValidThread()); |
| 926 | 930 |
| 927 DCHECK_NE(state_, WAITING_FOR_CODEC); | 931 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 928 state_ = WAITING_FOR_CODEC; | 932 state_ = WAITING_FOR_CODEC; |
| 929 | 933 |
| 930 ReleaseCodec(); | 934 ReleaseCodec(); |
| 931 | 935 |
| 932 base::Optional<TaskType> task_type = | 936 base::Optional<TaskType> task_type = |
| 933 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | 937 codec_allocator_->TaskTypeForAllocation(); |
| 934 if (!task_type) { | 938 if (!task_type) { |
| 935 // If there is no free thread, then just fail. | 939 // If there is no free thread, then just fail. |
| 936 OnCodecConfigured(nullptr); | 940 OnCodecConfigured(nullptr); |
| 937 return; | 941 return; |
| 938 } | 942 } |
| 939 | 943 |
| 940 // If autodetection is disallowed, fall back to Chrome's software decoders | 944 // If autodetection is disallowed, fall back to Chrome's software decoders |
| 941 // instead of using the software decoders provided by MediaCodec. | 945 // instead of using the software decoders provided by MediaCodec. |
| 942 if (task_type == TaskType::SW_CODEC && | 946 if (task_type == TaskType::SW_CODEC && |
| 943 IsMediaCodecSoftwareDecodingForbidden()) { | 947 IsMediaCodecSoftwareDecodingForbidden()) { |
| 944 OnCodecConfigured(nullptr); | 948 OnCodecConfigured(nullptr); |
| 945 return; | 949 return; |
| 946 } | 950 } |
| 947 | 951 |
| 948 codec_config_->task_type = task_type.value(); | 952 codec_config_->task_type = task_type.value(); |
| 949 AVDACodecAllocator::Instance()->CreateMediaCodecAsync( | 953 codec_allocator_->CreateMediaCodecAsync(weak_this_factory_.GetWeakPtr(), |
| 950 weak_this_factory_.GetWeakPtr(), codec_config_); | 954 codec_config_); |
| 951 } | 955 } |
| 952 | 956 |
| 953 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { | 957 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { |
| 954 DCHECK(thread_checker_.CalledOnValidThread()); | 958 DCHECK(thread_checker_.CalledOnValidThread()); |
| 955 DCHECK(!media_codec_); | 959 DCHECK(!media_codec_); |
| 956 DCHECK_NE(state_, WAITING_FOR_CODEC); | 960 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 957 state_ = WAITING_FOR_CODEC; | 961 state_ = WAITING_FOR_CODEC; |
| 958 | 962 |
| 959 base::Optional<TaskType> task_type = | 963 base::Optional<TaskType> task_type = |
| 960 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | 964 codec_allocator_->TaskTypeForAllocation(); |
| 961 if (!task_type) { | 965 if (!task_type) { |
| 962 // If there is no free thread, then just fail. | 966 // If there is no free thread, then just fail. |
| 963 OnCodecConfigured(nullptr); | 967 OnCodecConfigured(nullptr); |
| 964 return; | 968 return; |
| 965 } | 969 } |
| 966 | 970 |
| 967 codec_config_->task_type = task_type.value(); | 971 codec_config_->task_type = task_type.value(); |
| 968 std::unique_ptr<VideoCodecBridge> media_codec = | 972 std::unique_ptr<VideoCodecBridge> media_codec = |
| 969 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_); | 973 codec_allocator_->CreateMediaCodecSync(codec_config_); |
| 970 // Note that |media_codec| might be null, which will NotifyError. | 974 // Note that |media_codec| might be null, which will NotifyError. |
| 971 OnCodecConfigured(std::move(media_codec)); | 975 OnCodecConfigured(std::move(media_codec)); |
| 972 } | 976 } |
| 973 | 977 |
| 974 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 978 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 975 std::unique_ptr<VideoCodecBridge> media_codec) { | 979 std::unique_ptr<VideoCodecBridge> media_codec) { |
| 976 DCHECK(thread_checker_.CalledOnValidThread()); | 980 DCHECK(thread_checker_.CalledOnValidThread()); |
| 977 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 981 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 978 | 982 |
| 979 // If we are supposed to notify that initialization is complete, then do so | 983 // If we are supposed to notify that initialization is complete, then do so |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY; | 1049 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY; |
| 1046 } | 1050 } |
| 1047 | 1051 |
| 1048 void AndroidVideoDecodeAccelerator::OnDrainCompleted() { | 1052 void AndroidVideoDecodeAccelerator::OnDrainCompleted() { |
| 1049 DVLOG(2) << __func__; | 1053 DVLOG(2) << __func__; |
| 1050 DCHECK(thread_checker_.CalledOnValidThread()); | 1054 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1051 | 1055 |
| 1052 // Sometimes MediaCodec returns an EOS buffer even if we didn't queue one. | 1056 // Sometimes MediaCodec returns an EOS buffer even if we didn't queue one. |
| 1053 // Consider it an error. http://crbug.com/585959. | 1057 // Consider it an error. http://crbug.com/585959. |
| 1054 if (!drain_type_) { | 1058 if (!drain_type_) { |
| 1055 state_ = ERROR; | 1059 NOTIFY_ERROR(PLATFORM_FAILURE, "Unexpected EOS"); |
| 1056 ResetCodecState(); | |
| 1057 return; | 1060 return; |
| 1058 } | 1061 } |
| 1059 | 1062 |
| 1060 ResetCodecState(); | |
| 1061 switch (*drain_type_) { | 1063 switch (*drain_type_) { |
| 1062 case DRAIN_FOR_FLUSH: | 1064 case DRAIN_FOR_FLUSH: |
| 1065 ResetCodecState(); |
| 1063 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1066 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1064 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, | 1067 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, |
| 1065 weak_this_factory_.GetWeakPtr())); | 1068 weak_this_factory_.GetWeakPtr())); |
| 1066 break; | 1069 break; |
| 1067 case DRAIN_FOR_RESET: | 1070 case DRAIN_FOR_RESET: |
| 1071 ResetCodecState(); |
| 1068 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1072 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1069 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1073 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1070 weak_this_factory_.GetWeakPtr())); | 1074 weak_this_factory_.GetWeakPtr())); |
| 1071 break; | 1075 break; |
| 1072 case DRAIN_FOR_DESTROY: | 1076 case DRAIN_FOR_DESTROY: |
| 1073 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1077 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1074 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy, | 1078 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy, |
| 1075 weak_this_factory_.GetWeakPtr())); | 1079 weak_this_factory_.GetWeakPtr())); |
| 1076 break; | 1080 break; |
| 1077 } | 1081 } |
| 1078 drain_type_.reset(); | 1082 drain_type_.reset(); |
| 1079 } | 1083 } |
| 1080 | 1084 |
| 1081 void AndroidVideoDecodeAccelerator::ResetCodecState() { | 1085 void AndroidVideoDecodeAccelerator::ResetCodecState() { |
| 1082 DCHECK(thread_checker_.CalledOnValidThread()); | 1086 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1083 | 1087 |
| 1084 // If there is already a reset in flight, then that counts. This can really | 1088 // If the surface is destroyed or we're in an error state there's nothing to |
| 1085 // only happen if somebody calls Reset. | 1089 // do. |
| 1086 // If the surface is destroyed there's nothing to do. | 1090 if (state_ == WAITING_FOR_CODEC || !media_codec_ || |
| 1087 // Note that BEFORE_SURFACE_ALLOC implies that we have no codec, but it's | 1091 state_ == SURFACE_DESTROYED || state_ == BEFORE_SURFACE_ALLOC || |
| 1088 // included for completeness. | 1092 state_ == ERROR) { |
| 1089 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED || | |
| 1090 state_ == BEFORE_SURFACE_ALLOC || !media_codec_) { | |
| 1091 return; | 1093 return; |
| 1092 } | 1094 } |
| 1093 | 1095 |
| 1094 bitstream_buffers_in_decoder_.clear(); | 1096 bitstream_buffers_in_decoder_.clear(); |
| 1095 | 1097 |
| 1096 if (pending_input_buf_index_ != -1) { | 1098 if (pending_input_buf_index_ != -1) { |
| 1097 // The data for that index exists in the input buffer, but corresponding | 1099 // The data for that index exists in the input buffer, but corresponding |
| 1098 // shm block been deleted. Check that it is safe to flush the codec, i.e. | 1100 // shm block been deleted. Check that it is safe to flush the codec, i.e. |
| 1099 // |pending_bitstream_records_| is empty. | 1101 // |pending_bitstream_records_| is empty. |
| 1100 // TODO(timav): keep shm block for that buffer and remove this restriction. | 1102 // TODO(timav): keep shm block for that buffer and remove this restriction. |
| 1101 DCHECK(pending_bitstream_records_.empty()); | 1103 DCHECK(pending_bitstream_records_.empty()); |
| 1102 pending_input_buf_index_ = -1; | 1104 pending_input_buf_index_ = -1; |
| 1103 } | 1105 } |
| 1104 | 1106 |
| 1105 const bool did_codec_error_happen = state_ == ERROR; | 1107 // If we've just completed a flush don't reset the codec yet. Instead defer |
| 1106 state_ = NO_ERROR; | 1108 // until the next decode call. This prevents us from unbacking frames that |
| 1107 | 1109 // might be out for display at end of stream. |
| 1108 // Don't reset the codec here if there's no error and we're only flushing; | 1110 codec_needs_reset_ = drain_type_ == DRAIN_FOR_FLUSH; |
| 1109 // instead defer until the next decode call; this prevents us from unbacking | 1111 if (codec_needs_reset_) |
| 1110 // frames that might be out for display at end of stream. | |
| 1111 codec_needs_reset_ = false; | |
| 1112 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) { | |
| 1113 codec_needs_reset_ = true; | |
| 1114 return; | 1112 return; |
| 1115 } | |
| 1116 | 1113 |
| 1117 // Flush the codec if possible, or create a new one if not. | 1114 // Flush the codec if possible, or create a new one if not. |
| 1118 if (!did_codec_error_happen && | 1115 if (!MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
| 1119 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | |
| 1120 DVLOG(3) << __func__ << " Flushing MediaCodec."; | 1116 DVLOG(3) << __func__ << " Flushing MediaCodec."; |
| 1121 media_codec_->Flush(); | 1117 media_codec_->Flush(); |
| 1122 // Since we just flushed all the output buffers, make sure that nothing is | 1118 // Since we just flushed all the output buffers, make sure that nothing is |
| 1123 // using them. | 1119 // using them. |
| 1124 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1120 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1125 } else { | 1121 } else { |
| 1126 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; | 1122 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; |
| 1127 GetManager()->StopTimer(this); | 1123 GetManager()->StopTimer(this); |
| 1128 ConfigureMediaCodecAsynchronously(); | 1124 ConfigureMediaCodecAsynchronously(); |
| 1129 } | 1125 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 | 1192 |
| 1197 // Note that async codec construction might still be in progress. In that | 1193 // Note that async codec construction might still be in progress. In that |
| 1198 // case, the codec will be deleted when it completes once we invalidate all | 1194 // case, the codec will be deleted when it completes once we invalidate all |
| 1199 // our weak refs. | 1195 // our weak refs. |
| 1200 weak_this_factory_.InvalidateWeakPtrs(); | 1196 weak_this_factory_.InvalidateWeakPtrs(); |
| 1201 GetManager()->StopTimer(this); | 1197 GetManager()->StopTimer(this); |
| 1202 ReleaseCodec(); | 1198 ReleaseCodec(); |
| 1203 | 1199 |
| 1204 // We no longer care about |surface_id|, in case we did before. It's okay | 1200 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1205 // if we have no surface and/or weren't the owner or a waiter. | 1201 // if we have no surface and/or weren't the owner or a waiter. |
| 1206 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); | 1202 codec_allocator_->DeallocateSurface(this, config_.surface_id); |
| 1207 | 1203 |
| 1208 // Hop the SurfaceTexture release call through the task runner used last time | 1204 // Hop the SurfaceTexture release call through the task runner used last time |
| 1209 // we released a codec. This ensures that we release the surface texture after | 1205 // we released a codec. This ensures that we release the surface texture after |
| 1210 // the codec it's attached to (if any) is released. It's not sufficient to use | 1206 // the codec it's attached to (if any) is released. It's not sufficient to use |
| 1211 // |codec_config_->task_type| because that might have changed since we | 1207 // |codec_config_->task_type| because that might have changed since we |
| 1212 // released the codec this surface was attached to. | 1208 // released the codec this surface was attached to. |
| 1213 if (codec_config_->surface_texture) { | 1209 if (codec_config_->surface_texture) { |
| 1214 AVDACodecAllocator::Instance() | 1210 codec_allocator_->TaskRunnerFor(last_release_task_type_) |
| 1215 ->TaskRunnerFor(last_release_task_type_) | |
| 1216 ->PostTaskAndReply( | 1211 ->PostTaskAndReply( |
| 1217 FROM_HERE, base::Bind(&base::DoNothing), | 1212 FROM_HERE, base::Bind(&base::DoNothing), |
| 1218 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture, | 1213 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture, |
| 1219 codec_config_->surface_texture)); | 1214 codec_config_->surface_texture)); |
| 1220 } | 1215 } |
| 1221 | 1216 |
| 1222 delete this; | 1217 delete this; |
| 1223 } | 1218 } |
| 1224 | 1219 |
| 1225 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1220 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1536 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); | 1531 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); |
| 1537 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || | 1532 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || |
| 1538 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); | 1533 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); |
| 1539 | 1534 |
| 1540 const int previous_surface_id = config_.surface_id; | 1535 const int previous_surface_id = config_.surface_id; |
| 1541 const int new_surface_id = pending_surface_id_.value(); | 1536 const int new_surface_id = pending_surface_id_.value(); |
| 1542 pending_surface_id_.reset(); | 1537 pending_surface_id_.reset(); |
| 1543 bool success = true; | 1538 bool success = true; |
| 1544 | 1539 |
| 1545 // TODO(watk): Fix this so we can wait for the new surface to be allocated. | 1540 // TODO(watk): Fix this so we can wait for the new surface to be allocated. |
| 1546 if (!AVDACodecAllocator::Instance()->AllocateSurface(this, new_surface_id)) { | 1541 if (!codec_allocator_->AllocateSurface(this, new_surface_id)) { |
| 1547 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface"); | 1542 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface"); |
| 1548 success = false; | 1543 success = false; |
| 1549 } | 1544 } |
| 1550 | 1545 |
| 1551 // Ensure the current context is active when switching surfaces; we may need | 1546 // Ensure the current context is active when switching surfaces; we may need |
| 1552 // to create a new texture. | 1547 // to create a new texture. |
| 1553 if (success && !make_context_current_cb_.Run()) { | 1548 if (success && !make_context_current_cb_.Run()) { |
| 1554 NOTIFY_ERROR(PLATFORM_FAILURE, | 1549 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 1555 "Failed to make this decoder's GL context current when " | 1550 "Failed to make this decoder's GL context current when " |
| 1556 "switching surfaces."); | 1551 "switching surfaces."); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1573 } | 1568 } |
| 1574 | 1569 |
| 1575 if (success) { | 1570 if (success) { |
| 1576 config_.surface_id = new_surface_id; | 1571 config_.surface_id = new_surface_id; |
| 1577 codec_config_->surface = std::move(new_surface); | 1572 codec_config_->surface = std::move(new_surface); |
| 1578 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | 1573 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); |
| 1579 } else { | 1574 } else { |
| 1580 // This might be called from OnSurfaceDestroyed(), so we have to release the | 1575 // This might be called from OnSurfaceDestroyed(), so we have to release the |
| 1581 // MediaCodec if we failed to switch the surface. | 1576 // MediaCodec if we failed to switch the surface. |
| 1582 ReleaseCodec(); | 1577 ReleaseCodec(); |
| 1583 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); | 1578 codec_allocator_->DeallocateSurface(this, new_surface_id); |
| 1584 } | 1579 } |
| 1585 | 1580 |
| 1586 // Regardless of whether we succeeded, we no longer own the previous surface. | 1581 // Regardless of whether we succeeded, we no longer own the previous surface. |
| 1587 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); | 1582 codec_allocator_->DeallocateSurface(this, previous_surface_id); |
| 1588 | 1583 |
| 1589 return success; | 1584 return success; |
| 1590 } | 1585 } |
| 1591 | 1586 |
| 1592 void AndroidVideoDecodeAccelerator::ReleaseCodec() { | 1587 void AndroidVideoDecodeAccelerator::ReleaseCodec() { |
| 1593 if (!media_codec_) | 1588 if (!media_codec_) |
| 1594 return; | 1589 return; |
| 1595 | 1590 |
| 1596 picture_buffer_manager_.CodecChanged(nullptr); | 1591 picture_buffer_manager_.CodecChanged(nullptr); |
| 1597 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1592 codec_allocator_->ReleaseMediaCodec( |
| 1598 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1593 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
| 1599 last_release_task_type_ = codec_config_->task_type; | 1594 last_release_task_type_ = codec_config_->task_type; |
| 1600 } | 1595 } |
| 1601 | 1596 |
| 1602 } // namespace media | 1597 } // namespace media |
| OLD | NEW |