diff options
Diffstat (limited to 'chromecast/media/cma/pipeline')
6 files changed, 69 insertions, 2 deletions
diff --git a/chromecast/media/cma/pipeline/audio_pipeline_impl.cc b/chromecast/media/cma/pipeline/audio_pipeline_impl.cc index ab5478b..5148cb6 100644 --- a/chromecast/media/cma/pipeline/audio_pipeline_impl.cc +++ b/chromecast/media/cma/pipeline/audio_pipeline_impl.cc @@ -84,6 +84,7 @@ void AudioPipelineImpl::UpdateStatistics() { delta_stats.audio_bytes_decoded = current_stats.audio_bytes_decoded - previous_stats_.audio_bytes_decoded; + bytes_decoded_since_last_update_ = delta_stats.audio_bytes_decoded; previous_stats_ = current_stats; client().statistics_cb.Run(delta_stats); diff --git a/chromecast/media/cma/pipeline/av_pipeline_impl.cc b/chromecast/media/cma/pipeline/av_pipeline_impl.cc index 028fac4..815e8df 100644 --- a/chromecast/media/cma/pipeline/av_pipeline_impl.cc +++ b/chromecast/media/cma/pipeline/av_pipeline_impl.cc @@ -37,7 +37,8 @@ const int kNoCallbackId = -1; AvPipelineImpl::AvPipelineImpl(MediaPipelineBackend::Decoder* decoder, const AvPipelineClient& client) - : decoder_(decoder), + : bytes_decoded_since_last_update_(0), + decoder_(decoder), client_(client), state_(kUninitialized), buffered_time_(::media::kNoTimestamp()), diff --git a/chromecast/media/cma/pipeline/av_pipeline_impl.h b/chromecast/media/cma/pipeline/av_pipeline_impl.h index 4dfe091..ad44026 100644 --- a/chromecast/media/cma/pipeline/av_pipeline_impl.h +++ b/chromecast/media/cma/pipeline/av_pipeline_impl.h @@ -54,6 +54,10 @@ class AvPipelineImpl : MediaPipelineBackend::Decoder::Delegate { virtual void UpdateStatistics() = 0; + int bytes_decoded_since_last_update() const { + return bytes_decoded_since_last_update_; + } + protected: // Pipeline states. enum State { @@ -80,6 +84,7 @@ class AvPipelineImpl : MediaPipelineBackend::Decoder::Delegate { size_t max_frame_size); ::media::PipelineStatistics previous_stats_; + int bytes_decoded_since_last_update_; private: void OnFlushDone(); diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc index 73dc9ad..d3e78cb 100644 --- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc +++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc @@ -14,7 +14,6 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" -#include "base/time/time.h" #include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/media/cdm/browser_cdm_cast.h" #include "chromecast/media/cma/base/buffering_controller.h" @@ -52,6 +51,24 @@ const base::TimeDelta kTimeUpdateInterval( // kTimeUpdateInterval * kStatisticsUpdatePeriod. const int kStatisticsUpdatePeriod = 4; +void LogEstimatedBitrate(int decoded_bytes, + base::TimeDelta elapsed_time, + const char* tag, + const char* metric) { + int estimated_bitrate_in_kbps = + 8 * decoded_bytes / elapsed_time.InMilliseconds(); + + if (estimated_bitrate_in_kbps <= 0) + return; + + CMALOG(kLogControl) << "Estimated " << tag << " bitrate is " + << estimated_bitrate_in_kbps << " kbps"; + metrics::CastMetricsHelper* metrics_helper = + metrics::CastMetricsHelper::GetInstance(); + metrics_helper->RecordSimpleActionWithValue(metric, + estimated_bitrate_in_kbps); +} + } // namespace struct MediaPipelineImpl::FlushTask { @@ -68,6 +85,8 @@ MediaPipelineImpl::MediaPipelineImpl() video_decoder_(nullptr), pending_time_update_task_(false), statistics_rolling_counter_(0), + audio_bytes_for_bitrate_estimation_(0), + video_bytes_for_bitrate_estimation_(0), weak_factory_(this) { CMALOG(kLogControl) << __FUNCTION__; weak_this_ = weak_factory_.GetWeakPtr(); @@ -204,6 +223,7 @@ void MediaPipelineImpl::StartPlayingFrom(base::TimeDelta time) { return; } backend_state_ = BACKEND_STATE_PLAYING; + ResetBitrateState(); metrics::CastMetricsHelper::GetInstance()->RecordSimpleAction( "Cast.Platform.Playing"); @@ -318,6 +338,7 @@ void MediaPipelineImpl::SetPlaybackRate(double rate) { if (backend_state_ == BACKEND_STATE_PAUSED) { media_pipeline_backend_->Resume(); backend_state_ = BACKEND_STATE_PLAYING; + ResetBitrateState(); metrics::CastMetricsHelper::GetInstance()->RecordSimpleAction( "Cast.Platform.Playing"); } @@ -415,7 +436,31 @@ void MediaPipelineImpl::UpdateMediaTime() { audio_pipeline_->UpdateStatistics(); if (video_pipeline_) video_pipeline_->UpdateStatistics(); + + if (backend_state_ == BACKEND_STATE_PLAYING) { + base::TimeTicks current_time = base::TimeTicks::Now(); + if (audio_pipeline_) + audio_bytes_for_bitrate_estimation_ += + audio_pipeline_->bytes_decoded_since_last_update(); + if (video_pipeline_) + video_bytes_for_bitrate_estimation_ += + video_pipeline_->bytes_decoded_since_last_update(); + elapsed_time_delta_ += current_time - last_sample_time_; + if (elapsed_time_delta_.InMilliseconds() > 5000) { + if (audio_pipeline_) + LogEstimatedBitrate(audio_bytes_for_bitrate_estimation_, + elapsed_time_delta_, "audio", + "Cast.Platform.AudioBitrate"); + if (video_pipeline_) + LogEstimatedBitrate(video_bytes_for_bitrate_estimation_, + elapsed_time_delta_, "video", + "Cast.Platform.VideoBitrate"); + ResetBitrateState(); + } + last_sample_time_ = current_time; + } } + statistics_rolling_counter_ = (statistics_rolling_counter_ + 1) % kStatisticsUpdatePeriod; @@ -468,5 +513,12 @@ void MediaPipelineImpl::OnError(::media::PipelineStatus error) { client_.error_cb.Run(error); } +void MediaPipelineImpl::ResetBitrateState() { + elapsed_time_delta_ = base::TimeDelta::FromSeconds(0); + audio_bytes_for_bitrate_estimation_ = 0; + video_bytes_for_bitrate_estimation_ = 0; + last_sample_time_ = base::TimeTicks::Now(); +} + } // namespace media } // namespace chromecast diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.h b/chromecast/media/cma/pipeline/media_pipeline_impl.h index 6773643..1b6660f 100644 --- a/chromecast/media/cma/pipeline/media_pipeline_impl.h +++ b/chromecast/media/cma/pipeline/media_pipeline_impl.h @@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "chromecast/media/cma/pipeline/load_type.h" #include "chromecast/media/cma/pipeline/media_pipeline_client.h" #include "chromecast/public/media/media_pipeline_backend.h" @@ -82,6 +83,8 @@ class MediaPipelineImpl { void OnError(::media::PipelineStatus error); + void ResetBitrateState(); + base::ThreadChecker thread_checker_; MediaPipelineClient client_; scoped_ptr<BufferingController> buffering_controller_; @@ -108,6 +111,10 @@ class MediaPipelineImpl { // Used to make the statistics update period a multiplier of the time update // period. int statistics_rolling_counter_; + base::TimeTicks last_sample_time_; + base::TimeDelta elapsed_time_delta_; + int audio_bytes_for_bitrate_estimation_; + int video_bytes_for_bitrate_estimation_; base::WeakPtr<MediaPipelineImpl> weak_this_; base::WeakPtrFactory<MediaPipelineImpl> weak_factory_; diff --git a/chromecast/media/cma/pipeline/video_pipeline_impl.cc b/chromecast/media/cma/pipeline/video_pipeline_impl.cc index 6b480c6..04b5046 100644 --- a/chromecast/media/cma/pipeline/video_pipeline_impl.cc +++ b/chromecast/media/cma/pipeline/video_pipeline_impl.cc @@ -117,6 +117,7 @@ void VideoPipelineImpl::UpdateStatistics() { delta_stats.video_frames_dropped = current_stats.video_frames_dropped - previous_stats_.video_frames_dropped; + bytes_decoded_since_last_update_ = delta_stats.video_bytes_decoded; previous_stats_ = current_stats; client().statistics_cb.Run(delta_stats); |