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

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: Attempt to fix clang compilation 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
« no previous file with comments | « media/base/android/media_source_player.h ('k') | media/base/android/media_statistics.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/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_frame_stats()));
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_frame_stats()));
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();
497 return; 504 return;
498 } 505 }
499 506
500 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 507 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
508 media_stat_->StopAndReport(GetCurrentTime());
501 return; 509 return;
510 }
502 511
503 if (!playing_) { 512 if (!playing_) {
504 if (is_clock_manager) 513 if (is_clock_manager)
505 interpolator_.StopInterpolating(); 514 interpolator_.StopInterpolating();
506 515
516 media_stat_->StopAndReport(GetCurrentTime());
507 return; 517 return;
508 } 518 }
509 519
510 if (status == MEDIA_CODEC_NO_KEY) { 520 if (status == MEDIA_CODEC_NO_KEY) {
511 if (key_added_while_decode_pending_) { 521 if (key_added_while_decode_pending_) {
512 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding."; 522 DVLOG(2) << __FUNCTION__ << ": Key was added during decoding.";
513 ResumePlaybackAfterKeyAdded(); 523 ResumePlaybackAfterKeyAdded();
514 } else { 524 } else {
515 is_waiting_for_key_ = true; 525 is_waiting_for_key_ = true;
516 manager()->OnWaitingForDecryptionKey(player_id()); 526 manager()->OnWaitingForDecryptionKey(player_id());
527 media_stat_->StopAndReport(GetCurrentTime());
517 } 528 }
518 return; 529 return;
519 } 530 }
520 531
521 // If |key_added_while_decode_pending_| is true and both audio and video 532 // 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. 533 // 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 534 // 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 535 // 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 536 // we don't really have a new key. This should rarely happen and the
526 // performance impact should be pretty small. 537 // performance impact should be pretty small.
527 // TODO(qinmin/xhwang): This class is complicated because we handle both audio 538 // 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 539 // and video in one file. If we separate them, we should be able to remove a
529 // lot of duplication. 540 // lot of duplication.
530 541
531 // If the status is MEDIA_CODEC_ABORT, stop decoding new data. The player is 542 // 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 543 // in the middle of a seek or stop event and needs to wait for the IPCs to
533 // come. 544 // come.
534 if (status == MEDIA_CODEC_ABORT) 545 if (status == MEDIA_CODEC_ABORT) {
546 media_stat_->StopAndReport(GetCurrentTime());
535 return; 547 return;
548 }
536 549
537 if (prerolling_ && IsPrerollFinished(is_audio)) { 550 if (prerolling_ && IsPrerollFinished(is_audio)) {
538 if (IsPrerollFinished(!is_audio)) { 551 if (IsPrerollFinished(!is_audio)) {
539 prerolling_ = false; 552 prerolling_ = false;
540 StartInternal(); 553 StartInternal();
541 } 554 }
542 return; 555 return;
543 } 556 }
544 557
545 if (is_clock_manager) { 558 if (is_clock_manager) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 return audio_decoder_job_->OutputEOSReached() || !HasAudio(); 660 return audio_decoder_job_->OutputEOSReached() || !HasAudio();
648 } 661 }
649 662
650 bool MediaSourcePlayer::VideoFinished() { 663 bool MediaSourcePlayer::VideoFinished() {
651 return video_decoder_job_->OutputEOSReached() || !HasVideo(); 664 return video_decoder_job_->OutputEOSReached() || !HasVideo();
652 } 665 }
653 666
654 void MediaSourcePlayer::OnDecoderStarved() { 667 void MediaSourcePlayer::OnDecoderStarved() {
655 DVLOG(1) << __FUNCTION__; 668 DVLOG(1) << __FUNCTION__;
656 669
670 media_stat_->AddStarvation();
671
657 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 672 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
658 ProcessPendingEvents(); 673 ProcessPendingEvents();
659 } 674 }
660 675
661 void MediaSourcePlayer::StartStarvationCallback( 676 void MediaSourcePlayer::StartStarvationCallback(
662 base::TimeDelta current_presentation_timestamp, 677 base::TimeDelta current_presentation_timestamp,
663 base::TimeDelta max_presentation_timestamp) { 678 base::TimeDelta max_presentation_timestamp) {
664 // 20ms was chosen because it is the typical size of a compressed audio frame. 679 // 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 680 // Anything smaller than this would likely cause unnecessary cycling in and
666 // out of the prefetch state. 681 // out of the prefetch state.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 } 728 }
714 729
715 if (!playing_) 730 if (!playing_)
716 return; 731 return;
717 732
718 start_time_ticks_ = base::TimeTicks::Now(); 733 start_time_ticks_ = base::TimeTicks::Now();
719 start_presentation_timestamp_ = GetCurrentTime(); 734 start_presentation_timestamp_ = GetCurrentTime();
720 if (!interpolator_.interpolating()) 735 if (!interpolator_.interpolating())
721 interpolator_.StartInterpolating(); 736 interpolator_.StartInterpolating();
722 737
738 media_stat_->Start(start_presentation_timestamp_);
739
723 if (!AudioFinished()) 740 if (!AudioFinished())
724 DecodeMoreAudio(); 741 DecodeMoreAudio();
725 742
726 if (!VideoFinished()) 743 if (!VideoFinished())
727 DecodeMoreVideo(); 744 DecodeMoreVideo();
728 } 745 }
729 746
730 void MediaSourcePlayer::OnDemuxerConfigsChanged() { 747 void MediaSourcePlayer::OnDemuxerConfigsChanged() {
731 manager()->OnMediaMetadataChanged( 748 manager()->OnMediaMetadataChanged(
732 player_id(), duration_, GetVideoWidth(), GetVideoHeight(), true); 749 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 834 // 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 835 // MediaDrm when the video is paused, or when the device goes to sleep (see
819 // http://crbug.com/272421). 836 // http://crbug.com/272421).
820 audio_decoder_job_->SetDrmBridge(NULL); 837 audio_decoder_job_->SetDrmBridge(NULL);
821 video_decoder_job_->SetDrmBridge(NULL); 838 video_decoder_job_->SetDrmBridge(NULL);
822 cdm_registration_id_ = 0; 839 cdm_registration_id_ = 0;
823 drm_bridge_ = NULL; 840 drm_bridge_ = NULL;
824 } 841 }
825 842
826 } // namespace media 843 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.h ('k') | media/base/android/media_statistics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698