| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/media_codec_video_decoder.h" | 5 #include "media/gpu/android/media_codec_video_decoder.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/android/build_info.h" | 11 #include "base/android/build_info.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 #define NOTIFY_ERROR(error_code, error_message) \ | 49 #define NOTIFY_ERROR(error_code, error_message) \ |
| 50 do { \ | 50 do { \ |
| 51 DLOG(ERROR) << error_message; \ | 51 DLOG(ERROR) << error_message; \ |
| 52 NotifyError(VideoDecodeAccelerator::error_code); \ | 52 NotifyError(VideoDecodeAccelerator::error_code); \ |
| 53 } while (0) | 53 } while (0) |
| 54 | 54 |
| 55 namespace media { | 55 namespace media { |
| 56 | 56 |
| 57 namespace { | 57 namespace { |
| 58 | 58 |
| 59 enum { kNumPictureBuffers = limits::kMaxVideoFrames + 1 }; | |
| 60 | |
| 61 // Max number of bitstreams notified to the client with | 59 // Max number of bitstreams notified to the client with |
| 62 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. | 60 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. |
| 63 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; | 61 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; |
| 64 | 62 |
| 65 // MediaCodec is only guaranteed to support baseline, but some devices may | 63 // MediaCodec is only guaranteed to support baseline, but some devices may |
| 66 // support others. Advertise support for all H264 profiles and let the | 64 // support others. Advertise support for all H264 profiles and let the |
| 67 // MediaCodec fail when decoding if it's not actually supported. It's assumed | 65 // MediaCodec fail when decoding if it's not actually supported. It's assumed |
| 68 // that consumers won't have software fallback for H264 on Android anyway. | 66 // that consumers won't have software fallback for H264 on Android anyway. |
| 69 constexpr VideoCodecProfile kSupportedH264Profiles[] = { | 67 constexpr VideoCodecProfile kSupportedH264Profiles[] = { |
| 70 H264PROFILE_BASELINE, | 68 H264PROFILE_BASELINE, |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 | 220 |
| 223 MediaCodecVideoDecoder::BitstreamRecord::~BitstreamRecord() {} | 221 MediaCodecVideoDecoder::BitstreamRecord::~BitstreamRecord() {} |
| 224 | 222 |
| 225 MediaCodecVideoDecoder::MediaCodecVideoDecoder( | 223 MediaCodecVideoDecoder::MediaCodecVideoDecoder( |
| 226 const MakeGLContextCurrentCallback& make_context_current_cb, | 224 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 227 const GetGLES2DecoderCallback& get_gles2_decoder_cb) | 225 const GetGLES2DecoderCallback& get_gles2_decoder_cb) |
| 228 : client_(NULL), | 226 : client_(NULL), |
| 229 make_context_current_cb_(make_context_current_cb), | 227 make_context_current_cb_(make_context_current_cb), |
| 230 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 228 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
| 231 state_(NO_ERROR), | 229 state_(NO_ERROR), |
| 232 picturebuffers_requested_(false), | |
| 233 picture_buffer_manager_(get_gles2_decoder_cb), | 230 picture_buffer_manager_(get_gles2_decoder_cb), |
| 234 drain_type_(DRAIN_TYPE_NONE), | 231 drain_type_(DRAIN_TYPE_NONE), |
| 235 media_drm_bridge_cdm_context_(nullptr), | 232 media_drm_bridge_cdm_context_(nullptr), |
| 236 cdm_registration_id_(0), | 233 cdm_registration_id_(0), |
| 237 pending_input_buf_index_(-1), | 234 pending_input_buf_index_(-1), |
| 238 deferred_initialization_pending_(false), | 235 deferred_initialization_pending_(false), |
| 239 codec_needs_reset_(false), | 236 codec_needs_reset_(false), |
| 240 defer_surface_creation_(false), | 237 defer_surface_creation_(false), |
| 241 weak_this_factory_(this) {} | 238 weak_this_factory_(this) {} |
| 242 | 239 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 253 | 250 |
| 254 // Cancel previously registered callback (if any). | 251 // Cancel previously registered callback (if any). |
| 255 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( | 252 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( |
| 256 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); | 253 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); |
| 257 | 254 |
| 258 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); | 255 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); |
| 259 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 256 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 260 } | 257 } |
| 261 | 258 |
| 262 bool MediaCodecVideoDecoder::Initialize(const Config& config, Client* client) { | 259 bool MediaCodecVideoDecoder::Initialize(const Config& config, Client* client) { |
| 263 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); | 260 DVLOG(1) << __func__ << ": " << config.AsHumanReadableString(); |
| 264 TRACE_EVENT0("media", "MCVD::Initialize"); | 261 TRACE_EVENT0("media", "MCVD::Initialize"); |
| 265 DCHECK(!media_codec_); | 262 DCHECK(!media_codec_); |
| 266 DCHECK(thread_checker_.CalledOnValidThread()); | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
| 267 | 264 |
| 268 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) { | 265 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) { |
| 269 DLOG(ERROR) << "GL callbacks are required for this VDA"; | 266 DLOG(ERROR) << "GL callbacks are required for this VDA"; |
| 270 return false; | 267 return false; |
| 271 } | 268 } |
| 272 | 269 |
| 273 if (config.output_mode != Config::OutputMode::ALLOCATE) { | 270 if (config.output_mode != Config::OutputMode::ALLOCATE) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 if (config_.is_encrypted) { | 374 if (config_.is_encrypted) { |
| 378 InitializeCdm(); | 375 InitializeCdm(); |
| 379 return true; | 376 return true; |
| 380 } | 377 } |
| 381 | 378 |
| 382 if (deferred_initialization_pending_ || defer_surface_creation_) { | 379 if (deferred_initialization_pending_ || defer_surface_creation_) { |
| 383 defer_surface_creation_ = false; | 380 defer_surface_creation_ = false; |
| 384 ConfigureMediaCodecAsynchronously(); | 381 ConfigureMediaCodecAsynchronously(); |
| 385 return true; | 382 return true; |
| 386 } | 383 } |
| 387 | |
| 388 // If the client doesn't support deferred initialization (WebRTC), then we | |
| 389 // should complete it now and return a meaningful result. Note that it would | |
| 390 // be nice if we didn't have to worry about starting codec configuration at | |
| 391 // all (::Initialize or the wrapper can do it), but then they have to remember | |
| 392 // not to start codec config if we have to wait for the cdm. It's somewhat | |
| 393 // clearer for us to handle both cases. | |
| 394 return ConfigureMediaCodecSynchronously(); | |
| 395 } | 384 } |
| 396 | 385 |
| 397 void MediaCodecVideoDecoder::DoIOTask(bool start_timer) { | 386 void MediaCodecVideoDecoder::DoIOTask(bool start_timer) { |
| 398 DCHECK(thread_checker_.CalledOnValidThread()); | 387 DCHECK(thread_checker_.CalledOnValidThread()); |
| 399 TRACE_EVENT0("media", "MCVD::DoIOTask"); | 388 TRACE_EVENT0("media", "MCVD::DoIOTask"); |
| 400 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || | 389 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
| 401 state_ == SURFACE_DESTROYED) { | 390 state_ == SURFACE_DESTROYED) { |
| 402 return; | 391 return; |
| 403 } | 392 } |
| 404 | 393 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 if (key_id.empty() || iv.empty()) { | 489 if (key_id.empty() || iv.empty()) { |
| 501 status = media_codec_->QueueInputBuffer(input_buf_index, memory, | 490 status = media_codec_->QueueInputBuffer(input_buf_index, memory, |
| 502 bitstream_buffer.size(), | 491 bitstream_buffer.size(), |
| 503 presentation_timestamp); | 492 presentation_timestamp); |
| 504 } else { | 493 } else { |
| 505 status = media_codec_->QueueSecureInputBuffer( | 494 status = media_codec_->QueueSecureInputBuffer( |
| 506 input_buf_index, memory, bitstream_buffer.size(), key_id, iv, | 495 input_buf_index, memory, bitstream_buffer.size(), key_id, iv, |
| 507 subsamples, presentation_timestamp); | 496 subsamples, presentation_timestamp); |
| 508 } | 497 } |
| 509 | 498 |
| 510 DVLOG(2) << __FUNCTION__ | 499 DVLOG(2) << __func__ |
| 511 << ": Queue(Secure)InputBuffer: pts:" << presentation_timestamp | 500 << ": Queue(Secure)InputBuffer: pts:" << presentation_timestamp |
| 512 << " status:" << status; | 501 << " status:" << status; |
| 513 | 502 |
| 514 if (status == MEDIA_CODEC_NO_KEY) { | 503 if (status == MEDIA_CODEC_NO_KEY) { |
| 515 // Keep trying to enqueue the same input buffer. | 504 // Keep trying to enqueue the same input buffer. |
| 516 // The buffer is owned by us (not the MediaCodec) and is filled with data. | 505 // The buffer is owned by us (not the MediaCodec) and is filled with data. |
| 517 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY"; | 506 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY"; |
| 518 pending_input_buf_index_ = input_buf_index; | 507 pending_input_buf_index_ = input_buf_index; |
| 519 state_ = WAITING_FOR_KEY; | 508 state_ = WAITING_FOR_KEY; |
| 520 return false; | 509 return false; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 543 } | 532 } |
| 544 | 533 |
| 545 return true; | 534 return true; |
| 546 } | 535 } |
| 547 | 536 |
| 548 bool MediaCodecVideoDecoder::DequeueOutput() { | 537 bool MediaCodecVideoDecoder::DequeueOutput() { |
| 549 DCHECK(thread_checker_.CalledOnValidThread()); | 538 DCHECK(thread_checker_.CalledOnValidThread()); |
| 550 TRACE_EVENT0("media", "MCVD::DequeueOutput"); | 539 TRACE_EVENT0("media", "MCVD::DequeueOutput"); |
| 551 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) | 540 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) |
| 552 return false; | 541 return false; |
| 553 // If we're draining for reset or destroy, then we don't need picture buffers | |
| 554 // since we won't send any decoded frames anyway. There might not be any, | |
| 555 // since the pipeline might not be sending them back and / or they don't | |
| 556 // exist anymore. From the pipeline's point of view, for Destroy at least, | |
| 557 // the VDA is already gone. | |
| 558 if (picturebuffers_requested_ && output_picture_buffers_.empty() && | |
| 559 !IsDrainingForResetOrDestroy()) { | |
| 560 return false; | |
| 561 } | |
| 562 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && | 542 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && |
| 563 !IsDrainingForResetOrDestroy()) { | 543 !IsDrainingForResetOrDestroy()) { |
| 564 // Don't have any picture buffer to send. Need to wait. | 544 // Don't have any picture buffer to send. Need to wait. |
| 565 return false; | 545 return false; |
| 566 } | 546 } |
| 567 | 547 |
| 568 // If we're waiting to switch surfaces pause output release until we have all | 548 // If we're waiting to switch surfaces pause output release until we have all |
| 569 // picture buffers returned. This is so we can ensure the right flags are set | 549 // picture buffers returned. This is so we can ensure the right flags are set |
| 570 // on the picture buffers returned to the client. | 550 // on the picture buffers returned to the client. |
| 571 if (pending_surface_id_) { | 551 if (pending_surface_id_) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 588 &eos, NULL); | 568 &eos, NULL); |
| 589 TRACE_EVENT_END2("media", "MCVD::DequeueOutput", "status", status, | 569 TRACE_EVENT_END2("media", "MCVD::DequeueOutput", "status", status, |
| 590 "presentation_timestamp (ms)", | 570 "presentation_timestamp (ms)", |
| 591 presentation_timestamp.InMilliseconds()); | 571 presentation_timestamp.InMilliseconds()); |
| 592 | 572 |
| 593 switch (status) { | 573 switch (status) { |
| 594 case MEDIA_CODEC_ERROR: | 574 case MEDIA_CODEC_ERROR: |
| 595 // Do not post an error if we are draining for reset and destroy. | 575 // Do not post an error if we are draining for reset and destroy. |
| 596 // Instead, run the drain completion task. | 576 // Instead, run the drain completion task. |
| 597 if (IsDrainingForResetOrDestroy()) { | 577 if (IsDrainingForResetOrDestroy()) { |
| 598 DVLOG(1) << __FUNCTION__ << ": error while codec draining"; | 578 DVLOG(1) << __func__ << ": error while codec draining"; |
| 599 state_ = ERROR; | 579 state_ = ERROR; |
| 600 OnDrainCompleted(); | 580 OnDrainCompleted(); |
| 601 } else { | 581 } else { |
| 602 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); | 582 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); |
| 603 } | 583 } |
| 604 return false; | 584 return false; |
| 605 | 585 |
| 606 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: | 586 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: |
| 607 return false; | 587 return false; |
| 608 | 588 |
| 609 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { | 589 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { |
| 610 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame | 590 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame |
| 611 // size does not change. Therefore we have to keep track on the format | 591 // size does not change. Therefore we have to keep track on the format |
| 612 // even if draining, unless we are draining for destroy. | 592 // even if draining, unless we are draining for destroy. |
| 613 if (drain_type_ == DRAIN_FOR_DESTROY) | 593 if (drain_type_ == DRAIN_FOR_DESTROY) |
| 614 return true; // ignore | 594 return true; // ignore |
| 615 | 595 |
| 616 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) { | 596 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) { |
| 617 NOTIFY_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); | 597 NOTIFY_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); |
| 618 return false; | 598 return false; |
| 619 } | 599 } |
| 620 | 600 |
| 621 DVLOG(3) << __FUNCTION__ | 601 DVLOG(3) << __func__ |
| 622 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); | 602 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); |
| 623 | |
| 624 // Don't request picture buffers if we already have some. This avoids | |
| 625 // having to dismiss the existing buffers which may actively reference | |
| 626 // decoded images. Breaking their connection to the decoded image will | |
| 627 // cause rendering of black frames. Instead, we let the existing | |
| 628 // PictureBuffers live on and we simply update their size the next time | |
| 629 // they're attached to an image of the new resolution. See the | |
| 630 // size update in |SendDecodedFrameToClient| and https://crbug/587994. | |
| 631 if (output_picture_buffers_.empty() && !picturebuffers_requested_) { | |
| 632 picturebuffers_requested_ = true; | |
| 633 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 634 FROM_HERE, | |
| 635 base::Bind(&MediaCodecVideoDecoder::RequestPictureBuffers, | |
| 636 weak_this_factory_.GetWeakPtr())); | |
| 637 return false; | |
| 638 } | |
| 639 | |
| 640 return true; | 603 return true; |
| 641 } | 604 } |
| 642 | 605 |
| 643 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: | 606 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: |
| 644 break; | 607 break; |
| 645 | 608 |
| 646 case MEDIA_CODEC_OK: | 609 case MEDIA_CODEC_OK: |
| 647 DCHECK_GE(buf_index, 0); | 610 DCHECK_GE(buf_index, 0); |
| 648 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp | 611 DVLOG(3) << __func__ << ": pts:" << presentation_timestamp |
| 649 << " buf_index:" << buf_index << " offset:" << offset | 612 << " buf_index:" << buf_index << " offset:" << offset |
| 650 << " size:" << size << " eos:" << eos; | 613 << " size:" << size << " eos:" << eos; |
| 651 break; | 614 break; |
| 652 | 615 |
| 653 default: | 616 default: |
| 654 NOTREACHED(); | 617 NOTREACHED(); |
| 655 break; | 618 break; |
| 656 } | 619 } |
| 657 } while (buf_index < 0); | 620 } while (buf_index < 0); |
| 658 | 621 |
| 659 if (eos) { | 622 if (eos) { |
| 660 OnDrainCompleted(); | 623 OnDrainCompleted(); |
| 661 return false; | 624 return false; |
| 662 } | 625 } |
| 663 | 626 |
| 664 if (IsDrainingForResetOrDestroy()) { | 627 if (IsDrainingForResetOrDestroy()) { |
| 665 media_codec_->ReleaseOutputBuffer(buf_index, false); | 628 media_codec_->ReleaseOutputBuffer(buf_index, false); |
| 666 return true; | 629 return true; |
| 667 } | 630 } |
| 668 | 631 |
| 669 if (!picturebuffers_requested_) { | 632 // TODO(watk): Handle the case where we get a decoded buffer before |
| 670 // In 0.01% of playbacks MediaCodec returns a frame before FORMAT_CHANGED. | 633 // FORMAT_CHANGED. |
| 671 // Occurs on JB and M. (See the Media.MCVD.MissingFormatChanged histogram.) | 634 // In 0.01% of playbacks MediaCodec returns a frame before FORMAT_CHANGED. |
| 672 media_codec_->ReleaseOutputBuffer(buf_index, false); | 635 // Occurs on JB and M. (See the Media.MCVD.MissingFormatChanged histogram.) |
| 673 NOTIFY_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); | |
| 674 return false; | |
| 675 } | |
| 676 | 636 |
| 677 // Get the bitstream buffer id from the timestamp. | 637 // Get the bitstream buffer id from the timestamp. |
| 678 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); | 638 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); |
| 679 | 639 |
| 680 if (it != bitstream_buffers_in_decoder_.end()) { | 640 if (it != bitstream_buffers_in_decoder_.end()) { |
| 681 const int32_t bitstream_buffer_id = it->second; | 641 const int32_t bitstream_buffer_id = it->second; |
| 682 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), | 642 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), |
| 683 ++it); | 643 ++it); |
| 684 SendDecodedFrameToClient(buf_index, bitstream_buffer_id); | 644 SendDecodedFrameToClient(buf_index, bitstream_buffer_id); |
| 685 | 645 |
| 686 // Removes ids former or equal than the id from decoder. Note that | 646 // Removes ids former or equal than the id from decoder. Note that |
| 687 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder | 647 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder |
| 688 // because of frame reordering issue. We just maintain this roughly and use | 648 // because of frame reordering issue. We just maintain this roughly and use |
| 689 // it for throttling. | 649 // it for throttling. |
| 690 for (auto bitstream_it = bitstreams_notified_in_advance_.begin(); | 650 for (auto bitstream_it = bitstreams_notified_in_advance_.begin(); |
| 691 bitstream_it != bitstreams_notified_in_advance_.end(); | 651 bitstream_it != bitstreams_notified_in_advance_.end(); |
| 692 ++bitstream_it) { | 652 ++bitstream_it) { |
| 693 if (*bitstream_it == bitstream_buffer_id) { | 653 if (*bitstream_it == bitstream_buffer_id) { |
| 694 bitstreams_notified_in_advance_.erase( | 654 bitstreams_notified_in_advance_.erase( |
| 695 bitstreams_notified_in_advance_.begin(), ++bitstream_it); | 655 bitstreams_notified_in_advance_.begin(), ++bitstream_it); |
| 696 break; | 656 break; |
| 697 } | 657 } |
| 698 } | 658 } |
| 699 } else { | 659 } else { |
| 700 // Normally we assume that the decoder makes at most one output frame for | 660 // Normally we assume that the decoder makes at most one output frame for |
| 701 // each distinct input timestamp. However MediaCodecBridge uses timestamp | 661 // each distinct input timestamp. However MediaCodecBridge uses timestamp |
| 702 // correction and provides a non-decreasing timestamp sequence, which might | 662 // correction and provides a non-decreasing timestamp sequence, which might |
| 703 // result in timestamp duplicates. Discard the frame if we cannot get the | 663 // result in timestamp duplicates. Discard the frame if we cannot get the |
| 704 // corresponding buffer id. | 664 // corresponding buffer id. |
| 705 DVLOG(3) << __FUNCTION__ << ": Releasing buffer with unexpected PTS: " | 665 DVLOG(3) << __func__ << ": Releasing buffer with unexpected PTS: " |
| 706 << presentation_timestamp; | 666 << presentation_timestamp; |
| 707 media_codec_->ReleaseOutputBuffer(buf_index, false); | 667 media_codec_->ReleaseOutputBuffer(buf_index, false); |
| 708 } | 668 } |
| 709 | 669 |
| 710 // We got a decoded frame, so try for another. | 670 // We got a decoded frame, so try for another. |
| 711 return true; | 671 return true; |
| 712 } | 672 } |
| 713 | 673 |
| 714 void MediaCodecVideoDecoder::SendDecodedFrameToClient( | 674 void MediaCodecVideoDecoder::SendDecodedFrameToClient( |
| 715 int32_t codec_buffer_index, | 675 int32_t codec_buffer_index, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 | 758 |
| 799 void MediaCodecVideoDecoder::DecodeBuffer( | 759 void MediaCodecVideoDecoder::DecodeBuffer( |
| 800 const BitstreamBuffer& bitstream_buffer) { | 760 const BitstreamBuffer& bitstream_buffer) { |
| 801 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); | 761 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); |
| 802 TRACE_COUNTER1("media", "MCVD::PendingBitstreamBufferCount", | 762 TRACE_COUNTER1("media", "MCVD::PendingBitstreamBufferCount", |
| 803 pending_bitstream_records_.size()); | 763 pending_bitstream_records_.size()); |
| 804 | 764 |
| 805 DoIOTask(true); | 765 DoIOTask(true); |
| 806 } | 766 } |
| 807 | 767 |
| 808 void MediaCodecVideoDecoder::RequestPictureBuffers() { | |
| 809 if (client_) { | |
| 810 // Allocate a picture buffer that is the actual frame size. Note that it | |
| 811 // will be an external texture anyway, so it doesn't allocate an image of | |
| 812 // that size. It's important to get the coded size right, so that | |
| 813 // VideoLayerImpl doesn't try to scale the texture when building the quad | |
| 814 // for it. | |
| 815 client_->ProvidePictureBuffers(kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, | |
| 816 size_, | |
| 817 AVDAPictureBufferManager::kTextureTarget); | |
| 818 } | |
| 819 } | |
| 820 | |
| 821 void MediaCodecVideoDecoder::AssignPictureBuffers( | |
| 822 const std::vector<PictureBuffer>& buffers) { | |
| 823 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 824 DCHECK(output_picture_buffers_.empty()); | |
| 825 DCHECK(free_picture_ids_.empty()); | |
| 826 | |
| 827 if (buffers.size() < kNumPictureBuffers) { | |
| 828 NOTIFY_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); | |
| 829 return; | |
| 830 } | |
| 831 | |
| 832 const bool have_context = make_context_current_cb_.Run(); | |
| 833 LOG_IF(WARNING, !have_context) | |
| 834 << "Failed to make GL context current for Assign, continuing."; | |
| 835 | |
| 836 for (size_t i = 0; i < buffers.size(); ++i) { | |
| 837 DCHECK(buffers[i].size() == size_); | |
| 838 int32_t id = buffers[i].id(); | |
| 839 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); | |
| 840 free_picture_ids_.push(id); | |
| 841 | |
| 842 picture_buffer_manager_.AssignPictureBuffer(buffers[i], size_, | |
| 843 have_context); | |
| 844 } | |
| 845 TRACE_COUNTER1("media", "MCVD::FreePictureIds", free_picture_ids_.size()); | |
| 846 DoIOTask(true); | |
| 847 } | |
| 848 | |
| 849 void MediaCodecVideoDecoder::ReusePictureBuffer(int32_t picture_buffer_id) { | |
| 850 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 851 | |
| 852 free_picture_ids_.push(picture_buffer_id); | |
| 853 TRACE_COUNTER1("media", "MCVD::FreePictureIds", free_picture_ids_.size()); | |
| 854 | |
| 855 auto it = output_picture_buffers_.find(picture_buffer_id); | |
| 856 if (it == output_picture_buffers_.end()) { | |
| 857 NOTIFY_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " | |
| 858 << picture_buffer_id); | |
| 859 return; | |
| 860 } | |
| 861 | |
| 862 picture_buffer_manager_.ReusePictureBuffer(it->second); | |
| 863 DoIOTask(true); | |
| 864 } | |
| 865 | |
| 866 void MediaCodecVideoDecoder::Flush() { | 768 void MediaCodecVideoDecoder::Flush() { |
| 867 DVLOG(1) << __FUNCTION__; | 769 DVLOG(1) << __func__; |
| 868 DCHECK(thread_checker_.CalledOnValidThread()); | 770 DCHECK(thread_checker_.CalledOnValidThread()); |
| 869 | 771 |
| 870 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) | 772 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) |
| 871 NotifyFlushDone(); | 773 NotifyFlushDone(); |
| 872 else | 774 else |
| 873 StartCodecDrain(DRAIN_FOR_FLUSH); | 775 StartCodecDrain(DRAIN_FOR_FLUSH); |
| 874 } | 776 } |
| 875 | 777 |
| 876 void MediaCodecVideoDecoder::ConfigureMediaCodecAsynchronously() { | 778 void MediaCodecVideoDecoder::ConfigureMediaCodecAsynchronously() { |
| 877 DCHECK(thread_checker_.CalledOnValidThread()); | 779 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 898 if (codec_config_->task_type_ == TaskType::SW_CODEC && | 800 if (codec_config_->task_type_ == TaskType::SW_CODEC && |
| 899 IsMediaCodecSoftwareDecodingForbidden()) { | 801 IsMediaCodecSoftwareDecodingForbidden()) { |
| 900 OnCodecConfigured(nullptr); | 802 OnCodecConfigured(nullptr); |
| 901 return; | 803 return; |
| 902 } | 804 } |
| 903 | 805 |
| 904 AVDACodecAllocator::Instance()->CreateMediaCodecAsync( | 806 AVDACodecAllocator::Instance()->CreateMediaCodecAsync( |
| 905 weak_this_factory_.GetWeakPtr(), codec_config_); | 807 weak_this_factory_.GetWeakPtr(), codec_config_); |
| 906 } | 808 } |
| 907 | 809 |
| 908 bool MediaCodecVideoDecoder::ConfigureMediaCodecSynchronously() { | |
| 909 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 910 DCHECK(!media_codec_); | |
| 911 DCHECK_NE(state_, WAITING_FOR_CODEC); | |
| 912 state_ = WAITING_FOR_CODEC; | |
| 913 | |
| 914 codec_config_->task_type_ = | |
| 915 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | |
| 916 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) { | |
| 917 OnCodecConfigured(nullptr); | |
| 918 return false; | |
| 919 } | |
| 920 | |
| 921 std::unique_ptr<VideoCodecBridge> media_codec = | |
| 922 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_); | |
| 923 OnCodecConfigured(std::move(media_codec)); | |
| 924 return !!media_codec_; | |
| 925 } | |
| 926 | |
| 927 void MediaCodecVideoDecoder::OnCodecConfigured( | 810 void MediaCodecVideoDecoder::OnCodecConfigured( |
| 928 std::unique_ptr<VideoCodecBridge> media_codec) { | 811 std::unique_ptr<VideoCodecBridge> media_codec) { |
| 929 DCHECK(thread_checker_.CalledOnValidThread()); | 812 DCHECK(thread_checker_.CalledOnValidThread()); |
| 930 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 813 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 931 | 814 |
| 932 // If we are supposed to notify that initialization is complete, then do so | 815 // If we are supposed to notify that initialization is complete, then do so |
| 933 // now. Otherwise, this is a reconfiguration. | 816 // now. Otherwise, this is a reconfiguration. |
| 934 if (deferred_initialization_pending_) { | 817 if (deferred_initialization_pending_) { |
| 935 // Losing the output surface is not considered an error state, so notify | 818 // Losing the output surface is not considered an error state, so notify |
| 936 // success. The client will destroy this soon. | 819 // success. The client will destroy this soon. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 951 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec"); | 834 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec"); |
| 952 return; | 835 return; |
| 953 } | 836 } |
| 954 | 837 |
| 955 state_ = NO_ERROR; | 838 state_ = NO_ERROR; |
| 956 | 839 |
| 957 ManageTimer(true); | 840 ManageTimer(true); |
| 958 } | 841 } |
| 959 | 842 |
| 960 void MediaCodecVideoDecoder::StartCodecDrain(DrainType drain_type) { | 843 void MediaCodecVideoDecoder::StartCodecDrain(DrainType drain_type) { |
| 961 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type; | 844 DVLOG(2) << __func__ << " drain_type:" << drain_type; |
| 962 DCHECK(thread_checker_.CalledOnValidThread()); | 845 DCHECK(thread_checker_.CalledOnValidThread()); |
| 963 | 846 |
| 964 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while | 847 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while |
| 965 // another drain request is present, but DRAIN_FOR_DESTROY can. | 848 // another drain request is present, but DRAIN_FOR_DESTROY can. |
| 966 DCHECK_NE(drain_type, DRAIN_TYPE_NONE); | 849 DCHECK_NE(drain_type, DRAIN_TYPE_NONE); |
| 967 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY) | 850 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY) |
| 968 << "Unexpected StartCodecDrain() with drain type " << drain_type | 851 << "Unexpected StartCodecDrain() with drain type " << drain_type |
| 969 << " while already draining with drain type " << drain_type_; | 852 << " while already draining with drain type " << drain_type_; |
| 970 | 853 |
| 971 const bool enqueue_eos = drain_type_ == DRAIN_TYPE_NONE; | 854 const bool enqueue_eos = drain_type_ == DRAIN_TYPE_NONE; |
| 972 drain_type_ = drain_type; | 855 drain_type_ = drain_type; |
| 973 | 856 |
| 974 if (enqueue_eos) | 857 if (enqueue_eos) |
| 975 DecodeBuffer(BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); | 858 DecodeBuffer(BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); |
| 976 } | 859 } |
| 977 | 860 |
| 978 bool MediaCodecVideoDecoder::IsDrainingForResetOrDestroy() const { | 861 bool MediaCodecVideoDecoder::IsDrainingForResetOrDestroy() const { |
| 979 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY; | 862 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY; |
| 980 } | 863 } |
| 981 | 864 |
| 982 void MediaCodecVideoDecoder::OnDrainCompleted() { | 865 void MediaCodecVideoDecoder::OnDrainCompleted() { |
| 983 DVLOG(2) << __FUNCTION__; | 866 DVLOG(2) << __func__; |
| 984 DCHECK(thread_checker_.CalledOnValidThread()); | 867 DCHECK(thread_checker_.CalledOnValidThread()); |
| 985 | 868 |
| 986 // If we were waiting for an EOS, clear the state and reset the MediaCodec | 869 // If we were waiting for an EOS, clear the state and reset the MediaCodec |
| 987 // as normal. | 870 // as normal. |
| 988 // | 871 // |
| 989 // Some Android platforms seem to send an EOS buffer even when we're not | 872 // Some Android platforms seem to send an EOS buffer even when we're not |
| 990 // expecting it. In this case, destroy and reset the codec but don't notify | 873 // expecting it. In this case, destroy and reset the codec but don't notify |
| 991 // flush done since it violates the state machine. http://crbug.com/585959. | 874 // flush done since it violates the state machine. http://crbug.com/585959. |
| 992 | 875 |
| 993 switch (drain_type_) { | 876 switch (drain_type_) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 // frames that might be out for display at end of stream. | 929 // frames that might be out for display at end of stream. |
| 1047 codec_needs_reset_ = false; | 930 codec_needs_reset_ = false; |
| 1048 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) { | 931 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) { |
| 1049 codec_needs_reset_ = true; | 932 codec_needs_reset_ = true; |
| 1050 return; | 933 return; |
| 1051 } | 934 } |
| 1052 | 935 |
| 1053 // Flush the codec if possible, or create a new one if not. | 936 // Flush the codec if possible, or create a new one if not. |
| 1054 if (!did_codec_error_happen && | 937 if (!did_codec_error_happen && |
| 1055 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 938 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
| 1056 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; | 939 DVLOG(3) << __func__ << " Flushing MediaCodec."; |
| 1057 media_codec_->Flush(); | 940 media_codec_->Flush(); |
| 1058 // Since we just flushed all the output buffers, make sure that nothing is | 941 // Since we just flushed all the output buffers, make sure that nothing is |
| 1059 // using them. | 942 // using them. |
| 1060 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 943 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1061 } else { | 944 } else { |
| 1062 DVLOG(3) << __FUNCTION__ | 945 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; |
| 1063 << " Deleting the MediaCodec and creating a new one."; | |
| 1064 g_mcvd_manager.Get().StopTimer(this); | 946 g_mcvd_manager.Get().StopTimer(this); |
| 1065 ConfigureMediaCodecAsynchronously(); | 947 ConfigureMediaCodecAsynchronously(); |
| 1066 } | 948 } |
| 1067 } | 949 } |
| 1068 | 950 |
| 1069 void MediaCodecVideoDecoder::Reset() { | 951 void MediaCodecVideoDecoder::Reset() { |
| 1070 DVLOG(1) << __FUNCTION__; | 952 DVLOG(1) << __func__; |
| 1071 DCHECK(thread_checker_.CalledOnValidThread()); | 953 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1072 TRACE_EVENT0("media", "MCVD::Reset"); | 954 TRACE_EVENT0("media", "MCVD::Reset"); |
| 1073 | 955 |
| 1074 if (defer_surface_creation_) { | 956 if (defer_surface_creation_) { |
| 1075 DCHECK(!media_codec_); | 957 DCHECK(!media_codec_); |
| 1076 DCHECK(pending_bitstream_records_.empty()); | 958 DCHECK(pending_bitstream_records_.empty()); |
| 1077 DCHECK_EQ(state_, NO_ERROR); | 959 DCHECK_EQ(state_, NO_ERROR); |
| 1078 base::ThreadTaskRunnerHandle::Get()->PostTask( | 960 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1079 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::NotifyResetDone, | 961 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::NotifyResetDone, |
| 1080 weak_this_factory_.GetWeakPtr())); | 962 weak_this_factory_.GetWeakPtr())); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 return; | 1003 return; |
| 1122 } | 1004 } |
| 1123 | 1005 |
| 1124 // Surface changes never take effect immediately, they will be handled during | 1006 // Surface changes never take effect immediately, they will be handled during |
| 1125 // DequeOutput() once we get to a good switch point or immediately during an | 1007 // DequeOutput() once we get to a good switch point or immediately during an |
| 1126 // OnSurfaceDestroyed() call. | 1008 // OnSurfaceDestroyed() call. |
| 1127 pending_surface_id_ = surface_id; | 1009 pending_surface_id_ = surface_id; |
| 1128 } | 1010 } |
| 1129 | 1011 |
| 1130 void MediaCodecVideoDecoder::Destroy() { | 1012 void MediaCodecVideoDecoder::Destroy() { |
| 1131 DVLOG(1) << __FUNCTION__; | 1013 DVLOG(1) << __func__; |
| 1132 DCHECK(thread_checker_.CalledOnValidThread()); | 1014 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1133 | 1015 |
| 1134 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1016 picture_buffer_manager_.Destroy(output_picture_buffers_); |
| 1135 | 1017 |
| 1136 client_ = nullptr; | 1018 client_ = nullptr; |
| 1137 | 1019 |
| 1138 // Some VP8 files require a complete MediaCodec drain before we can call | 1020 // Some VP8 files require a complete MediaCodec drain before we can call |
| 1139 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In | 1021 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In |
| 1140 // that case, postpone ActualDestroy() until after the drain. | 1022 // that case, postpone ActualDestroy() until after the drain. |
| 1141 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { | 1023 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { |
| 1142 // Clear |pending_bitstream_records_|. | 1024 // Clear |pending_bitstream_records_|. |
| 1143 while (!pending_bitstream_records_.empty()) | 1025 while (!pending_bitstream_records_.empty()) |
| 1144 pending_bitstream_records_.pop(); | 1026 pending_bitstream_records_.pop(); |
| 1145 | 1027 |
| 1146 StartCodecDrain(DRAIN_FOR_DESTROY); | 1028 StartCodecDrain(DRAIN_FOR_DESTROY); |
| 1147 } else { | 1029 } else { |
| 1148 ActualDestroy(); | 1030 ActualDestroy(); |
| 1149 } | 1031 } |
| 1150 } | 1032 } |
| 1151 | 1033 |
| 1152 void MediaCodecVideoDecoder::ActualDestroy() { | 1034 void MediaCodecVideoDecoder::ActualDestroy() { |
| 1153 DVLOG(1) << __FUNCTION__; | 1035 DVLOG(1) << __func__; |
| 1154 DCHECK(thread_checker_.CalledOnValidThread()); | 1036 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1155 | 1037 |
| 1156 // Note that async codec construction might still be in progress. In that | 1038 // Note that async codec construction might still be in progress. In that |
| 1157 // case, the codec will be deleted when it completes once we invalidate all | 1039 // case, the codec will be deleted when it completes once we invalidate all |
| 1158 // our weak refs. | 1040 // our weak refs. |
| 1159 weak_this_factory_.InvalidateWeakPtrs(); | 1041 weak_this_factory_.InvalidateWeakPtrs(); |
| 1160 g_mcvd_manager.Get().StopTimer(this); | 1042 g_mcvd_manager.Get().StopTimer(this); |
| 1161 if (media_codec_) { | 1043 if (media_codec_) { |
| 1162 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1044 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
| 1163 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); | 1045 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); |
| 1164 } | 1046 } |
| 1165 | 1047 |
| 1166 // We no longer care about |surface_id|, in case we did before. It's okay | 1048 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1167 // if we have no surface and/or weren't the owner or a waiter. | 1049 // if we have no surface and/or weren't the owner or a waiter. |
| 1168 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); | 1050 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); |
| 1169 | 1051 |
| 1170 delete this; | 1052 delete this; |
| 1171 } | 1053 } |
| 1172 | 1054 |
| 1173 bool MediaCodecVideoDecoder::TryToSetupDecodeOnSeparateThread( | |
| 1174 const base::WeakPtr<Client>& decode_client, | |
| 1175 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | |
| 1176 return false; | |
| 1177 } | |
| 1178 | |
| 1179 void MediaCodecVideoDecoder::OnSurfaceDestroyed() { | 1055 void MediaCodecVideoDecoder::OnSurfaceDestroyed() { |
| 1180 DVLOG(1) << __func__; | 1056 DVLOG(1) << __func__; |
| 1181 TRACE_EVENT0("media", "MCVD::OnSurfaceDestroyed"); | 1057 TRACE_EVENT0("media", "MCVD::OnSurfaceDestroyed"); |
| 1182 DCHECK(thread_checker_.CalledOnValidThread()); | 1058 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1183 | 1059 |
| 1184 // If the API is available avoid having to restart the decoder in order to | 1060 // If the API is available avoid having to restart the decoder in order to |
| 1185 // leave fullscreen. If we don't clear the surface immediately during this | 1061 // leave fullscreen. If we don't clear the surface immediately during this |
| 1186 // callback, the MediaCodec will throw an error as the surface is destroyed. | 1062 // callback, the MediaCodec will throw an error as the surface is destroyed. |
| 1187 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1063 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
| 1188 // Since we can't wait for a transition, we must invalidate all outstanding | 1064 // Since we can't wait for a transition, we must invalidate all outstanding |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1211 picture_buffer_manager_.CodecChanged(nullptr); | 1087 picture_buffer_manager_.CodecChanged(nullptr); |
| 1212 } | 1088 } |
| 1213 | 1089 |
| 1214 // If we're draining, signal completion now because the drain can no longer | 1090 // If we're draining, signal completion now because the drain can no longer |
| 1215 // proceed. | 1091 // proceed. |
| 1216 if (drain_type_ != DRAIN_TYPE_NONE) | 1092 if (drain_type_ != DRAIN_TYPE_NONE) |
| 1217 OnDrainCompleted(); | 1093 OnDrainCompleted(); |
| 1218 } | 1094 } |
| 1219 | 1095 |
| 1220 void MediaCodecVideoDecoder::InitializeCdm() { | 1096 void MediaCodecVideoDecoder::InitializeCdm() { |
| 1221 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id; | 1097 DVLOG(2) << __func__ << ": " << config_.cdm_id; |
| 1222 | 1098 |
| 1223 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 1099 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 1224 NOTIMPLEMENTED(); | 1100 NOTIMPLEMENTED(); |
| 1225 NotifyInitializationComplete(false); | 1101 NotifyInitializationComplete(false); |
| 1226 #else | 1102 #else |
| 1227 // Store the CDM to hold a reference to it. | 1103 // Store the CDM to hold a reference to it. |
| 1228 cdm_for_reference_holding_only_ = | 1104 cdm_for_reference_holding_only_ = |
| 1229 MojoCdmService::LegacyGetCdm(config_.cdm_id); | 1105 MojoCdmService::LegacyGetCdm(config_.cdm_id); |
| 1230 DCHECK(cdm_for_reference_holding_only_); | 1106 DCHECK(cdm_for_reference_holding_only_); |
| 1231 | 1107 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1250 // Deferred initialization will continue in OnMediaCryptoReady(). | 1126 // Deferred initialization will continue in OnMediaCryptoReady(). |
| 1251 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( | 1127 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( |
| 1252 BindToCurrentLoop(base::Bind(&MediaCodecVideoDecoder::OnMediaCryptoReady, | 1128 BindToCurrentLoop(base::Bind(&MediaCodecVideoDecoder::OnMediaCryptoReady, |
| 1253 weak_this_factory_.GetWeakPtr()))); | 1129 weak_this_factory_.GetWeakPtr()))); |
| 1254 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 1130 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 1255 } | 1131 } |
| 1256 | 1132 |
| 1257 void MediaCodecVideoDecoder::OnMediaCryptoReady( | 1133 void MediaCodecVideoDecoder::OnMediaCryptoReady( |
| 1258 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto, | 1134 MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto, |
| 1259 bool needs_protected_surface) { | 1135 bool needs_protected_surface) { |
| 1260 DVLOG(1) << __FUNCTION__; | 1136 DVLOG(1) << __func__; |
| 1261 | 1137 |
| 1262 if (!media_crypto) { | 1138 if (!media_crypto) { |
| 1263 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; | 1139 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; |
| 1264 cdm_for_reference_holding_only_ = nullptr; | 1140 cdm_for_reference_holding_only_ = nullptr; |
| 1265 media_drm_bridge_cdm_context_ = nullptr; | 1141 media_drm_bridge_cdm_context_ = nullptr; |
| 1266 NotifyInitializationComplete(false); | 1142 NotifyInitializationComplete(false); |
| 1267 return; | 1143 return; |
| 1268 } | 1144 } |
| 1269 | 1145 |
| 1270 DCHECK(!media_crypto->is_null()); | 1146 DCHECK(!media_crypto->is_null()); |
| 1271 | 1147 |
| 1272 // We assume this is a part of the initialization process, thus MediaCodec | 1148 // We assume this is a part of the initialization process, thus MediaCodec |
| 1273 // is not created yet. | 1149 // is not created yet. |
| 1274 DCHECK(!media_codec_); | 1150 DCHECK(!media_codec_); |
| 1275 | 1151 |
| 1276 codec_config_->media_crypto_ = std::move(media_crypto); | 1152 codec_config_->media_crypto_ = std::move(media_crypto); |
| 1277 codec_config_->needs_protected_surface_ = needs_protected_surface; | 1153 codec_config_->needs_protected_surface_ = needs_protected_surface; |
| 1278 | 1154 |
| 1279 // After receiving |media_crypto_| we can configure MediaCodec. | 1155 // After receiving |media_crypto_| we can configure MediaCodec. |
| 1280 ConfigureMediaCodecAsynchronously(); | 1156 ConfigureMediaCodecAsynchronously(); |
| 1281 } | 1157 } |
| 1282 | 1158 |
| 1283 void MediaCodecVideoDecoder::OnKeyAdded() { | 1159 void MediaCodecVideoDecoder::OnKeyAdded() { |
| 1284 DVLOG(1) << __FUNCTION__; | 1160 DVLOG(1) << __func__; |
| 1285 | 1161 |
| 1286 if (state_ == WAITING_FOR_KEY) | 1162 if (state_ == WAITING_FOR_KEY) |
| 1287 state_ = NO_ERROR; | 1163 state_ = NO_ERROR; |
| 1288 | 1164 |
| 1289 DoIOTask(true); | 1165 DoIOTask(true); |
| 1290 } | 1166 } |
| 1291 | 1167 |
| 1292 void MediaCodecVideoDecoder::NotifyInitializationComplete(bool success) { | |
| 1293 if (client_) | |
| 1294 client_->NotifyInitializationComplete(success); | |
| 1295 } | |
| 1296 | |
| 1297 void MediaCodecVideoDecoder::NotifyPictureReady(const Picture& picture) { | |
| 1298 if (client_) | |
| 1299 client_->PictureReady(picture); | |
| 1300 } | |
| 1301 | |
| 1302 void MediaCodecVideoDecoder::NotifyEndOfBitstreamBuffer(int input_buffer_id) { | |
| 1303 if (client_) | |
| 1304 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); | |
| 1305 } | |
| 1306 | |
| 1307 void MediaCodecVideoDecoder::NotifyFlushDone() { | |
| 1308 if (client_) | |
| 1309 client_->NotifyFlushDone(); | |
| 1310 } | |
| 1311 | |
| 1312 void MediaCodecVideoDecoder::NotifyResetDone() { | |
| 1313 if (client_) | |
| 1314 client_->NotifyResetDone(); | |
| 1315 } | |
| 1316 | |
| 1317 void MediaCodecVideoDecoder::NotifyError(Error error) { | 1168 void MediaCodecVideoDecoder::NotifyError(Error error) { |
| 1318 state_ = ERROR; | 1169 state_ = ERROR; |
| 1319 if (client_) | 1170 if (client_) |
| 1320 client_->NotifyError(error); | 1171 client_->NotifyError(error); |
| 1321 } | 1172 } |
| 1322 | 1173 |
| 1323 void MediaCodecVideoDecoder::ManageTimer(bool did_work) { | 1174 void MediaCodecVideoDecoder::ManageTimer(bool did_work) { |
| 1324 bool should_be_running = true; | 1175 bool should_be_running = true; |
| 1325 | 1176 |
| 1326 base::TimeTicks now = base::TimeTicks::Now(); | 1177 base::TimeTicks now = base::TimeTicks::Now(); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); | 1350 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); |
| 1500 } | 1351 } |
| 1501 | 1352 |
| 1502 // Regardless of whether we succeeded, we no longer own the previous surface. | 1353 // Regardless of whether we succeeded, we no longer own the previous surface. |
| 1503 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); | 1354 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); |
| 1504 | 1355 |
| 1505 return success; | 1356 return success; |
| 1506 } | 1357 } |
| 1507 | 1358 |
| 1508 } // namespace media | 1359 } // namespace media |
| OLD | NEW |