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 16 matching lines...) Expand all Loading... | |
27 #include "gpu/command_buffer/service/mailbox_manager.h" | 27 #include "gpu/command_buffer/service/mailbox_manager.h" |
28 #include "gpu/ipc/service/gpu_channel.h" | 28 #include "gpu/ipc/service/gpu_channel.h" |
29 #include "media/base/android/media_codec_bridge_impl.h" | 29 #include "media/base/android/media_codec_bridge_impl.h" |
30 #include "media/base/android/media_codec_util.h" | 30 #include "media/base/android/media_codec_util.h" |
31 #include "media/base/bind_to_current_loop.h" | 31 #include "media/base/bind_to_current_loop.h" |
32 #include "media/base/bitstream_buffer.h" | 32 #include "media/base/bitstream_buffer.h" |
33 #include "media/base/limits.h" | 33 #include "media/base/limits.h" |
34 #include "media/base/media.h" | 34 #include "media/base/media.h" |
35 #include "media/base/timestamp_constants.h" | 35 #include "media/base/timestamp_constants.h" |
36 #include "media/base/video_decoder_config.h" | 36 #include "media/base/video_decoder_config.h" |
37 #include "media/gpu/android_video_surface_chooser_impl.h" | |
37 #include "media/gpu/avda_picture_buffer_manager.h" | 38 #include "media/gpu/avda_picture_buffer_manager.h" |
38 #include "media/gpu/content_video_view_overlay.h" | 39 #include "media/gpu/content_video_view_overlay.h" |
40 #include "media/gpu/content_video_view_overlay_factory.h" | |
39 #include "media/gpu/shared_memory_region.h" | 41 #include "media/gpu/shared_memory_region.h" |
40 #include "media/video/picture.h" | 42 #include "media/video/picture.h" |
41 #include "ui/gl/android/scoped_java_surface.h" | 43 #include "ui/gl/android/scoped_java_surface.h" |
42 #include "ui/gl/android/surface_texture.h" | 44 #include "ui/gl/android/surface_texture.h" |
43 #include "ui/gl/gl_bindings.h" | 45 #include "ui/gl/gl_bindings.h" |
44 | 46 |
45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 47 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
46 #include "media/mojo/services/mojo_cdm_service.h" // nogncheck | 48 #include "media/mojo/services/mojo_cdm_service.h" // nogncheck |
47 #endif | 49 #endif |
48 | 50 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 constexpr base::TimeDelta DecodePollDelay = | 104 constexpr base::TimeDelta DecodePollDelay = |
103 base::TimeDelta::FromMilliseconds(10); | 105 base::TimeDelta::FromMilliseconds(10); |
104 | 106 |
105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); | 107 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); |
106 | 108 |
107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); | 109 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); |
108 | 110 |
109 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | 111 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), |
110 // defer the surface creation until the codec is actually used if we know no | 112 // defer the surface creation until the codec is actually used if we know no |
111 // software fallback exists. | 113 // software fallback exists. |
112 bool ShouldDeferSurfaceCreation(AVDACodecAllocator* codec_allocator, | 114 bool ShouldDeferSurfaceCreation( |
113 int surface_id, | 115 AVDACodecAllocator* codec_allocator, |
114 VideoCodec codec) { | 116 int surface_id, |
115 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && | 117 VideoCodec codec, |
116 codec_allocator->IsAnyRegisteredAVDA() && | 118 const AndroidVideoDecodeAccelerator::PlatformConfig& platform_config) { |
117 base::android::BuildInfo::GetInstance()->sdk_int() <= 18; | 119 return platform_config.force_deferred_surface_creation || |
120 (surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && | |
121 codec_allocator->IsAnyRegisteredAVDA() && | |
122 platform_config.sdk_int <= 18); | |
118 } | 123 } |
119 | 124 |
120 } // namespace | 125 } // namespace |
121 | 126 |
122 // AVDAManager manages shared resources for a number of AVDA instances. | 127 // AVDAManager manages a RepeatingTimer so that AVDAs can get a regular callback |
123 // Its responsibilities include: | 128 // to DoIOTask(). |
124 // - Starting and stopping a shared "construction" thread for instantiating and | |
125 // releasing MediaCodecs. | |
126 // - Detecting when a task has hung on the construction thread so AVDAs can | |
127 // stop using it. | |
128 // - Running a RepeatingTimer so that AVDAs can get a regular callback to | |
129 // DoIOTask(). | |
130 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when | |
131 // surfaces are released. | |
132 class AVDAManager { | 129 class AVDAManager { |
133 public: | 130 public: |
134 AVDAManager() {} | 131 AVDAManager() {} |
135 | 132 |
136 // Request periodic callback of |avda|->DoIOTask(). Does nothing if the | 133 // Request periodic callback of |avda|->DoIOTask(). Does nothing if the |
137 // instance is already registered and the timer started. The first request | 134 // instance is already registered and the timer started. The first request |
138 // will start the repeating timer on an interval of DecodePollDelay. | 135 // will start the repeating timer on an interval of DecodePollDelay. |
139 void StartTimer(AndroidVideoDecodeAccelerator* avda) { | 136 void StartTimer(AndroidVideoDecodeAccelerator* avda) { |
140 DCHECK(thread_checker_.CalledOnValidThread()); | 137 DCHECK(thread_checker_.CalledOnValidThread()); |
141 | 138 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 base::ThreadChecker thread_checker_; | 201 base::ThreadChecker thread_checker_; |
205 | 202 |
206 DISALLOW_COPY_AND_ASSIGN(AVDAManager); | 203 DISALLOW_COPY_AND_ASSIGN(AVDAManager); |
207 }; | 204 }; |
208 | 205 |
209 static AVDAManager* GetManager() { | 206 static AVDAManager* GetManager() { |
210 static AVDAManager* manager = new AVDAManager(); | 207 static AVDAManager* manager = new AVDAManager(); |
211 return manager; | 208 return manager; |
212 } | 209 } |
213 | 210 |
211 AndroidVideoDecodeAccelerator::PlatformConfig | |
212 AndroidVideoDecodeAccelerator::PlatformConfig::CreateDefault() { | |
213 PlatformConfig config; | |
214 | |
215 config.sdk_int = base::android::BuildInfo::GetInstance()->sdk_int(); | |
216 config.allow_setsurface = MediaCodecUtil::IsSetOutputSurfaceSupported(); | |
217 | |
218 return config; | |
219 } | |
220 | |
214 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 221 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
215 const BitstreamBuffer& bitstream_buffer) | 222 const BitstreamBuffer& bitstream_buffer) |
216 : buffer(bitstream_buffer) { | 223 : buffer(bitstream_buffer) { |
217 if (buffer.id() != -1) | 224 if (buffer.id() != -1) |
218 memory.reset(new SharedMemoryRegion(buffer, true)); | 225 memory.reset(new SharedMemoryRegion(buffer, true)); |
219 } | 226 } |
220 | 227 |
221 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 228 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
222 BitstreamRecord&& other) | 229 BitstreamRecord&& other) |
223 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} | 230 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} |
224 | 231 |
225 AndroidVideoDecodeAccelerator::BitstreamRecord::~BitstreamRecord() {} | 232 AndroidVideoDecodeAccelerator::BitstreamRecord::~BitstreamRecord() {} |
226 | 233 |
227 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 234 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
228 AVDACodecAllocator* codec_allocator, | 235 AVDACodecAllocator* codec_allocator, |
236 std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser, | |
229 const MakeGLContextCurrentCallback& make_context_current_cb, | 237 const MakeGLContextCurrentCallback& make_context_current_cb, |
230 const GetGLES2DecoderCallback& get_gles2_decoder_cb) | 238 const GetGLES2DecoderCallback& get_gles2_decoder_cb, |
239 const PlatformConfig& platform_config) | |
231 : client_(nullptr), | 240 : client_(nullptr), |
232 codec_allocator_(codec_allocator), | 241 codec_allocator_(codec_allocator), |
233 make_context_current_cb_(make_context_current_cb), | 242 make_context_current_cb_(make_context_current_cb), |
234 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 243 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
235 state_(WAITING_FOR_SURFACE), | 244 state_(BEFORE_OVERLAY_INIT), |
236 picturebuffers_requested_(false), | 245 picturebuffers_requested_(false), |
237 picture_buffer_manager_(this), | 246 picture_buffer_manager_(this), |
238 media_drm_bridge_cdm_context_(nullptr), | 247 media_drm_bridge_cdm_context_(nullptr), |
239 cdm_registration_id_(0), | 248 cdm_registration_id_(0), |
240 pending_input_buf_index_(-1), | 249 pending_input_buf_index_(-1), |
241 during_initialize_(false), | 250 during_initialize_(false), |
242 deferred_initialization_pending_(false), | 251 deferred_initialization_pending_(false), |
243 codec_needs_reset_(false), | 252 codec_needs_reset_(false), |
244 defer_surface_creation_(false), | 253 defer_surface_creation_(false), |
254 surface_chooser_(std::move(surface_chooser)), | |
255 platform_config_(platform_config), | |
245 weak_this_factory_(this) {} | 256 weak_this_factory_(this) {} |
246 | 257 |
247 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 258 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
248 DCHECK(thread_checker_.CalledOnValidThread()); | 259 DCHECK(thread_checker_.CalledOnValidThread()); |
249 GetManager()->StopTimer(this); | 260 GetManager()->StopTimer(this); |
250 codec_allocator_->StopThread(this); | 261 codec_allocator_->StopThread(this); |
251 | 262 |
252 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 263 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
253 if (!media_drm_bridge_cdm_context_) | 264 if (!media_drm_bridge_cdm_context_) |
254 return; | 265 return; |
(...skipping 26 matching lines...) Expand all Loading... | |
281 return false; | 292 return false; |
282 } | 293 } |
283 | 294 |
284 DCHECK(client); | 295 DCHECK(client); |
285 client_ = client; | 296 client_ = client; |
286 config_ = config; | 297 config_ = config; |
287 codec_config_ = new CodecConfig(); | 298 codec_config_ = new CodecConfig(); |
288 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile); | 299 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile); |
289 codec_config_->initial_expected_coded_size = | 300 codec_config_->initial_expected_coded_size = |
290 config.initial_expected_coded_size; | 301 config.initial_expected_coded_size; |
291 incoming_bundle_ = new AVDASurfaceBundle(config_.surface_id); | |
292 | 302 |
293 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 && | 303 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 && |
294 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 304 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
295 codec_config_->codec != kCodecHEVC && | 305 codec_config_->codec != kCodecHEVC && |
296 #endif | 306 #endif |
297 codec_config_->codec != kCodecH264) { | 307 codec_config_->codec != kCodecH264) { |
298 DLOG(ERROR) << "Unsupported profile: " << GetProfileName(config.profile); | 308 DLOG(ERROR) << "Unsupported profile: " << GetProfileName(config.profile); |
299 return false; | 309 return false; |
300 } | 310 } |
301 | 311 |
(...skipping 21 matching lines...) Expand all Loading... | |
323 // SetSurface() can't be called before Initialize(), so we pick up our first | 333 // SetSurface() can't be called before Initialize(), so we pick up our first |
324 // surface ID from the codec configuration. | 334 // surface ID from the codec configuration. |
325 DCHECK(!pending_surface_id_); | 335 DCHECK(!pending_surface_id_); |
326 | 336 |
327 // We signaled that we support deferred initialization, so see if the client | 337 // We signaled that we support deferred initialization, so see if the client |
328 // does also. | 338 // does also. |
329 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 339 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
330 | 340 |
331 // If we're low on resources, we may decide to defer creation of the surface | 341 // If we're low on resources, we may decide to defer creation of the surface |
332 // until the codec is actually used. | 342 // until the codec is actually used. |
333 if (ShouldDeferSurfaceCreation(codec_allocator_, surface_id(), | 343 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, |
334 codec_config_->codec)) { | 344 codec_config_->codec, platform_config_)) { |
335 // We should never be here if a SurfaceView is required. | 345 // We should never be here if a SurfaceView is required. |
336 DCHECK_EQ(surface_id(), SurfaceManager::kNoSurfaceID); | 346 // TODO(liberato): This really isn't true with AndroidOverlay. |
347 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | |
337 defer_surface_creation_ = true; | 348 defer_surface_creation_ = true; |
338 } | 349 } |
339 | 350 |
340 if (!codec_allocator_->StartThread(this)) { | 351 if (!codec_allocator_->StartThread(this)) { |
341 LOG(ERROR) << "Unable to start thread"; | 352 LOG(ERROR) << "Unable to start thread"; |
342 return false; | 353 return false; |
343 } | 354 } |
344 | 355 |
345 // For encrypted media, start by initializing the CDM. Otherwise, start with | 356 // For encrypted media, start by initializing the CDM. Otherwise, start with |
346 // the surface. | 357 // the surface. |
347 if (config_.is_encrypted()) { | 358 if (config_.is_encrypted()) { |
348 if (!deferred_initialization_pending_) { | 359 if (!deferred_initialization_pending_) { |
349 DLOG(ERROR) | 360 DLOG(ERROR) |
350 << "Deferred initialization must be used for encrypted streams"; | 361 << "Deferred initialization must be used for encrypted streams"; |
351 return false; | 362 return false; |
352 } | 363 } |
353 InitializeCdm(); | 364 InitializeCdm(); |
354 } else { | 365 } else { |
355 StartSurfaceCreation(); | 366 StartOverlayHelper(); |
watk
2017/05/02 21:00:01
s/OverlayHelper/SurfaceChooser/
s/overlay helper/s
liberato (no reviews please)
2017/05/02 21:50:04
Done.
| |
356 } | 367 } |
357 | 368 |
358 // Fail / complete / defer initialization. | 369 // Fail / complete / defer initialization. |
359 return state_ != ERROR; | 370 return state_ != ERROR; |
360 } | 371 } |
361 | 372 |
362 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { | 373 void AndroidVideoDecodeAccelerator::StartOverlayHelper() { |
363 // We might be called during Initialize, during deferred initialization, or | 374 DCHECK_EQ(state_, BEFORE_OVERLAY_INIT); |
364 // afterwards (::Decode, for deferred surface init, UpdateSurface). | |
365 DCHECK(incoming_bundle_); | |
366 | 375 |
367 // We should not yet have an overlay. | 376 // If we're trying to defer surface creation, then don't notify the helper |
368 DCHECK(!incoming_bundle_->overlay); | 377 // that it may start getting surfaces yet. We'll do that later. |
369 | |
370 // Note that we don't enforce that for any SurfaceTexture or its Surface, | |
371 // since there might be a codec that's using them. They'll get cleared | |
372 // later, in InitializePictureBufferManager. | |
373 | |
374 // If surface creation is deferred, then do nothing except signal that init | |
375 // is complete, if needed. We might still fail to get a surface or codec, | |
376 // which would normally be an init error. Since we're deferring init until a | |
377 // decode to save resources, though, we're signaling success now. If we're | |
378 // wrong, then decoding might fail when we might have been able to use a | |
379 // fallback renderer in WMPI if we failed init. | |
380 if (defer_surface_creation_) { | 378 if (defer_surface_creation_) { |
381 if (deferred_initialization_pending_) | 379 if (deferred_initialization_pending_) |
382 NotifyInitializationSucceeded(); | 380 NotifyInitializationSucceeded(); |
383 | |
384 return; | 381 return; |
385 } | 382 } |
386 | 383 |
387 if (incoming_bundle_->surface_id != SurfaceManager::kNoSurfaceID) { | 384 // Handle the sync path, which must use SurfaceTexture anyway. Note that we |
388 // Create the overlay. Note that it will never call us back immediately. | 385 // check both |during_initialize_| and |deferred_initialization_pending_|, |
389 // It will post when the surface is available. | 386 // since we might get here during deferred surface creation. In that case, |
390 AndroidOverlay::Config overlay_config; | 387 // Decode will call us (after clearing |defer_surface_creation_|), but |
391 // We use weak ptrs here since |overlay| can outlive us, if we send it for | 388 // deferred init will have already been signaled optimistically as success. |
392 // async codec config. | 389 // |
393 overlay_config.ready_cb = | 390 // Also note that we might choose to defer surface creation for the sync path, |
394 base::Bind(&AndroidVideoDecodeAccelerator::OnOverlayReady, | 391 // which won't get here. We'll exit above, successfully, during init, and |
395 weak_this_factory_.GetWeakPtr()); | 392 // will fall through to the below when Decode calls us back. That's okay. |
396 overlay_config.failed_cb = | 393 // We only handle this case specially since |surface_chooser_| is allowed to |
397 base::Bind(&AndroidVideoDecodeAccelerator::OnOverlayFailed, | 394 // post callbacks to us. Here, we guarantee that the sync case is actually |
398 weak_this_factory_.GetWeakPtr()); | 395 // resolved synchronously. The only exception will be if we need to defer |
399 overlay_config.destroyed_cb = | 396 // surface creation for other reasons, in which case the sync path with just |
400 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceDestroyed, | 397 // signal success optimistically. |
401 weak_this_factory_.GetWeakPtr()); | 398 if (during_initialize_ && !deferred_initialization_pending_) { |
402 // TODO(liberato): make |surface_id| the overlay config token. If we're | 399 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); |
403 // using CVV, then we'll need a CVV factory impl that understands it. | 400 OnSurfaceTransition(nullptr); |
404 incoming_bundle_->overlay = base::MakeUnique<ContentVideoViewOverlay>( | |
405 incoming_bundle_->surface_id, overlay_config); | |
406 // We have to wait for some other AVDA instance to free up the surface. | |
407 // OnOverlayReady will be called when it's available. | |
408 // Note that if we aren't deferring init, then we'll signal success, and | |
409 // if we fail later then it will fail decoding instead. However, since | |
410 // nobody that provides a SurfaceView requires sync init, it doesn't matter. | |
411 // Also remember that ContentVideoViewOverlay will not call OnOverlayReady | |
412 // before it returns. | |
413 state_ = WAITING_FOR_SURFACE; | |
414 return; | 401 return; |
415 } | 402 } |
416 | 403 |
417 // We're creating a SurfaceTexture. | 404 // If we have a surface, then notify |surface_chooser_| about it. |
418 InitializePictureBufferManager(); | 405 std::unique_ptr<AndroidOverlayFactory> factory; |
406 if (config_.surface_id != SurfaceManager::kNoSurfaceID) { | |
407 factory = | |
408 base::MakeUnique<ContentVideoViewOverlayFactory>(config_.surface_id); | |
409 } | |
410 | |
411 // Notify |surface_chooser_| that we've started. This guarantees that we'll | |
412 // get a callback. It might not be a synchronous callback, but we're not in | |
413 // the synchronous case. It will be soon, though. For pre-M, we rely on the | |
414 // fact that |surface_chooser_| won't tell us to use a SurfaceTexture while | |
415 // waiting for an overlay to become ready, for example. | |
416 surface_chooser_->Initialize( | |
417 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceTransition, | |
418 weak_this_factory_.GetWeakPtr()), | |
419 base::Bind(&AndroidVideoDecodeAccelerator::OnSurfaceTransition, | |
420 weak_this_factory_.GetWeakPtr(), nullptr), | |
421 base::Bind(&AndroidVideoDecodeAccelerator::OnStopUsingOverlayImmediately, | |
422 weak_this_factory_.GetWeakPtr()), | |
423 std::move(factory)); | |
419 } | 424 } |
420 | 425 |
421 void AndroidVideoDecodeAccelerator::OnOverlayReady(AndroidOverlay* overlay) { | 426 void AndroidVideoDecodeAccelerator::OnSurfaceTransition( |
422 DCHECK(!defer_surface_creation_); | 427 std::unique_ptr<AndroidOverlay> overlay) { |
423 DCHECK_EQ(state_, WAITING_FOR_SURFACE); | 428 // If we're waiting for a surface (e.g., during startup), then proceed |
424 DCHECK(incoming_bundle_); | 429 // immediately. Otherwise, wait for Dequeue to handle it. This can probably |
430 // be merged with UpdateSurface. | |
431 if (state_ == BEFORE_OVERLAY_INIT) { | |
432 DCHECK(!incoming_overlay_); | |
433 incoming_bundle_ = new AVDASurfaceBundle(std::move(overlay)); | |
434 InitializePictureBufferManager(); | |
435 return; | |
436 } | |
425 | 437 |
426 InitializePictureBufferManager(); | 438 // If, for some reason, |surface_chooser_| decides that we really should |
427 } | 439 // change our output surface pre-M, ignore it. For example, if the |
440 // compositor tells us that it can't use an overlay, well, there's not much | |
441 // that we can do here unless we start falling forward to keyframes. | |
442 if (!platform_config_.allow_setsurface) | |
443 return; | |
428 | 444 |
429 void AndroidVideoDecodeAccelerator::OnOverlayFailed(AndroidOverlay* overlay) { | 445 // If we're using a SurfaceTexture and are told to switch to one, then just |
430 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); | 446 // do nothing. |surface_chooser_| doesn't really know if we've switched to |
447 // SurfaceTexture or not. Note that it can't ask us to switch to the same | |
448 // overlay we're using, since it's unique_ptr. | |
449 if (!overlay && codec_config_->surface_bundle && | |
450 !codec_config_->surface_bundle->overlay) { | |
451 // Also stop transitioning to an overlay, if we were doing so. | |
452 incoming_overlay_.reset(); | |
453 return; | |
454 } | |
455 | |
456 incoming_overlay_ = std::move(overlay); | |
431 } | 457 } |
432 | 458 |
433 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 459 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
434 DCHECK(!defer_surface_creation_); | 460 DCHECK(!defer_surface_creation_); |
435 DCHECK(incoming_bundle_); | 461 DCHECK(incoming_bundle_); |
436 | 462 |
437 if (!make_context_current_cb_.Run()) { | 463 if (!make_context_current_cb_.Run()) { |
438 NOTIFY_ERROR(PLATFORM_FAILURE, | 464 NOTIFY_ERROR(PLATFORM_FAILURE, |
439 "Failed to make this decoder's GL context current"); | 465 "Failed to make this decoder's GL context current"); |
440 incoming_bundle_ = nullptr; | 466 incoming_bundle_ = nullptr; |
(...skipping 25 matching lines...) Expand all Loading... | |
466 // do not try to allocate a new codec; we might not be at a keyframe, etc. | 492 // do not try to allocate a new codec; we might not be at a keyframe, etc. |
467 // If we get here with a codec, then we must setSurface. | 493 // If we get here with a codec, then we must setSurface. |
468 if (media_codec_) { | 494 if (media_codec_) { |
469 // TODO(liberato): fail on api check? | 495 // TODO(liberato): fail on api check? |
470 if (!media_codec_->SetSurface(incoming_bundle_->j_surface().obj())) { | 496 if (!media_codec_->SetSurface(incoming_bundle_->j_surface().obj())) { |
471 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 497 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
472 // We're not going to use |incoming_bundle_|. | 498 // We're not going to use |incoming_bundle_|. |
473 } else { | 499 } else { |
474 // We've switched surfaces, so replace |surface_bundle|. | 500 // We've switched surfaces, so replace |surface_bundle|. |
475 codec_config_->surface_bundle = incoming_bundle_; | 501 codec_config_->surface_bundle = incoming_bundle_; |
476 // We could be in WAITING_FOR_SURFACE, but we're not anymore. | 502 // We could be in BEFORE_OVERLAY_INIT, but we're not anymore. |
477 state_ = NO_ERROR; | 503 state_ = NO_ERROR; |
478 } | 504 } |
479 incoming_bundle_ = nullptr; | 505 incoming_bundle_ = nullptr; |
480 return; | 506 return; |
481 } | 507 } |
482 | 508 |
483 // We're going to create a codec with |incoming_bundle_|. It might fail, but | 509 // We're going to create a codec with |incoming_bundle_|. It might fail, but |
484 // either way, we're done with any previous bundle. Note that, since we | 510 // either way, we're done with any previous bundle. Note that, since we |
485 // never get here after init (i.e., we never change surfaces without using | 511 // never get here after init (i.e., we never change surfaces without using |
486 // SetSurface), there shouldn't be any previous bundle. However, this is the | 512 // SetSurface), there shouldn't be any previous bundle. However, this is the |
487 // right thing to do even if we can switch. | 513 // right thing to do even if we can switch. |
488 codec_config_->surface_bundle = incoming_bundle_; | 514 codec_config_->surface_bundle = incoming_bundle_; |
489 incoming_bundle_ = nullptr; | 515 incoming_bundle_ = nullptr; |
490 | 516 |
491 // If the client doesn't support deferred initialization (WebRTC), then we | 517 // If the client doesn't support deferred initialization (WebRTC), then we |
492 // should complete it now and return a meaningful result. Note that it would | 518 // should complete it now and return a meaningful result. Note that it would |
493 // be nice if we didn't have to worry about starting codec configuration at | 519 // be nice if we didn't have to worry about starting codec configuration at |
494 // all (::Initialize or the wrapper can do it), but then they have to remember | 520 // all (::Initialize or the wrapper can do it), but then they have to remember |
495 // not to start codec config if we have to wait for the cdm. It's somewhat | 521 // not to start codec config if we have to wait for the cdm. It's somewhat |
496 // clearer for us to handle both cases. | 522 // clearer for us to handle both cases. |
497 // For this to be a case for sync configuration, we must be called from | 523 // For this to be a case for sync configuration, we must be called from |
498 // Initialize(), and the client must not want deferred init. Note that having | 524 // Initialize(), and the client must not want deferred init. Note that having |
499 // |deferred_initialization_pending_| false by itself isn't enough; if we're | 525 // |deferred_initialization_pending_| false by itself isn't enough; if we're |
500 // deferring surface creation, then we'll finish deferred init before asking | 526 // deferring surface creation, then we'll finish deferred init before asking |
501 // for the surface. We'll be called via ::Decode. | 527 // for the surface. We'll be called via Decode. |
502 if (during_initialize_ && !deferred_initialization_pending_) { | 528 if (during_initialize_ && !deferred_initialization_pending_) { |
503 ConfigureMediaCodecSynchronously(); | 529 ConfigureMediaCodecSynchronously(); |
504 return; | 530 return; |
505 } | 531 } |
506 | 532 |
507 // In all other cases, we don't have to wait for the codec. | 533 // In all other cases, we don't have to wait for the codec. |
508 ConfigureMediaCodecAsynchronously(); | 534 ConfigureMediaCodecAsynchronously(); |
509 } | 535 } |
510 | 536 |
511 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { | 537 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { |
512 DCHECK(thread_checker_.CalledOnValidThread()); | 538 DCHECK(thread_checker_.CalledOnValidThread()); |
513 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 539 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
514 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || | 540 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
515 state_ == SURFACE_DESTROYED || state_ == WAITING_FOR_SURFACE) { | 541 state_ == SURFACE_DESTROYED || state_ == BEFORE_OVERLAY_INIT) { |
516 return; | 542 return; |
517 } | 543 } |
518 | 544 |
519 picture_buffer_manager_.MaybeRenderEarly(); | 545 picture_buffer_manager_.MaybeRenderEarly(); |
520 bool did_work = false, did_input = false, did_output = false; | 546 bool did_work = false, did_input = false, did_output = false; |
521 do { | 547 do { |
522 did_input = QueueInput(); | 548 did_input = QueueInput(); |
523 did_output = DequeueOutput(); | 549 did_output = DequeueOutput(); |
524 if (did_input || did_output) | 550 if (did_input || did_output) |
525 did_work = true; | 551 did_work = true; |
526 } while (did_input || did_output); | 552 } while (did_input || did_output); |
527 | 553 |
528 ManageTimer(did_work || start_timer); | 554 ManageTimer(did_work || start_timer); |
529 } | 555 } |
530 | 556 |
531 bool AndroidVideoDecodeAccelerator::QueueInput() { | 557 bool AndroidVideoDecodeAccelerator::QueueInput() { |
532 DCHECK(thread_checker_.CalledOnValidThread()); | 558 DCHECK(thread_checker_.CalledOnValidThread()); |
533 TRACE_EVENT0("media", "AVDA::QueueInput"); | 559 TRACE_EVENT0("media", "AVDA::QueueInput"); |
534 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || | 560 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
535 state_ == WAITING_FOR_KEY || state_ == WAITING_FOR_SURFACE) { | 561 state_ == WAITING_FOR_KEY || state_ == BEFORE_OVERLAY_INIT) { |
536 return false; | 562 return false; |
537 } | 563 } |
538 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) | 564 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) |
539 return false; | 565 return false; |
540 if (pending_bitstream_records_.empty()) | 566 if (pending_bitstream_records_.empty()) |
541 return false; | 567 return false; |
542 | 568 |
543 int input_buf_index = pending_input_buf_index_; | 569 int input_buf_index = pending_input_buf_index_; |
544 | 570 |
545 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY. | 571 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 return false; | 682 return false; |
657 } | 683 } |
658 | 684 |
659 return true; | 685 return true; |
660 } | 686 } |
661 | 687 |
662 bool AndroidVideoDecodeAccelerator::DequeueOutput() { | 688 bool AndroidVideoDecodeAccelerator::DequeueOutput() { |
663 DCHECK(thread_checker_.CalledOnValidThread()); | 689 DCHECK(thread_checker_.CalledOnValidThread()); |
664 TRACE_EVENT0("media", "AVDA::DequeueOutput"); | 690 TRACE_EVENT0("media", "AVDA::DequeueOutput"); |
665 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || | 691 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
666 state_ == WAITING_FOR_SURFACE) { | 692 state_ == BEFORE_OVERLAY_INIT) { |
667 return false; | 693 return false; |
668 } | 694 } |
669 // If we're draining for reset or destroy, then we don't need picture buffers | 695 // If we're draining for reset or destroy, then we don't need picture buffers |
670 // since we won't send any decoded frames anyway. There might not be any, | 696 // since we won't send any decoded frames anyway. There might not be any, |
671 // since the pipeline might not be sending them back and / or they don't | 697 // since the pipeline might not be sending them back and / or they don't |
672 // exist anymore. From the pipeline's point of view, for Destroy at least, | 698 // exist anymore. From the pipeline's point of view, for Destroy at least, |
673 // the VDA is already gone. | 699 // the VDA is already gone. |
674 if (picturebuffers_requested_ && output_picture_buffers_.empty() && | 700 if (picturebuffers_requested_ && output_picture_buffers_.empty() && |
675 !IsDrainingForResetOrDestroy()) { | 701 !IsDrainingForResetOrDestroy()) { |
676 return false; | 702 return false; |
677 } | 703 } |
678 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && | 704 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && |
679 !IsDrainingForResetOrDestroy()) { | 705 !IsDrainingForResetOrDestroy()) { |
680 // Don't have any picture buffer to send. Need to wait. | 706 // Don't have any picture buffer to send. Need to wait. |
681 return false; | 707 return false; |
682 } | 708 } |
683 | 709 |
684 // If we're waiting to switch surfaces pause output release until we have all | 710 // If we're waiting to switch surfaces pause output release until we have all |
685 // picture buffers returned. This is so we can ensure the right flags are set | 711 // picture buffers returned. This is so we can ensure the right flags are set |
686 // on the picture buffers returned to the client. | 712 // on the picture buffers returned to the client. |
687 if (pending_surface_id_) { | 713 if (incoming_overlay_) { |
688 if (picture_buffer_manager_.HasUnrenderedPictures()) | 714 if (picture_buffer_manager_.HasUnrenderedPictures()) |
689 return false; | 715 return false; |
690 if (!UpdateSurface()) | 716 if (!UpdateSurface()) |
691 return false; | 717 return false; |
692 // If we can't allocate the incoming surface yet, then stop here. | 718 |
693 if (state_ != NO_ERROR) | 719 // UpdateSurface should fail if we've transitioned to the error state. |
694 return false; | 720 DCHECK(state_ == NO_ERROR); |
695 } | 721 } |
696 | 722 |
697 bool eos = false; | 723 bool eos = false; |
698 base::TimeDelta presentation_timestamp; | 724 base::TimeDelta presentation_timestamp; |
699 int32_t buf_index = 0; | 725 int32_t buf_index = 0; |
700 do { | 726 do { |
701 size_t offset = 0; | 727 size_t offset = 0; |
702 size_t size = 0; | 728 size_t size = 0; |
703 | 729 |
704 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); | 730 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
877 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index, | 903 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index, |
878 picture_buffer); | 904 picture_buffer); |
879 } | 905 } |
880 | 906 |
881 void AndroidVideoDecodeAccelerator::Decode( | 907 void AndroidVideoDecodeAccelerator::Decode( |
882 const BitstreamBuffer& bitstream_buffer) { | 908 const BitstreamBuffer& bitstream_buffer) { |
883 DCHECK(thread_checker_.CalledOnValidThread()); | 909 DCHECK(thread_checker_.CalledOnValidThread()); |
884 | 910 |
885 // If we deferred getting a surface, then start getting one now. | 911 // If we deferred getting a surface, then start getting one now. |
886 if (defer_surface_creation_) { | 912 if (defer_surface_creation_) { |
887 // This is a little strange in that we're not really waiting for a surface | 913 // We should still be in BEFORE_OVERLAY_INIT, since we've deferred doing it |
888 // yet -- we haven't requested one. We're still in WAITING_FOR_SURFACE as | 914 // until now. |
889 // the initial state set during construction. | 915 DCHECK_EQ(state_, BEFORE_OVERLAY_INIT); |
890 DCHECK_EQ(state_, WAITING_FOR_SURFACE); | |
891 defer_surface_creation_ = false; | 916 defer_surface_creation_ = false; |
892 StartSurfaceCreation(); | 917 StartOverlayHelper(); |
893 if (state_ == ERROR) { | 918 if (state_ == ERROR) { |
894 DLOG(ERROR) << "Failed deferred surface and MediaCodec initialization."; | 919 DLOG(ERROR) << "Failed deferred surface and MediaCodec initialization."; |
895 return; | 920 return; |
896 } | 921 } |
897 } | 922 } |
898 | 923 |
899 // If we previously deferred a codec restart, take care of it now. This can | 924 // If we previously deferred a codec restart, take care of it now. This can |
900 // happen on older devices where configuration changes require a codec reset. | 925 // happen on older devices where configuration changes require a codec reset. |
901 if (codec_needs_reset_) { | 926 if (codec_needs_reset_) { |
902 DCHECK(!drain_type_); | 927 DCHECK(!drain_type_); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
990 } | 1015 } |
991 | 1016 |
992 void AndroidVideoDecodeAccelerator::Flush() { | 1017 void AndroidVideoDecodeAccelerator::Flush() { |
993 DVLOG(1) << __func__; | 1018 DVLOG(1) << __func__; |
994 DCHECK(thread_checker_.CalledOnValidThread()); | 1019 DCHECK(thread_checker_.CalledOnValidThread()); |
995 StartCodecDrain(DRAIN_FOR_FLUSH); | 1020 StartCodecDrain(DRAIN_FOR_FLUSH); |
996 } | 1021 } |
997 | 1022 |
998 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 1023 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
999 DCHECK(thread_checker_.CalledOnValidThread()); | 1024 DCHECK(thread_checker_.CalledOnValidThread()); |
1025 DCHECK(!media_codec_); | |
1000 | 1026 |
1001 DCHECK_NE(state_, WAITING_FOR_CODEC); | 1027 DCHECK_NE(state_, WAITING_FOR_CODEC); |
1002 state_ = WAITING_FOR_CODEC; | 1028 state_ = WAITING_FOR_CODEC; |
1003 | 1029 |
1004 ReleaseCodec(); | |
1005 | |
1006 base::Optional<TaskType> task_type = | 1030 base::Optional<TaskType> task_type = |
1007 codec_allocator_->TaskTypeForAllocation(); | 1031 codec_allocator_->TaskTypeForAllocation(); |
1008 if (!task_type) { | 1032 if (!task_type) { |
1009 // If there is no free thread, then just fail. | 1033 // If there is no free thread, then just fail. |
1010 OnCodecConfigured(nullptr); | 1034 OnCodecConfigured(nullptr); |
1011 return; | 1035 return; |
1012 } | 1036 } |
1013 | 1037 |
1014 // If autodetection is disallowed, fall back to Chrome's software decoders | 1038 // If autodetection is disallowed, fall back to Chrome's software decoders |
1015 // instead of using the software decoders provided by MediaCodec. | 1039 // instead of using the software decoders provided by MediaCodec. |
(...skipping 17 matching lines...) Expand all Loading... | |
1033 base::Optional<TaskType> task_type = | 1057 base::Optional<TaskType> task_type = |
1034 codec_allocator_->TaskTypeForAllocation(); | 1058 codec_allocator_->TaskTypeForAllocation(); |
1035 if (!task_type) { | 1059 if (!task_type) { |
1036 // If there is no free thread, then just fail. | 1060 // If there is no free thread, then just fail. |
1037 OnCodecConfigured(nullptr); | 1061 OnCodecConfigured(nullptr); |
1038 return; | 1062 return; |
1039 } | 1063 } |
1040 | 1064 |
1041 codec_config_->task_type = task_type.value(); | 1065 codec_config_->task_type = task_type.value(); |
1042 std::unique_ptr<MediaCodecBridge> media_codec = | 1066 std::unique_ptr<MediaCodecBridge> media_codec = |
1043 AVDACodecAllocator::GetInstance()->CreateMediaCodecSync(codec_config_); | 1067 codec_allocator_->CreateMediaCodecSync(codec_config_); |
1044 // Note that |media_codec| might be null, which will NotifyError. | 1068 // Note that |media_codec| might be null, which will NotifyError. |
1045 OnCodecConfigured(std::move(media_codec)); | 1069 OnCodecConfigured(std::move(media_codec)); |
1046 } | 1070 } |
1047 | 1071 |
1048 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 1072 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
1049 std::unique_ptr<MediaCodecBridge> media_codec) { | 1073 std::unique_ptr<MediaCodecBridge> media_codec) { |
1050 DCHECK(thread_checker_.CalledOnValidThread()); | 1074 DCHECK(thread_checker_.CalledOnValidThread()); |
1051 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 1075 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
1052 // If we are supposed to notify that initialization is complete, then do so | 1076 // If we are supposed to notify that initialization is complete, then do so |
1053 // before returning. Otherwise, this is a reconfiguration. | 1077 // before returning. Otherwise, this is a reconfiguration. |
1054 | 1078 |
1079 DCHECK(!media_codec_); | |
1080 media_codec_ = std::move(media_codec); | |
1081 | |
1055 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, | 1082 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, |
1056 // then the codec is already invalid so we return early and drop it. | 1083 // then the codec is already invalid so we return early and drop it. |
1057 // TODO(liberato): We're going to drop the codec when |media_codec| goes out | |
1058 // of scope, on this thread. We really should post it to the proper thread | |
1059 // to avoid potentially hanging. | |
1060 if (state_ == SURFACE_DESTROYED) { | 1084 if (state_ == SURFACE_DESTROYED) { |
1061 if (deferred_initialization_pending_) { | 1085 if (deferred_initialization_pending_) { |
1062 // Losing the output surface is not considered an error state, so notify | 1086 // Losing the output surface is not considered an error state, so notify |
1063 // success. The client will destroy this soon. | 1087 // success. The client will destroy |this| soon. |
1064 NotifyInitializationSucceeded(); | 1088 NotifyInitializationSucceeded(); |
1065 } | 1089 } |
1090 | |
1091 // Post it to the right thread. | |
1092 ReleaseCodecAndBundle(); | |
1066 return; | 1093 return; |
1067 } | 1094 } |
1068 | 1095 |
1069 DCHECK(!media_codec_); | |
1070 media_codec_ = std::move(media_codec); | |
1071 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1096 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1072 if (!media_codec_) { | 1097 if (!media_codec_) { |
1073 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec"); | 1098 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec"); |
1074 return; | 1099 return; |
1075 } | 1100 } |
1076 | 1101 |
1077 if (deferred_initialization_pending_) | 1102 if (deferred_initialization_pending_) |
1078 NotifyInitializationSucceeded(); | 1103 NotifyInitializationSucceeded(); |
1079 | 1104 |
1080 state_ = NO_ERROR; | 1105 state_ = NO_ERROR; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1150 } | 1175 } |
1151 drain_type_.reset(); | 1176 drain_type_.reset(); |
1152 } | 1177 } |
1153 | 1178 |
1154 void AndroidVideoDecodeAccelerator::ResetCodecState() { | 1179 void AndroidVideoDecodeAccelerator::ResetCodecState() { |
1155 DCHECK(thread_checker_.CalledOnValidThread()); | 1180 DCHECK(thread_checker_.CalledOnValidThread()); |
1156 | 1181 |
1157 // If there is already a reset in flight, then that counts. This can really | 1182 // If there is already a reset in flight, then that counts. This can really |
1158 // only happen if somebody calls Reset. | 1183 // only happen if somebody calls Reset. |
1159 // If the surface is destroyed or we're in an error state there's nothing to | 1184 // If the surface is destroyed or we're in an error state there's nothing to |
1160 // do. Note that WAITING_FOR_SURFACE implies that we have no codec, but it's | 1185 // do. Note that BEFORE_OVERLAY_INIT implies that we have no codec, but it's |
1161 // included for completeness. | 1186 // included for completeness. |
1162 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED || | 1187 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED || |
1163 state_ == WAITING_FOR_SURFACE || state_ == ERROR || !media_codec_) { | 1188 state_ == BEFORE_OVERLAY_INIT || state_ == ERROR || !media_codec_) { |
1164 return; | 1189 return; |
1165 } | 1190 } |
1166 | 1191 |
1167 bitstream_buffers_in_decoder_.clear(); | 1192 bitstream_buffers_in_decoder_.clear(); |
1168 | 1193 |
1169 if (pending_input_buf_index_ != -1) { | 1194 if (pending_input_buf_index_ != -1) { |
1170 // The data for that index exists in the input buffer, but corresponding | 1195 // The data for that index exists in the input buffer, but corresponding |
1171 // shm block been deleted. Check that it is safe to flush the codec, i.e. | 1196 // shm block been deleted. Check that it is safe to flush the codec, i.e. |
1172 // |pending_bitstream_records_| is empty. | 1197 // |pending_bitstream_records_| is empty. |
1173 // TODO(timav): keep shm block for that buffer and remove this restriction. | 1198 // TODO(timav): keep shm block for that buffer and remove this restriction. |
(...skipping 12 matching lines...) Expand all Loading... | |
1186 // Flush the codec if possible, or create a new one if not. | 1211 // Flush the codec if possible, or create a new one if not. |
1187 if (!MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 1212 if (!MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
1188 DVLOG(3) << __func__ << " Flushing MediaCodec."; | 1213 DVLOG(3) << __func__ << " Flushing MediaCodec."; |
1189 media_codec_->Flush(); | 1214 media_codec_->Flush(); |
1190 // Since we just flushed all the output buffers, make sure that nothing is | 1215 // Since we just flushed all the output buffers, make sure that nothing is |
1191 // using them. | 1216 // using them. |
1192 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1217 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1193 } else { | 1218 } else { |
1194 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; | 1219 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; |
1195 GetManager()->StopTimer(this); | 1220 GetManager()->StopTimer(this); |
1196 // Note that this will release the codec, then allocate a new one. It will | 1221 // Release the codec, retain the bundle, and allocate a new codec. It will |
1197 // not wait for the old one to finish up with the surface, which is bad. | 1222 // not wait for the old one to finish up with the bundle, which is bad. It |
1198 // It works (usually) because it ends up allocating the codec on the same | 1223 // works (usually) because it ends up allocating the codec on the same |
1199 // thread as is used to release the old one, so it's serialized anyway. | 1224 // thread as is used to release the old one, so it's serialized anyway. |
1225 ReleaseCodec(); | |
1200 ConfigureMediaCodecAsynchronously(); | 1226 ConfigureMediaCodecAsynchronously(); |
1201 } | 1227 } |
1202 } | 1228 } |
1203 | 1229 |
1204 void AndroidVideoDecodeAccelerator::Reset() { | 1230 void AndroidVideoDecodeAccelerator::Reset() { |
1205 DVLOG(1) << __func__; | 1231 DVLOG(1) << __func__; |
1206 DCHECK(thread_checker_.CalledOnValidThread()); | 1232 DCHECK(thread_checker_.CalledOnValidThread()); |
1207 TRACE_EVENT0("media", "AVDA::Reset"); | 1233 TRACE_EVENT0("media", "AVDA::Reset"); |
1208 | 1234 |
1209 if (defer_surface_creation_) { | 1235 if (defer_surface_creation_) { |
1210 DCHECK(!media_codec_); | 1236 DCHECK(!media_codec_); |
1211 DCHECK(pending_bitstream_records_.empty()); | 1237 DCHECK(pending_bitstream_records_.empty()); |
1212 DCHECK_EQ(state_, WAITING_FOR_SURFACE); | 1238 DCHECK_EQ(state_, BEFORE_OVERLAY_INIT); |
1213 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1239 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1214 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1240 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
1215 weak_this_factory_.GetWeakPtr())); | 1241 weak_this_factory_.GetWeakPtr())); |
1216 return; | 1242 return; |
1217 } | 1243 } |
1218 | 1244 |
1219 while (!pending_bitstream_records_.empty()) { | 1245 while (!pending_bitstream_records_.empty()) { |
1220 int32_t bitstream_buffer_id = | 1246 int32_t bitstream_buffer_id = |
1221 pending_bitstream_records_.front().buffer.id(); | 1247 pending_bitstream_records_.front().buffer.id(); |
1222 pending_bitstream_records_.pop(); | 1248 pending_bitstream_records_.pop(); |
1223 | 1249 |
1224 if (bitstream_buffer_id != -1) { | 1250 if (bitstream_buffer_id != -1) { |
1225 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1251 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1226 FROM_HERE, | 1252 FROM_HERE, |
1227 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, | 1253 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, |
1228 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); | 1254 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); |
1229 } | 1255 } |
1230 } | 1256 } |
1231 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); | 1257 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); |
1232 bitstreams_notified_in_advance_.clear(); | 1258 bitstreams_notified_in_advance_.clear(); |
1233 | 1259 |
1234 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1260 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
1235 StartCodecDrain(DRAIN_FOR_RESET); | 1261 StartCodecDrain(DRAIN_FOR_RESET); |
1236 } | 1262 } |
1237 | 1263 |
1238 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | 1264 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
1239 DVLOG(1) << __func__; | 1265 DVLOG(1) << __func__; |
1240 DCHECK(thread_checker_.CalledOnValidThread()); | 1266 DCHECK(thread_checker_.CalledOnValidThread()); |
1241 | 1267 |
1242 if (surface_id == this->surface_id()) { | 1268 // It's possible that we'll receive a SetSurface before initializing the |
1243 pending_surface_id_.reset(); | 1269 // overlay helper. For example, if we defer surface creation, then we'll |
1270 // signal success to WMPI before initializing it. WMPI is free to change the | |
1271 // surface. In this case, just pretend that |surface_id| is the initial one. | |
1272 if (state_ == BEFORE_OVERLAY_INIT) { | |
1273 config_.surface_id = surface_id; | |
1244 return; | 1274 return; |
1245 } | 1275 } |
1246 | 1276 |
1247 // Surface changes never take effect immediately, they will be handled during | 1277 std::unique_ptr<AndroidOverlayFactory> factory; |
1248 // DequeOutput() once we get to a good switch point or immediately during an | 1278 if (surface_id != SurfaceManager::kNoSurfaceID) |
1249 // OnSurfaceDestroyed() call. | 1279 factory = base::MakeUnique<ContentVideoViewOverlayFactory>(surface_id); |
1250 pending_surface_id_ = surface_id; | 1280 |
1281 surface_chooser_->ReplaceOverlayFactory(std::move(factory)); | |
1251 } | 1282 } |
1252 | 1283 |
1253 void AndroidVideoDecodeAccelerator::Destroy() { | 1284 void AndroidVideoDecodeAccelerator::Destroy() { |
1254 DVLOG(1) << __func__; | 1285 DVLOG(1) << __func__; |
1255 DCHECK(thread_checker_.CalledOnValidThread()); | 1286 DCHECK(thread_checker_.CalledOnValidThread()); |
1256 | 1287 |
1257 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1288 picture_buffer_manager_.Destroy(output_picture_buffers_); |
1258 client_ = nullptr; | 1289 client_ = nullptr; |
1259 | 1290 |
1260 // We don't want to queue more inputs while draining. | 1291 // We don't want to queue more inputs while draining. |
1261 std::queue<BitstreamRecord>().swap(pending_bitstream_records_); | 1292 std::queue<BitstreamRecord>().swap(pending_bitstream_records_); |
1262 StartCodecDrain(DRAIN_FOR_DESTROY); | 1293 StartCodecDrain(DRAIN_FOR_DESTROY); |
1263 } | 1294 } |
1264 | 1295 |
1265 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1296 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
1266 DVLOG(1) << __func__; | 1297 DVLOG(1) << __func__; |
1267 DCHECK(thread_checker_.CalledOnValidThread()); | 1298 DCHECK(thread_checker_.CalledOnValidThread()); |
1268 | 1299 |
1269 // Note that async codec construction might still be in progress. In that | 1300 // Note that async codec construction might still be in progress. In that |
1270 // case, the codec will be deleted when it completes once we invalidate all | 1301 // case, the codec will be deleted when it completes once we invalidate all |
1271 // our weak refs. | 1302 // our weak refs. |
1272 weak_this_factory_.InvalidateWeakPtrs(); | 1303 weak_this_factory_.InvalidateWeakPtrs(); |
1273 GetManager()->StopTimer(this); | 1304 GetManager()->StopTimer(this); |
1274 ReleaseCodec(); | 1305 ReleaseCodecAndBundle(); |
1275 | 1306 |
1276 delete this; | 1307 delete this; |
1277 } | 1308 } |
1278 | 1309 |
1279 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1310 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
1280 const base::WeakPtr<Client>& decode_client, | 1311 const base::WeakPtr<Client>& decode_client, |
1281 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1312 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
1282 return false; | 1313 return false; |
1283 } | 1314 } |
1284 | 1315 |
1285 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 1316 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
1286 return size_; | 1317 return size_; |
1287 } | 1318 } |
1288 | 1319 |
1289 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1320 base::WeakPtr<gpu::gles2::GLES2Decoder> |
1290 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1321 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
1291 return get_gles2_decoder_cb_.Run(); | 1322 return get_gles2_decoder_cb_.Run(); |
1292 } | 1323 } |
1293 | 1324 |
1294 void AndroidVideoDecodeAccelerator::OnSurfaceDestroyed( | 1325 void AndroidVideoDecodeAccelerator::OnStopUsingOverlayImmediately( |
1295 AndroidOverlay* overlay) { | 1326 AndroidOverlay* overlay) { |
1296 DVLOG(1) << __func__; | 1327 DVLOG(1) << __func__; |
1297 TRACE_EVENT0("media", "AVDA::OnSurfaceDestroyed"); | 1328 TRACE_EVENT0("media", "AVDA::OnStopUsingOverlayImmediately"); |
1298 DCHECK(thread_checker_.CalledOnValidThread()); | 1329 DCHECK(thread_checker_.CalledOnValidThread()); |
1299 | 1330 |
1300 // We cannot get here if we're before surface allocation, since we transition | 1331 // We cannot get here if we're before surface allocation, since we transition |
1301 // to WAITING_FOR_CODEC (or NO_ERROR, if sync) when we get the surface without | 1332 // to WAITING_FOR_CODEC (or NO_ERROR, if sync) when we get the surface without |
1302 // posting. If we do ever lose the surface before starting codec allocation, | 1333 // posting. If we do ever lose the surface before starting codec allocation, |
1303 // then we could just update the config to use a SurfaceTexture and return | 1334 // then we could just update the config to use a SurfaceTexture and return |
1304 // without changing state. | 1335 // without changing state. |
1305 DCHECK_NE(state_, WAITING_FOR_SURFACE); | 1336 DCHECK_NE(state_, BEFORE_OVERLAY_INIT); |
1337 | |
1338 // If we're transitioning to |overlay|, then just stop here. We're not also | |
1339 // using the overlay if we're transitioning to it. | |
1340 if (incoming_overlay_->get() == overlay) { | |
1341 incoming_overlay_.reset(); | |
1342 return; | |
1343 } | |
1344 | |
1345 // If we have no codec, or if our current config doesn't refer to |overlay|, | |
1346 // then do nothing. |overlay| might be for some overlay that's waiting for | |
1347 // codec destruction on some other thread. | |
1348 if (!codec_config_->surface_bundle || | |
1349 codec_config_->surface_bundle->overlay.get() != overlay) { | |
1350 return; | |
1351 } | |
1352 | |
1353 // If we have a codec, or if codec allocation is in flight, then it's using an | |
1354 // overlay that was destroyed. | |
1355 if (state_ == WAITING_FOR_CODEC) { | |
1356 // What we should do here is to set |incoming_overlay_| to nullptr, to start | |
1357 // a transistion to SurfaceTexture. OnCodecConfigured could notice that | |
1358 // there's an incoming overlay, and then immediately transition the codec / | |
1359 // drop and re-allocate the codec using it. However, for CVV, that won't | |
1360 // work, since CVV-based overlays block the main thread waiting for the | |
1361 // overlay to be dropped, so OnCodecConfigured won't run. For DS, it's the | |
1362 // right thing. | |
1363 // So, for now, we just fail, and let OnCodecConfigured drop the codec. | |
1364 // Note that this case really can only happen on pre-M anyway, unless it's | |
1365 // during initial construction. This will result in the overlay being | |
1366 // destroyed after timeout, since OnCodecConfigured can't run until the | |
1367 // synchronous CVV destruction quits. | |
1368 state_ = SURFACE_DESTROYED; | |
1369 return; | |
1370 } | |
1306 | 1371 |
1307 // If the API is available avoid having to restart the decoder in order to | 1372 // If the API is available avoid having to restart the decoder in order to |
1308 // leave fullscreen. If we don't clear the surface immediately during this | 1373 // leave fullscreen. If we don't clear the surface immediately during this |
1309 // callback, the MediaCodec will throw an error as the surface is destroyed. | 1374 // callback, the MediaCodec will throw an error as the surface is destroyed. |
1310 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1375 if (platform_config_.allow_setsurface) { |
1311 // Since we can't wait for a transition, we must invalidate all outstanding | 1376 // Since we can't wait for a transition, we must invalidate all outstanding |
1312 // picture buffers to avoid putting the GL system in a broken state. | 1377 // picture buffers to avoid putting the GL system in a broken state. |
1313 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1378 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
1314 | 1379 |
1315 // Switch away from the surface being destroyed to a surface texture. | 1380 // If we aren't transitioning to some other surface, then transition to a |
1316 DCHECK_NE(surface_id(), SurfaceManager::kNoSurfaceID); | 1381 // SurfaceTexture. Remember that, if |incoming_overlay_| is an overlay, |
1382 // then it's already ready and can be transitioned to immediately. We were | |
1383 // just waiting for codec buffers to come back, but we just dropped them. | |
1384 // Note that we want |incoming_overlay_| to has_value(), but that value | |
1385 // should be a nullptr to indicate that we should switch to SurfaceTexture. | |
1386 if (!incoming_overlay_) | |
1387 incoming_overlay_ = std::unique_ptr<AndroidOverlay>(); | |
1317 | 1388 |
1318 // The leaving fullscreen notification may come in before this point. | |
1319 if (pending_surface_id_) | |
1320 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); | |
1321 | |
1322 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | |
1323 UpdateSurface(); | 1389 UpdateSurface(); |
1324 // Switching to a SurfaceTexture should never need to wait. If it does, | 1390 // Switching to a SurfaceTexture should never need to wait. If it does, |
1325 // then the codec might still be using the destroyed surface, which is bad. | 1391 // then the codec might still be using the destroyed surface, which is bad. |
1326 DCHECK_NE(state_, WAITING_FOR_SURFACE); | |
1327 return; | 1392 return; |
1328 } | 1393 } |
1329 | 1394 |
1330 // If we're currently asynchronously configuring a codec, it will be destroyed | 1395 // If we're currently asynchronously configuring a codec, it will be destroyed |
1331 // when configuration completes and it notices that |state_| has changed to | 1396 // when configuration completes and it notices that |state_| has changed to |
1332 // SURFACE_DESTROYED. | 1397 // SURFACE_DESTROYED. |
1333 state_ = SURFACE_DESTROYED; | 1398 state_ = SURFACE_DESTROYED; |
1334 ReleaseCodec(); | 1399 ReleaseCodecAndBundle(); |
1335 | 1400 |
1336 // If we're draining, signal completion now because the drain can no longer | 1401 // If we're draining, signal completion now because the drain can no longer |
1337 // proceed. | 1402 // proceed. |
1338 if (drain_type_) | 1403 if (drain_type_) |
1339 OnDrainCompleted(); | 1404 OnDrainCompleted(); |
1340 } | 1405 } |
1341 | 1406 |
1342 void AndroidVideoDecodeAccelerator::InitializeCdm() { | 1407 void AndroidVideoDecodeAccelerator::InitializeCdm() { |
1343 DVLOG(2) << __func__ << ": " << config_.cdm_id; | 1408 DVLOG(2) << __func__ << ": " << config_.cdm_id; |
1344 | 1409 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1393 | 1458 |
1394 // We assume this is a part of the initialization process, thus MediaCodec | 1459 // We assume this is a part of the initialization process, thus MediaCodec |
1395 // is not created yet. | 1460 // is not created yet. |
1396 DCHECK(!media_codec_); | 1461 DCHECK(!media_codec_); |
1397 DCHECK(deferred_initialization_pending_); | 1462 DCHECK(deferred_initialization_pending_); |
1398 | 1463 |
1399 codec_config_->media_crypto = std::move(media_crypto); | 1464 codec_config_->media_crypto = std::move(media_crypto); |
1400 codec_config_->needs_protected_surface = needs_protected_surface; | 1465 codec_config_->needs_protected_surface = needs_protected_surface; |
1401 | 1466 |
1402 // After receiving |media_crypto_| we can start with surface creation. | 1467 // After receiving |media_crypto_| we can start with surface creation. |
1403 StartSurfaceCreation(); | 1468 StartOverlayHelper(); |
1404 } | 1469 } |
1405 | 1470 |
1406 void AndroidVideoDecodeAccelerator::OnKeyAdded() { | 1471 void AndroidVideoDecodeAccelerator::OnKeyAdded() { |
1407 DVLOG(1) << __func__; | 1472 DVLOG(1) << __func__; |
1408 | 1473 |
1409 // This can also be called before initial surface allocation has completed, | 1474 // This can also be called before initial surface allocation has completed, |
1410 // so we might not have a surface / codec yet. In that case, we'll never | 1475 // so we might not have a surface / codec yet. In that case, we'll never |
1411 // transition to WAITING_FOR_KEY, which is fine. | 1476 // transition to WAITING_FOR_KEY, which is fine. |
1412 if (state_ == WAITING_FOR_KEY) | 1477 if (state_ == WAITING_FOR_KEY) |
1413 state_ = NO_ERROR; | 1478 state_ = NO_ERROR; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1583 | 1648 |
1584 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1649 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
1585 const { | 1650 const { |
1586 // Prevent MediaCodec from using its internal software decoders when we have | 1651 // Prevent MediaCodec from using its internal software decoders when we have |
1587 // more secure and up to date versions in the renderer process. | 1652 // more secure and up to date versions in the renderer process. |
1588 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || | 1653 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || |
1589 codec_config_->codec == kCodecVP9); | 1654 codec_config_->codec == kCodecVP9); |
1590 } | 1655 } |
1591 | 1656 |
1592 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | 1657 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
1593 DCHECK(pending_surface_id_); | 1658 DCHECK(incoming_overlay_); |
1594 DCHECK_NE(surface_id(), pending_surface_id_.value()); | |
1595 DCHECK(surface_id() == SurfaceManager::kNoSurfaceID || | |
1596 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); | |
1597 | |
1598 const int new_surface_id = pending_surface_id_.value(); | |
1599 pending_surface_id_.reset(); | |
1600 | 1659 |
1601 // Start surface creation. Note that if we're called via surfaceDestroyed, | 1660 // Start surface creation. Note that if we're called via surfaceDestroyed, |
1602 // then this must complete synchronously or it will DCHECK. Otherwise, we | 1661 // then this must complete synchronously or it will DCHECK. Otherwise, we |
1603 // might still be using the destroyed surface. We don't enforce this, but | 1662 // might still be using the destroyed surface. We don't enforce this, but |
1604 // it's worth remembering that there are cases where it's required. | 1663 // it's worth remembering that there are cases where it's required. |
1605 // Note that we don't re-use |surface_bundle|, since the codec is using it! | 1664 // Note that we don't re-use |surface_bundle|, since the codec is using it! |
1606 incoming_bundle_ = new AVDASurfaceBundle(new_surface_id); | 1665 incoming_bundle_ = |
1607 StartSurfaceCreation(); | 1666 new AVDASurfaceBundle(std::move(incoming_overlay_.value())); |
1667 incoming_overlay_.reset(); | |
1668 InitializePictureBufferManager(); | |
1608 if (state_ == ERROR) { | 1669 if (state_ == ERROR) { |
1609 // This might be called from OnSurfaceDestroyed(), so we have to release the | 1670 // This might be called from OnSurfaceDestroyed(), so we have to release the |
1610 // MediaCodec if we failed to switch the surface. We reset the surface ID | 1671 // MediaCodec if we failed to switch the surface. We reset the surface ID |
1611 // to the previous one, since failures never result in the codec using the | 1672 // to the previous one, since failures never result in the codec using the |
1612 // new surface. This is only guaranteed because of how OnCodecConfigured | 1673 // new surface. This is only guaranteed because of how OnCodecConfigured |
1613 // works. If it could fail after getting a codec, then this assumption | 1674 // works. If it could fail after getting a codec, then this assumption |
1614 // wouldn't be necessarily true anymore. | 1675 // wouldn't be necessarily true anymore. |
1615 // Also note that we might not have switched surfaces yet, which is also bad | 1676 // Also note that we might not have switched surfaces yet, which is also bad |
1616 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't | 1677 // for OnSurfaceDestroyed, because of BEFORE_OVERLAY_INIT. Shouldn't |
1617 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. In | 1678 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. In |
1618 // either case, we definitely should not still have an incoming bundle; it | 1679 // either case, we definitely should not still have an incoming bundle; it |
1619 // should have been dropped. | 1680 // should have been dropped. |
1620 DCHECK(!incoming_bundle_); | 1681 DCHECK(!incoming_bundle_); |
1621 ReleaseCodec(); | 1682 ReleaseCodecAndBundle(); |
1622 } | 1683 } |
1623 | 1684 |
1624 return state_ != ERROR; | 1685 return state_ != ERROR; |
1625 } | 1686 } |
1626 | 1687 |
1627 void AndroidVideoDecodeAccelerator::ReleaseCodec() { | 1688 void AndroidVideoDecodeAccelerator::ReleaseCodec() { |
1628 if (!media_codec_) | 1689 if (!media_codec_) |
1629 return; | 1690 return; |
1630 | 1691 |
1631 picture_buffer_manager_.CodecChanged(nullptr); | 1692 picture_buffer_manager_.CodecChanged(nullptr); |
1632 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_), | 1693 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_), |
1633 codec_config_->task_type, | 1694 codec_config_->task_type, |
1634 codec_config_->surface_bundle); | 1695 codec_config_->surface_bundle); |
1635 } | 1696 } |
1636 | 1697 |
1698 void AndroidVideoDecodeAccelerator::ReleaseCodecAndBundle() { | |
1699 ReleaseCodec(); | |
1700 codec_config_->surface_bundle = nullptr; | |
1701 } | |
1702 | |
1637 } // namespace media | 1703 } // namespace media |
OLD | NEW |