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