Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: media/gpu/android_video_decode_accelerator.cc

Issue 2662173002: media: Don't create a new MediaCodec during AVDA teardown (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/android_video_decode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698