summaryrefslogtreecommitdiffstats
path: root/chromecast/media/cma/pipeline
diff options
context:
space:
mode:
Diffstat (limited to 'chromecast/media/cma/pipeline')
-rw-r--r--chromecast/media/cma/pipeline/audio_pipeline_impl.cc1
-rw-r--r--chromecast/media/cma/pipeline/av_pipeline_impl.cc3
-rw-r--r--chromecast/media/cma/pipeline/av_pipeline_impl.h5
-rw-r--r--chromecast/media/cma/pipeline/media_pipeline_impl.cc54
-rw-r--r--chromecast/media/cma/pipeline/media_pipeline_impl.h7
-rw-r--r--chromecast/media/cma/pipeline/video_pipeline_impl.cc1
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);