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

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

Issue 2461073002: Use MediaCodec.setOutputSurface() for fullscreen transitions on M. (Closed)
Patch Set: Address comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/avda_codec_image.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 if (timer_avda_instances_.empty()) 162 if (timer_avda_instances_.empty())
163 io_timer_.Stop(); 163 io_timer_.Stop();
164 } 164 }
165 165
166 // |avda| would like to use |surface_id|. If it is not busy, then mark it 166 // |avda| would like to use |surface_id|. If it is not busy, then mark it
167 // as busy and return true. If it is busy, then replace any existing waiter, 167 // as busy and return true. If it is busy, then replace any existing waiter,
168 // make |avda| the current waiter, and return false. Any existing waiter 168 // make |avda| the current waiter, and return false. Any existing waiter
169 // is assumed to be on the way out, so we fail its allocation request. 169 // is assumed to be on the way out, so we fail its allocation request.
170 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { 170 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) {
171 // Nobody has to wait for no surface. 171 // Nobody has to wait for no surface.
172 if (surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID) 172 if (surface_id == SurfaceManager::kNoSurfaceID)
173 return true; 173 return true;
174 174
175 auto iter = surface_waiter_map_.find(surface_id); 175 auto iter = surface_waiter_map_.find(surface_id);
176 if (iter == surface_waiter_map_.end()) { 176 if (iter == surface_waiter_map_.end()) {
177 // SurfaceView isn't allocated. Succeed. 177 // SurfaceView isn't allocated. Succeed.
178 surface_waiter_map_[surface_id].owner = avda; 178 surface_waiter_map_[surface_id].owner = avda;
179 return true; 179 return true;
180 } 180 }
181 181
182 // SurfaceView is already allocated. 182 // SurfaceView is already allocated.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 // Promote |waiter| to be the owner. 218 // Promote |waiter| to be the owner.
219 iter->second.owner = waiter; 219 iter->second.owner = waiter;
220 iter->second.waiter = nullptr; 220 iter->second.waiter = nullptr;
221 waiter->OnSurfaceAvailable(true); 221 waiter->OnSurfaceAvailable(true);
222 } 222 }
223 223
224 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), 224 // On low end devices (< KitKat is always low-end due to buggy MediaCodec),
225 // defer the surface creation until the codec is actually used if we know no 225 // defer the surface creation until the codec is actually used if we know no
226 // software fallback exists. 226 // software fallback exists.
227 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { 227 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) {
228 return surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID && 228 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 &&
229 codec == kCodecH264 &&
230 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() && 229 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() &&
231 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || 230 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 ||
232 base::SysInfo::IsLowEndDevice()); 231 base::SysInfo::IsLowEndDevice());
233 } 232 }
234 233
235 private: 234 private:
236 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; 235 friend struct base::DefaultLazyInstanceTraits<AVDAManager>;
237 236
238 AVDAManager() {} 237 AVDAManager() {}
239 ~AVDAManager() { NOTREACHED(); } 238 ~AVDAManager() { NOTREACHED(); }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 picture_buffer_manager_(this), 311 picture_buffer_manager_(this),
313 drain_type_(DRAIN_TYPE_NONE), 312 drain_type_(DRAIN_TYPE_NONE),
314 media_drm_bridge_cdm_context_(nullptr), 313 media_drm_bridge_cdm_context_(nullptr),
315 cdm_registration_id_(0), 314 cdm_registration_id_(0),
316 pending_input_buf_index_(-1), 315 pending_input_buf_index_(-1),
317 error_sequence_token_(0), 316 error_sequence_token_(0),
318 defer_errors_(false), 317 defer_errors_(false),
319 deferred_initialization_pending_(false), 318 deferred_initialization_pending_(false),
320 codec_needs_reset_(false), 319 codec_needs_reset_(false),
321 defer_surface_creation_(false), 320 defer_surface_creation_(false),
321 surface_id_(SurfaceManager::kNoSurfaceID),
322 weak_this_factory_(this) {} 322 weak_this_factory_(this) {}
323 323
324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
325 DCHECK(thread_checker_.CalledOnValidThread()); 325 DCHECK(thread_checker_.CalledOnValidThread());
326 g_avda_manager.Get().StopTimer(this); 326 g_avda_manager.Get().StopTimer(this);
327 g_avda_codec_allocator.Get().StopThread(this); 327 g_avda_codec_allocator.Get().StopThread(this);
328 328
329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
330 if (!media_drm_bridge_cdm_context_) 330 if (!media_drm_bridge_cdm_context_)
331 return; 331 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 << " is not hardware accelerated"; 390 << " is not hardware accelerated";
391 return false; 391 return false;
392 } 392 }
393 393
394 auto gles_decoder = get_gles2_decoder_cb_.Run(); 394 auto gles_decoder = get_gles2_decoder_cb_.Run();
395 if (!gles_decoder) { 395 if (!gles_decoder) {
396 DLOG(ERROR) << "Failed to get gles2 decoder instance."; 396 DLOG(ERROR) << "Failed to get gles2 decoder instance.";
397 return false; 397 return false;
398 } 398 }
399 399
400 // If SetSurface() was called before initialize, pick up the surface.
401 if (pending_surface_id_) {
402 surface_id_ = pending_surface_id_.value();
403 pending_surface_id_.reset();
404 }
405
400 // If we're low on resources, we may decide to defer creation of the surface 406 // If we're low on resources, we may decide to defer creation of the surface
401 // until the codec is actually used. 407 // until the codec is actually used.
402 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, 408 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(surface_id_,
403 codec_config_->codec_)) { 409 codec_config_->codec_)) {
404 DCHECK(!deferred_initialization_pending_); 410 DCHECK(!deferred_initialization_pending_);
405 411
406 // We should never be here if a SurfaceView is required. 412 // We should never be here if a SurfaceView is required.
407 DCHECK_EQ(config_.surface_id, Config::kNoSurfaceID); 413 DCHECK_EQ(surface_id_, SurfaceManager::kNoSurfaceID);
408 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); 414 DCHECK(g_avda_manager.Get().AllocateSurface(surface_id_, this));
409 415
410 defer_surface_creation_ = true; 416 defer_surface_creation_ = true;
411 NotifyInitializationComplete(true); 417 NotifyInitializationComplete(true);
412 return true; 418 return true;
413 } 419 }
414 420
415 // We signaled that we support deferred initialization, so see if the client 421 // We signaled that we support deferred initialization, so see if the client
416 // does also. 422 // does also.
417 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; 423 deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
418 if (config_.is_encrypted && !deferred_initialization_pending_) { 424 if (config_.is_encrypted && !deferred_initialization_pending_) {
419 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; 425 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams";
420 return false; 426 return false;
421 } 427 }
422 428
423 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { 429 if (g_avda_manager.Get().AllocateSurface(surface_id_, this)) {
424 // We have successfully owned the surface, so finish initialization now. 430 // We have successfully owned the surface, so finish initialization now.
425 return InitializePictureBufferManager(); 431 return InitializePictureBufferManager();
426 } 432 }
427 433
428 // We have to wait for some other AVDA instance to free up the surface. 434 // We have to wait for some other AVDA instance to free up the surface.
429 // OnSurfaceAvailable will be called when it's available. 435 // OnSurfaceAvailable will be called when it's available.
430 return true; 436 return true;
431 } 437 }
432 438
433 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { 439 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) {
434 DCHECK(deferred_initialization_pending_); 440 DCHECK(deferred_initialization_pending_);
435 DCHECK(!defer_surface_creation_); 441 DCHECK(!defer_surface_creation_);
436 442
437 if (!success || !InitializePictureBufferManager()) { 443 if (!success || !InitializePictureBufferManager()) {
438 NotifyInitializationComplete(false); 444 NotifyInitializationComplete(false);
439 deferred_initialization_pending_ = false; 445 deferred_initialization_pending_ = false;
440 } 446 }
441 } 447 }
442 448
443 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { 449 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() {
444 if (!make_context_current_cb_.Run()) { 450 if (!make_context_current_cb_.Run()) {
445 LOG(ERROR) << "Failed to make this decoder's GL context current."; 451 LOG(ERROR) << "Failed to make this decoder's GL context current.";
446 return false; 452 return false;
447 } 453 }
448 454
449 codec_config_->surface_ = 455 codec_config_->surface_ = picture_buffer_manager_.Initialize(surface_id_);
450 picture_buffer_manager_.Initialize(config_.surface_id);
451 if (codec_config_->surface_.IsEmpty()) 456 if (codec_config_->surface_.IsEmpty())
452 return false; 457 return false;
453 458
454 on_destroying_surface_cb_ = 459 on_destroying_surface_cb_ =
455 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, 460 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface,
456 weak_this_factory_.GetWeakPtr()); 461 weak_this_factory_.GetWeakPtr());
457 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( 462 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback(
458 on_destroying_surface_cb_); 463 on_destroying_surface_cb_);
459 464
460 if (!g_avda_codec_allocator.Get().StartThread(this)) 465 if (!g_avda_codec_allocator.Get().StartThread(this))
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 if (picturebuffers_requested_ && output_picture_buffers_.empty() && 652 if (picturebuffers_requested_ && output_picture_buffers_.empty() &&
648 !IsDrainingForResetOrDestroy()) { 653 !IsDrainingForResetOrDestroy()) {
649 return false; 654 return false;
650 } 655 }
651 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && 656 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() &&
652 !IsDrainingForResetOrDestroy()) { 657 !IsDrainingForResetOrDestroy()) {
653 // Don't have any picture buffer to send. Need to wait. 658 // Don't have any picture buffer to send. Need to wait.
654 return false; 659 return false;
655 } 660 }
656 661
662 // If we're waiting to switch surfaces pause output release until we have all
663 // picture buffers returned. This is so we can ensure the right flags are set
664 // on the picture buffers returned to the client.
665 if (pending_surface_id_) {
666 if (picture_buffer_manager_.HasUnrenderedPictures())
667 return false;
668 if (!UpdateSurface())
669 return false;
670 }
671
657 bool eos = false; 672 bool eos = false;
658 base::TimeDelta presentation_timestamp; 673 base::TimeDelta presentation_timestamp;
659 int32_t buf_index = 0; 674 int32_t buf_index = 0;
660 do { 675 do {
661 size_t offset = 0; 676 size_t offset = 0;
662 size_t size = 0; 677 size_t size = 0;
663 678
664 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); 679 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput");
665 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 680 MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
666 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, 681 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp,
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 const BitstreamBuffer& bitstream_buffer) { 892 const BitstreamBuffer& bitstream_buffer) {
878 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); 893 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer));
879 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 894 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
880 pending_bitstream_records_.size()); 895 pending_bitstream_records_.size());
881 896
882 DoIOTask(true); 897 DoIOTask(true);
883 } 898 }
884 899
885 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 900 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
886 if (client_) { 901 if (client_) {
887 client_->ProvidePictureBuffers( 902 // Allocate a picture buffer that is the actual frame size. Note that it
888 kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, 903 // will be an external texture anyway, so it doesn't allocate an image of
889 picture_buffer_manager_.GetPictureBufferSize(), 904 // that size. It's important to get the coded size right, so that
890 picture_buffer_manager_.GetTextureTarget()); 905 // VideoLayerImpl doesn't try to scale the texture when building the quad
906 // for it.
907 client_->ProvidePictureBuffers(kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1,
908 size_,
909 AVDAPictureBufferManager::kTextureTarget);
891 } 910 }
892 } 911 }
893 912
894 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 913 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
895 const std::vector<PictureBuffer>& buffers) { 914 const std::vector<PictureBuffer>& buffers) {
896 DCHECK(thread_checker_.CalledOnValidThread()); 915 DCHECK(thread_checker_.CalledOnValidThread());
897 DCHECK(output_picture_buffers_.empty()); 916 DCHECK(output_picture_buffers_.empty());
898 DCHECK(free_picture_ids_.empty()); 917 DCHECK(free_picture_ids_.empty());
899 918
900 if (buffers.size() < kNumPictureBuffers) { 919 if (buffers.size() < kNumPictureBuffers) {
901 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 920 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
902 return; 921 return;
903 } 922 }
904 923
905 const bool have_context = make_context_current_cb_.Run(); 924 const bool have_context = make_context_current_cb_.Run();
906 LOG_IF(WARNING, !have_context) 925 LOG_IF(WARNING, !have_context)
907 << "Failed to make GL context current for Assign, continuing."; 926 << "Failed to make GL context current for Assign, continuing.";
908 927
909 for (size_t i = 0; i < buffers.size(); ++i) { 928 for (size_t i = 0; i < buffers.size(); ++i) {
910 if (buffers[i].size() != picture_buffer_manager_.GetPictureBufferSize()) { 929 DCHECK(buffers[i].size() == size_);
911 POST_ERROR(INVALID_ARGUMENT,
912 "Invalid picture buffer size assigned. Wanted "
913 << size_.ToString() << ", but got "
914 << buffers[i].size().ToString());
915 return;
916 }
917 int32_t id = buffers[i].id(); 930 int32_t id = buffers[i].id();
918 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); 931 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
919 free_picture_ids_.push(id); 932 free_picture_ids_.push(id);
920 933
921 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context); 934 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context);
922 } 935 }
923 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 936 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
924 DoIOTask(true); 937 DoIOTask(true);
925 } 938 }
926 939
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 // Postpone ResetCodecState() after the drain. 1247 // Postpone ResetCodecState() after the drain.
1235 StartCodecDrain(DRAIN_FOR_RESET); 1248 StartCodecDrain(DRAIN_FOR_RESET);
1236 } else { 1249 } else {
1237 ResetCodecState(); 1250 ResetCodecState();
1238 base::ThreadTaskRunnerHandle::Get()->PostTask( 1251 base::ThreadTaskRunnerHandle::Get()->PostTask(
1239 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1252 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1240 weak_this_factory_.GetWeakPtr())); 1253 weak_this_factory_.GetWeakPtr()));
1241 } 1254 }
1242 } 1255 }
1243 1256
1257 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) {
1258 if (surface_id == surface_id_) {
1259 pending_surface_id_.reset();
1260 return;
1261 }
1262
1263 // Surface changes never take effect immediately, they will be handled during
1264 // DequeOutput() once we get to a good switch point or immediately during an
1265 // OnDestroyingSurface() call.
1266 pending_surface_id_ = surface_id;
1267 }
1268
1244 void AndroidVideoDecodeAccelerator::Destroy() { 1269 void AndroidVideoDecodeAccelerator::Destroy() {
1245 DVLOG(1) << __FUNCTION__; 1270 DVLOG(1) << __FUNCTION__;
1246 DCHECK(thread_checker_.CalledOnValidThread()); 1271 DCHECK(thread_checker_.CalledOnValidThread());
1247 1272
1248 picture_buffer_manager_.Destroy(output_picture_buffers_); 1273 picture_buffer_manager_.Destroy(output_picture_buffers_);
1249 1274
1250 client_ = nullptr; 1275 client_ = nullptr;
1251 1276
1252 // Some VP8 files require a complete MediaCodec drain before we can call 1277 // Some VP8 files require a complete MediaCodec drain before we can call
1253 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In 1278 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In
(...skipping 13 matching lines...) Expand all
1267 DVLOG(1) << __FUNCTION__; 1292 DVLOG(1) << __FUNCTION__;
1268 DCHECK(thread_checker_.CalledOnValidThread()); 1293 DCHECK(thread_checker_.CalledOnValidThread());
1269 1294
1270 if (!on_destroying_surface_cb_.is_null()) { 1295 if (!on_destroying_surface_cb_.is_null()) {
1271 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( 1296 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback(
1272 on_destroying_surface_cb_); 1297 on_destroying_surface_cb_);
1273 } 1298 }
1274 1299
1275 // We no longer care about |surface_id|, in case we did before. It's okay 1300 // We no longer care about |surface_id|, in case we did before. It's okay
1276 // if we have no surface and/or weren't the owner or a waiter. 1301 // if we have no surface and/or weren't the owner or a waiter.
1277 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); 1302 g_avda_manager.Get().DeallocateSurface(surface_id_, this);
1278 1303
1279 // Note that async codec construction might still be in progress. In that 1304 // Note that async codec construction might still be in progress. In that
1280 // case, the codec will be deleted when it completes once we invalidate all 1305 // case, the codec will be deleted when it completes once we invalidate all
1281 // our weak refs. 1306 // our weak refs.
1282 weak_this_factory_.InvalidateWeakPtrs(); 1307 weak_this_factory_.InvalidateWeakPtrs();
1283 if (media_codec_) { 1308 if (media_codec_) {
1284 g_avda_manager.Get().StopTimer(this); 1309 g_avda_manager.Get().StopTimer(this);
1285 ReleaseMediaCodec(); 1310 ReleaseMediaCodec();
1286 } 1311 }
1287 1312
(...skipping 13 matching lines...) Expand all
1301 base::WeakPtr<gpu::gles2::GLES2Decoder> 1326 base::WeakPtr<gpu::gles2::GLES2Decoder>
1302 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1327 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1303 return get_gles2_decoder_cb_.Run(); 1328 return get_gles2_decoder_cb_.Run();
1304 } 1329 }
1305 1330
1306 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { 1331 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) {
1307 DCHECK(thread_checker_.CalledOnValidThread()); 1332 DCHECK(thread_checker_.CalledOnValidThread());
1308 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); 1333 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface");
1309 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; 1334 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id;
1310 1335
1311 if (surface_id != config_.surface_id) 1336 if (surface_id != surface_id_)
1312 return; 1337 return;
1313 1338
1339 // If the API is available avoid having to restart the decoder in order to
1340 // leave fullscreen. If we don't clear the surface immediately during this
1341 // callback, the MediaCodec will throw an error as the surface is destroyed.
1342 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) {
1343 // Since we can't wait for a transition, we must invalidate all outstanding
1344 // picture buffers to avoid putting the GL system in a broken state.
1345 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1346
1347 // Switch away from the surface being destroyed to a surface texture.
1348 DCHECK_NE(surface_id_, SurfaceManager::kNoSurfaceID);
1349
1350 // The leaving fullscreen notification may come in before this point.
1351 if (pending_surface_id_)
1352 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID);
1353
1354 pending_surface_id_ = SurfaceManager::kNoSurfaceID;
1355 UpdateSurface();
1356 return;
1357 }
1358
1314 // If we're currently asynchronously configuring a codec, it will be destroyed 1359 // If we're currently asynchronously configuring a codec, it will be destroyed
1315 // when configuration completes and it notices that |state_| has changed to 1360 // when configuration completes and it notices that |state_| has changed to
1316 // SURFACE_DESTROYED. 1361 // SURFACE_DESTROYED.
1317 state_ = SURFACE_DESTROYED; 1362 state_ = SURFACE_DESTROYED;
1318 if (media_codec_) { 1363 if (media_codec_) {
1319 ReleaseMediaCodec(); 1364 ReleaseMediaCodec();
1320 picture_buffer_manager_.CodecChanged(media_codec_.get()); 1365 picture_buffer_manager_.CodecChanged(media_codec_.get());
1321 } 1366 }
1322 // If we're draining, signal completion now because the drain can no longer 1367 // If we're draining, signal completion now because the drain can no longer
1323 // proceed. 1368 // proceed.
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 } 1622 }
1578 1623
1579 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() 1624 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden()
1580 const { 1625 const {
1581 // Prevent MediaCodec from using its internal software decoders when we have 1626 // Prevent MediaCodec from using its internal software decoders when we have
1582 // more secure and up to date versions in the renderer process. 1627 // more secure and up to date versions in the renderer process.
1583 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || 1628 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 ||
1584 codec_config_->codec_ == kCodecVP9); 1629 codec_config_->codec_ == kCodecVP9);
1585 } 1630 }
1586 1631
1632 bool AndroidVideoDecodeAccelerator::UpdateSurface() {
1633 DCHECK(pending_surface_id_);
1634 DCHECK_NE(surface_id_, pending_surface_id_.value());
1635
1636 // Ensure the current context is active when switching surfaces; we may need
1637 // to create a new texture.
1638 if (!make_context_current_cb_.Run()) {
1639 POST_ERROR(PLATFORM_FAILURE,
1640 "Failed to make this decoder's GL context current when "
1641 "switching surfaces.");
1642 return false;
1643 }
1644
1645 surface_id_ = pending_surface_id_.value();
1646 codec_config_->surface_ =
1647 picture_buffer_manager_.Initialize(pending_surface_id_.value());
1648 if (codec_config_->surface_.IsEmpty()) {
1649 POST_ERROR(PLATFORM_FAILURE, "An error occurred while switching surfaces.");
1650 return false;
1651 }
1652
1653 if (media_codec_ &&
1654 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) {
1655 POST_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
1656 return false;
1657 }
1658
1659 pending_surface_id_.reset();
1660 return true;
1661 }
1662
1587 } // namespace media 1663 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/avda_codec_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698