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

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

Issue 1828033002: media: Lazily reconfigure MediaCodecs in AVDA for JellyBean (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | no next file » | 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 "content/common/gpu/media/android_video_decode_accelerator.h" 5 #include "content/common/gpu/media/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 401
402 NOTIMPLEMENTED(); 402 NOTIMPLEMENTED();
403 NotifyCdmAttached(false); 403 NotifyCdmAttached(false);
404 404
405 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 405 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
406 } 406 }
407 407
408 void AndroidVideoDecodeAccelerator::DoIOTask() { 408 void AndroidVideoDecodeAccelerator::DoIOTask() {
409 DCHECK(thread_checker_.CalledOnValidThread()); 409 DCHECK(thread_checker_.CalledOnValidThread());
410 TRACE_EVENT0("media", "AVDA::DoIOTask"); 410 TRACE_EVENT0("media", "AVDA::DoIOTask");
411
411 if (state_ == ERROR) { 412 if (state_ == ERROR) {
412 return; 413 return;
414 } else if (state_ == PENDING_CODEC_RECONFIGURE) {
watk 2016/03/24 01:02:58 Should probably put this in Decode().
liberato (no reviews please) 2016/03/29 14:54:40 probably, yes, since the codec can't take any acti
415 // Defer errors here in case we're about to be destroyed because the
416 // pipeline is suspending.
417 base::AutoReset<bool> auto_reset(&defer_errors_, true);
418 if (!ConfigureMediaCodec()) {
419 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
420 return;
421 }
422 state_ = NO_ERROR;
413 } 423 }
414 424
415 bool did_work = QueueInput(); 425 bool did_work = QueueInput();
416 while (DequeueOutput()) 426 while (DequeueOutput())
417 did_work = true; 427 did_work = true;
418 428
419 ManageTimer(did_work); 429 ManageTimer(did_work);
420 } 430 }
421 431
422 bool AndroidVideoDecodeAccelerator::QueueInput() { 432 bool AndroidVideoDecodeAccelerator::QueueInput() {
423 DCHECK(thread_checker_.CalledOnValidThread()); 433 DCHECK(thread_checker_.CalledOnValidThread());
434 DCHECK_NE(state_, PENDING_CODEC_RECONFIGURE);
424 TRACE_EVENT0("media", "AVDA::QueueInput"); 435 TRACE_EVENT0("media", "AVDA::QueueInput");
425 base::AutoReset<bool> auto_reset(&defer_errors_, true); 436 base::AutoReset<bool> auto_reset(&defer_errors_, true);
426 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) 437 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
427 return false; 438 return false;
428 if (pending_bitstream_buffers_.empty()) 439 if (pending_bitstream_buffers_.empty())
429 return false; 440 return false;
430 if (state_ == WAITING_FOR_KEY) 441 if (state_ == WAITING_FOR_KEY)
431 return false; 442 return false;
432 443
433 int input_buf_index = pending_input_buf_index_; 444 int input_buf_index = pending_input_buf_index_;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY"; 539 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY";
529 pending_input_buf_index_ = input_buf_index; 540 pending_input_buf_index_ = input_buf_index;
530 state_ = WAITING_FOR_KEY; 541 state_ = WAITING_FOR_KEY;
531 return false; 542 return false;
532 } 543 }
533 544
534 pending_input_buf_index_ = -1; 545 pending_input_buf_index_ = -1;
535 pending_bitstream_buffers_.pop(); 546 pending_bitstream_buffers_.pop();
536 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 547 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
537 pending_bitstream_buffers_.size()); 548 pending_bitstream_buffers_.size());
538
539 if (status != media::MEDIA_CODEC_OK) {
540 POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status);
541 return false;
542 }
543
544 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 549 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
545 // will be returned from the bitstream buffer. However, MediaCodec API is 550 // will be returned from the bitstream buffer. However, MediaCodec API is
546 // not enough to guarantee it. 551 // not enough to guarantee it.
547 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 552 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
548 // keep getting more bitstreams from the client, and throttle them by using 553 // keep getting more bitstreams from the client, and throttle them by using
549 // |bitstreams_notified_in_advance_|. 554 // |bitstreams_notified_in_advance_|.
550 // TODO(dwkang): check if there is a way to remove this workaround. 555 // TODO(dwkang): check if there is a way to remove this workaround.
551 base::MessageLoop::current()->PostTask( 556 base::MessageLoop::current()->PostTask(
552 FROM_HERE, 557 FROM_HERE,
553 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 558 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
554 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); 559 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
555 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id()); 560 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
556 561
562 if (status != media::MEDIA_CODEC_OK) {
563 POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status);
564 return false;
watk 2016/03/24 01:02:58 This has to be moved because otherwise we might po
565 }
566
557 return true; 567 return true;
558 } 568 }
559 569
560 bool AndroidVideoDecodeAccelerator::DequeueOutput() { 570 bool AndroidVideoDecodeAccelerator::DequeueOutput() {
561 DCHECK(thread_checker_.CalledOnValidThread()); 571 DCHECK(thread_checker_.CalledOnValidThread());
572 DCHECK_NE(state_, PENDING_CODEC_RECONFIGURE);
562 TRACE_EVENT0("media", "AVDA::DequeueOutput"); 573 TRACE_EVENT0("media", "AVDA::DequeueOutput");
563 base::AutoReset<bool> auto_reset(&defer_errors_, true); 574 base::AutoReset<bool> auto_reset(&defer_errors_, true);
564 if (picturebuffers_requested_ && output_picture_buffers_.empty()) 575 if (picturebuffers_requested_ && output_picture_buffers_.empty())
565 return false; 576 return false;
566 577
567 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) { 578 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) {
568 // Don't have any picture buffer to send. Need to wait more. 579 // Don't have any picture buffer to send. Need to wait more.
569 return false; 580 return false;
570 } 581 }
571 582
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 // The data for that index exists in the input buffer, but corresponding 915 // The data for that index exists in the input buffer, but corresponding
905 // shm block been deleted. Check that it is safe to flush the coec, i.e. 916 // shm block been deleted. Check that it is safe to flush the coec, i.e.
906 // |pending_bitstream_buffers_| is empty. 917 // |pending_bitstream_buffers_| is empty.
907 // TODO(timav): keep shm block for that buffer and remove this restriction. 918 // TODO(timav): keep shm block for that buffer and remove this restriction.
908 DCHECK(pending_bitstream_buffers_.empty()); 919 DCHECK(pending_bitstream_buffers_.empty());
909 pending_input_buf_index_ = -1; 920 pending_input_buf_index_ = -1;
910 } 921 }
911 922
912 if (state_ == WAITING_FOR_KEY) 923 if (state_ == WAITING_FOR_KEY)
913 state_ = NO_ERROR; 924 state_ = NO_ERROR;
914 925
liberato (no reviews please) 2016/03/29 14:54:40 should this early out here if |state_| is already
915 // We might increment error_sequence_token here to cancel any delayed errors, 926 // We might increment error_sequence_token here to cancel any delayed errors,
916 // but right now it's unclear that it's safe to do so. If we are in an error 927 // but right now it's unclear that it's safe to do so. If we are in an error
917 // state because of a codec error, then it would be okay. Otherwise, it's 928 // state because of a codec error, then it would be okay. Otherwise, it's
918 // less obvious that we are exiting the error state. Since deferred errors 929 // less obvious that we are exiting the error state. Since deferred errors
919 // are only intended for fullscreen transitions right now, we take the more 930 // are only intended for fullscreen transitions right now, we take the more
920 // conservative approach and let the errors post. 931 // conservative approach and let the errors post.
921 // TODO(liberato): revisit this once we sort out the error state a bit more. 932 // TODO(liberato): revisit this once we sort out the error state a bit more.
922 933
923 // When codec is not in error state we can quickly reset (internally calls 934 // When codec is not in error state we can quickly reset (internally calls
924 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs 935 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
925 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new 936 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
926 // one. The full reconfigure is much slower and may cause visible freezing if 937 // one. The full reconfigure is much slower and may cause visible freezing if
927 // done mid-stream. 938 // done mid-stream.
928 if (state_ == NO_ERROR && 939 if (state_ == NO_ERROR &&
929 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 940 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
930 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; 941 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
931 media_codec_->Reset(); 942 media_codec_->Reset();
932 // Since we just flushed all the output buffers, make sure that nothing is 943 // Since we just flushed all the output buffers, make sure that nothing is
933 // using them. 944 // using them.
934 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 945 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
935 } else { 946 } else {
936 DVLOG(3) << __FUNCTION__ 947 DVLOG(3) << __FUNCTION__
937 << " Deleting the MediaCodec and creating a new one."; 948 << " Deleting the MediaCodec and creating a new one.";
938 g_avda_timer.Pointer()->StopTimer(this); 949 g_avda_timer.Pointer()->StopTimer(this);
939 media_codec_.reset(); 950 media_codec_.reset();
951 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
940 // Changing the codec will also notify the strategy to forget about any 952 // Changing the codec will also notify the strategy to forget about any
941 // output buffers it has currently. 953 // output buffers it has currently.
942 state_ = NO_ERROR; 954 state_ = PENDING_CODEC_RECONFIGURE;
liberato (no reviews please) 2016/03/29 14:54:40 you might consider not deferring the reset in the
943 if (!ConfigureMediaCodec())
944 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
945 } 955 }
946 } 956 }
947 957
948 void AndroidVideoDecodeAccelerator::DismissPictureBuffers() { 958 void AndroidVideoDecodeAccelerator::DismissPictureBuffers() {
949 DCHECK(thread_checker_.CalledOnValidThread()); 959 DCHECK(thread_checker_.CalledOnValidThread());
950 DVLOG(3) << __FUNCTION__; 960 DVLOG(3) << __FUNCTION__;
951 961
952 for (const auto& pb : output_picture_buffers_) { 962 for (const auto& pb : output_picture_buffers_) {
953 strategy_->DismissOnePictureBuffer(pb.second); 963 strategy_->DismissOnePictureBuffer(pb.second);
954 client_->DismissPictureBuffer(pb.first); 964 client_->DismissPictureBuffer(pb.first);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1219 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1210 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1220 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1211 media::VideoDecodeAccelerator::Capabilities:: 1221 media::VideoDecodeAccelerator::Capabilities::
1212 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1222 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1213 } 1223 }
1214 1224
1215 return capabilities; 1225 return capabilities;
1216 } 1226 }
1217 1227
1218 } // namespace content 1228 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698