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

Side by Side Diff: media/base/android/media_source_player.cc

Issue 1367403003: Added UMA metrics for MediaSourcePlayer and MediaCodecPlayer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-drm
Patch Set: Addressed most of the comments Created 5 years, 2 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
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/base/android/media_source_player.h" 5 #include "media/base/android/media_source_player.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
(...skipping 29 matching lines...) Expand all
40 doing_browser_seek_(false), 40 doing_browser_seek_(false),
41 pending_seek_(false), 41 pending_seek_(false),
42 drm_bridge_(NULL), 42 drm_bridge_(NULL),
43 cdm_registration_id_(0), 43 cdm_registration_id_(0),
44 is_waiting_for_key_(false), 44 is_waiting_for_key_(false),
45 key_added_while_decode_pending_(false), 45 key_added_while_decode_pending_(false),
46 is_waiting_for_audio_decoder_(false), 46 is_waiting_for_audio_decoder_(false),
47 is_waiting_for_video_decoder_(false), 47 is_waiting_for_video_decoder_(false),
48 prerolling_(true), 48 prerolling_(true),
49 weak_factory_(this) { 49 weak_factory_(this) {
50 media_stat_.reset(new MediaStatistics());
51
50 audio_decoder_job_.reset(new AudioDecoderJob( 52 audio_decoder_job_.reset(new AudioDecoderJob(
51 base::Bind(&DemuxerAndroid::RequestDemuxerData, 53 base::Bind(&DemuxerAndroid::RequestDemuxerData,
52 base::Unretained(demuxer_.get()), 54 base::Unretained(demuxer_.get()),
53 DemuxerStream::AUDIO), 55 DemuxerStream::AUDIO),
54 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, 56 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
55 weak_factory_.GetWeakPtr()))); 57 weak_factory_.GetWeakPtr()),
58 &media_stat_->audio_frames()));
56 video_decoder_job_.reset(new VideoDecoderJob( 59 video_decoder_job_.reset(new VideoDecoderJob(
57 base::Bind(&DemuxerAndroid::RequestDemuxerData, 60 base::Bind(&DemuxerAndroid::RequestDemuxerData,
58 base::Unretained(demuxer_.get()), 61 base::Unretained(demuxer_.get()),
59 DemuxerStream::VIDEO), 62 DemuxerStream::VIDEO),
60 base::Bind(request_media_resources_cb_, player_id), 63 base::Bind(request_media_resources_cb_, player_id),
61 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, 64 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
62 weak_factory_.GetWeakPtr()))); 65 weak_factory_.GetWeakPtr()),
66 &media_stat_->video_frames()));
67
63 demuxer_->Initialize(this); 68 demuxer_->Initialize(this);
64 interpolator_.SetUpperBound(base::TimeDelta()); 69 interpolator_.SetUpperBound(base::TimeDelta());
65 weak_this_ = weak_factory_.GetWeakPtr(); 70 weak_this_ = weak_factory_.GetWeakPtr();
66 } 71 }
67 72
68 MediaSourcePlayer::~MediaSourcePlayer() { 73 MediaSourcePlayer::~MediaSourcePlayer() {
69 Release(); 74 Release();
70 DCHECK_EQ(!drm_bridge_, !cdm_registration_id_); 75 DCHECK_EQ(!drm_bridge_, !cdm_registration_id_);
71 if (drm_bridge_) { 76 if (drm_bridge_) {
72 drm_bridge_->UnregisterPlayer(cdm_registration_id_); 77 drm_bridge_->UnregisterPlayer(cdm_registration_id_);
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 465
461 bool is_clock_manager = is_audio || !HasAudio(); 466 bool is_clock_manager = is_audio || !HasAudio();
462 467
463 if (is_clock_manager) 468 if (is_clock_manager)
464 decoder_starvation_callback_.Cancel(); 469 decoder_starvation_callback_.Cancel();
465 470
466 if (status == MEDIA_CODEC_ERROR) { 471 if (status == MEDIA_CODEC_ERROR) {
467 DVLOG(1) << __FUNCTION__ << " : decode error"; 472 DVLOG(1) << __FUNCTION__ << " : decode error";
468 Release(); 473 Release();
469 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); 474 manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
475 media_stat_->StopAndReport(GetCurrentTime());
470 return; 476 return;
471 } 477 }
472 478
473 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); 479 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
474 480
475 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of 481 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
476 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process 482 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
477 // any other pending events only after handling EOS detection. 483 // any other pending events only after handling EOS detection.
478 if (IsEventPending(SEEK_EVENT_PENDING)) { 484 if (IsEventPending(SEEK_EVENT_PENDING)) {
479 ProcessPendingEvents(); 485 ProcessPendingEvents();
486 media_stat_->StopAndReport(GetCurrentTime());
480 return; 487 return;
481 } 488 }
482 489
483 if ((status == MEDIA_CODEC_OK || status == MEDIA_CODEC_INPUT_END_OF_STREAM) && 490 if ((status == MEDIA_CODEC_OK || status == MEDIA_CODEC_INPUT_END_OF_STREAM) &&
484 is_clock_manager && current_presentation_timestamp != kNoTimestamp()) { 491 is_clock_manager && current_presentation_timestamp != kNoTimestamp()) {
485 UpdateTimestamps(current_presentation_timestamp, 492 UpdateTimestamps(current_presentation_timestamp,
486 max_presentation_timestamp); 493 max_presentation_timestamp);
487 } 494 }
488 495
489 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) { 496 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
490 PlaybackCompleted(is_audio); 497 PlaybackCompleted(is_audio);
491 if (is_clock_manager) 498 if (is_clock_manager)
492 interpolator_.StopInterpolating(); 499 interpolator_.StopInterpolating();
493 } 500 }
494 501
495 if (pending_event_ != NO_EVENT_PENDING) { 502 if (pending_event_ != NO_EVENT_PENDING) {
496 ProcessPendingEvents(); 503 ProcessPendingEvents();
504 media_stat_->StopAndReport(GetCurrentTime());
497 return; 505 return;
498 } 506 }
499 507
500 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 508 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
509 media_stat_->StopAndReport(GetCurrentTime());
501 return; 510 return;
511 }
502 512
503 if (!playing_) { 513 if (!playing_) {
504 if (is_clock_manager) 514 if (is_clock_manager)
505 interpolator_.StopInterpolating(); 515 interpolator_.StopInterpolating();
506 516
517 media_stat_->StopAndReport(GetCurrentTime());
507 return; 518 return;
508 } 519 }
509 520
510 if (status == MEDIA_CODEC_NO_KEY) { 521 if (status == MEDIA_CODEC_NO_KEY) {
511 if (key_added_while_decode_pending_) { 522 if (key_added_while_decode_pending_) {
512 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding."; 523 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding.";
513 ResumePlaybackAfterKeyAdded(); 524 ResumePlaybackAfterKeyAdded();
514 } else { 525 } else {
515 is_waiting_for_key_ = true; 526 is_waiting_for_key_ = true;
516 manager()->OnWaitingForDecryptionKey(player_id()); 527 manager()->OnWaitingForDecryptionKey(player_id());
517 } 528 }
529 media_stat_->StopAndReport(GetCurrentTime());
xhwang 2015/09/30 21:02:57 Why should we StopAndReport() after ResumePlayback
Tima Vaisburd 2015/10/01 20:05:15 Aha, this is the place that you explained to me! U
518 return; 530 return;
519 } 531 }
520 532
521 // If |key_added_while_decode_pending_| is true and both audio and video 533 // If |key_added_while_decode_pending_| is true and both audio and video
522 // decoding succeeded, we should clear |key_added_while_decode_pending_| here. 534 // decoding succeeded, we should clear |key_added_while_decode_pending_| here.
523 // But that would add more complexity into this function. If we don't clear it 535 // But that would add more complexity into this function. If we don't clear it
524 // here, the worst case would be we call ResumePlaybackAfterKeyAdded() when 536 // here, the worst case would be we call ResumePlaybackAfterKeyAdded() when
525 // we don't really have a new key. This should rarely happen and the 537 // we don't really have a new key. This should rarely happen and the
526 // performance impact should be pretty small. 538 // performance impact should be pretty small.
527 // TODO(qinmin/xhwang): This class is complicated because we handle both audio 539 // TODO(qinmin/xhwang): This class is complicated because we handle both audio
528 // and video in one file. If we separate them, we should be able to remove a 540 // and video in one file. If we separate them, we should be able to remove a
529 // lot of duplication. 541 // lot of duplication.
530 542
531 // If the status is MEDIA_CODEC_ABORT, stop decoding new data. The player is 543 // If the status is MEDIA_CODEC_ABORT, stop decoding new data. The player is
532 // in the middle of a seek or stop event and needs to wait for the IPCs to 544 // in the middle of a seek or stop event and needs to wait for the IPCs to
533 // come. 545 // come.
534 if (status == MEDIA_CODEC_ABORT) 546 if (status == MEDIA_CODEC_ABORT) {
547 media_stat_->StopAndReport(GetCurrentTime());
535 return; 548 return;
549 }
536 550
537 if (prerolling_ && IsPrerollFinished(is_audio)) { 551 if (prerolling_ && IsPrerollFinished(is_audio)) {
538 if (IsPrerollFinished(!is_audio)) { 552 if (IsPrerollFinished(!is_audio)) {
539 prerolling_ = false; 553 prerolling_ = false;
540 StartInternal(); 554 StartInternal();
541 } 555 }
542 return; 556 return;
543 } 557 }
544 558
545 if (is_clock_manager) { 559 if (is_clock_manager) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 return audio_decoder_job_->OutputEOSReached() || !HasAudio(); 661 return audio_decoder_job_->OutputEOSReached() || !HasAudio();
648 } 662 }
649 663
650 bool MediaSourcePlayer::VideoFinished() { 664 bool MediaSourcePlayer::VideoFinished() {
651 return video_decoder_job_->OutputEOSReached() || !HasVideo(); 665 return video_decoder_job_->OutputEOSReached() || !HasVideo();
652 } 666 }
653 667
654 void MediaSourcePlayer::OnDecoderStarved() { 668 void MediaSourcePlayer::OnDecoderStarved() {
655 DVLOG(1) << __FUNCTION__; 669 DVLOG(1) << __FUNCTION__;
656 670
671 media_stat_->AddStarvation();
672
657 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 673 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
658 ProcessPendingEvents(); 674 ProcessPendingEvents();
659 } 675 }
660 676
661 void MediaSourcePlayer::StartStarvationCallback( 677 void MediaSourcePlayer::StartStarvationCallback(
662 base::TimeDelta current_presentation_timestamp, 678 base::TimeDelta current_presentation_timestamp,
663 base::TimeDelta max_presentation_timestamp) { 679 base::TimeDelta max_presentation_timestamp) {
664 // 20ms was chosen because it is the typical size of a compressed audio frame. 680 // 20ms was chosen because it is the typical size of a compressed audio frame.
665 // Anything smaller than this would likely cause unnecessary cycling in and 681 // Anything smaller than this would likely cause unnecessary cycling in and
666 // out of the prefetch state. 682 // out of the prefetch state.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 } 729 }
714 730
715 if (!playing_) 731 if (!playing_)
716 return; 732 return;
717 733
718 start_time_ticks_ = base::TimeTicks::Now(); 734 start_time_ticks_ = base::TimeTicks::Now();
719 start_presentation_timestamp_ = GetCurrentTime(); 735 start_presentation_timestamp_ = GetCurrentTime();
720 if (!interpolator_.interpolating()) 736 if (!interpolator_.interpolating())
721 interpolator_.StartInterpolating(); 737 interpolator_.StartInterpolating();
722 738
739 media_stat_->Start(start_presentation_timestamp_);
740
723 if (!AudioFinished()) 741 if (!AudioFinished())
724 DecodeMoreAudio(); 742 DecodeMoreAudio();
725 743
726 if (!VideoFinished()) 744 if (!VideoFinished())
727 DecodeMoreVideo(); 745 DecodeMoreVideo();
728 } 746 }
729 747
730 void MediaSourcePlayer::OnDemuxerConfigsChanged() { 748 void MediaSourcePlayer::OnDemuxerConfigsChanged() {
731 manager()->OnMediaMetadataChanged( 749 manager()->OnMediaMetadataChanged(
732 player_id(), duration_, GetVideoWidth(), GetVideoHeight(), true); 750 player_id(), duration_, GetVideoWidth(), GetVideoHeight(), true);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release 835 // support setMediaKeys(0) (see http://crbug.com/330324), or when we release
818 // MediaDrm when the video is paused, or when the device goes to sleep (see 836 // MediaDrm when the video is paused, or when the device goes to sleep (see
819 // http://crbug.com/272421). 837 // http://crbug.com/272421).
820 audio_decoder_job_->SetDrmBridge(NULL); 838 audio_decoder_job_->SetDrmBridge(NULL);
821 video_decoder_job_->SetDrmBridge(NULL); 839 video_decoder_job_->SetDrmBridge(NULL);
822 cdm_registration_id_ = 0; 840 cdm_registration_id_ = 0;
823 drm_bridge_ = NULL; 841 drm_bridge_ = NULL;
824 } 842 }
825 843
826 } // namespace media 844 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698