Add ability for NetLogLogger to gather data from more than just NetLog
[chromium-blink-merge.git] / chromecast / media / cma / pipeline / video_pipeline_impl.cc
blob560bccf52136d2b53562957311b090bf38977f19
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/media/cma/pipeline/video_pipeline_impl.h"
7 #include "base/bind.h"
8 #include "chromecast/media/cma/backend/video_pipeline_device.h"
9 #include "chromecast/media/cma/base/buffering_defs.h"
10 #include "chromecast/media/cma/base/cma_logging.h"
11 #include "chromecast/media/cma/base/coded_frame_provider.h"
12 #include "chromecast/media/cma/pipeline/av_pipeline_impl.h"
13 #include "media/base/video_decoder_config.h"
15 namespace chromecast {
16 namespace media {
18 namespace {
19 const size_t kMaxVideoFrameSize = 1024 * 1024;
22 VideoPipelineImpl::VideoPipelineImpl(VideoPipelineDevice* video_device)
23 : video_device_(video_device),
24 weak_factory_(this) {
25 weak_this_ = weak_factory_.GetWeakPtr();
26 av_pipeline_impl_ = new AvPipelineImpl(
27 video_device_,
28 base::Bind(&VideoPipelineImpl::OnUpdateConfig, base::Unretained(this)));
31 VideoPipelineImpl::~VideoPipelineImpl() {
32 av_pipeline_impl_->Finalize();
35 void VideoPipelineImpl::SetCodedFrameProvider(
36 scoped_ptr<CodedFrameProvider> frame_provider) {
37 av_pipeline_impl_->SetCodedFrameProvider(
38 frame_provider.Pass(), kAppVideoBufferSize, kMaxVideoFrameSize);
41 bool VideoPipelineImpl::StartPlayingFrom(
42 base::TimeDelta time,
43 const scoped_refptr<BufferingState>& buffering_state) {
44 CMALOG(kLogControl) << "VideoPipelineImpl::StartPlayingFrom t0="
45 << time.InMilliseconds();
47 // Reset the pipeline statistics.
48 previous_stats_ = ::media::PipelineStatistics();
50 // Start playing.
51 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError)
52 return false;
53 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kFlushed);
55 if (!av_pipeline_impl_->StartPlayingFrom(time, buffering_state)) {
56 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kError);
57 return false;
59 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kPlaying);
61 return true;
64 void VideoPipelineImpl::Flush(const ::media::PipelineStatusCB& status_cb) {
65 CMALOG(kLogControl) << "VideoPipelineImpl::Flush";
66 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
67 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
68 return;
70 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kPlaying);
71 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushing);
72 av_pipeline_impl_->Flush(
73 base::Bind(&VideoPipelineImpl::OnFlushDone, weak_this_, status_cb));
76 void VideoPipelineImpl::OnFlushDone(
77 const ::media::PipelineStatusCB& status_cb) {
78 CMALOG(kLogControl) << "VideoPipelineImpl::OnFlushDone";
79 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
80 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
81 return;
83 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
84 status_cb.Run(::media::PIPELINE_OK);
87 void VideoPipelineImpl::Stop() {
88 CMALOG(kLogControl) << "VideoPipelineImpl::Stop";
89 av_pipeline_impl_->Stop();
90 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kStopped);
93 void VideoPipelineImpl::SetCdm(BrowserCdmCast* media_keys) {
94 av_pipeline_impl_->SetCdm(media_keys);
97 void VideoPipelineImpl::SetClient(const VideoPipelineClient& client) {
98 video_client_ = client;
99 av_pipeline_impl_->SetClient(client.av_pipeline_client);
102 void VideoPipelineImpl::Initialize(
103 const ::media::VideoDecoderConfig& video_config,
104 scoped_ptr<CodedFrameProvider> frame_provider,
105 const ::media::PipelineStatusCB& status_cb) {
106 CMALOG(kLogControl) << "VideoPipelineImpl::Initialize "
107 << video_config.AsHumanReadableString();
108 VideoPipelineDevice::VideoClient client;
109 client.natural_size_changed_cb =
110 base::Bind(&VideoPipelineImpl::OnNaturalSizeChanged, weak_this_);
111 video_device_->SetVideoClient(client);
112 if (frame_provider)
113 SetCodedFrameProvider(frame_provider.Pass());
115 if (!video_device_->SetConfig(video_config) ||
116 !av_pipeline_impl_->Initialize()) {
117 status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED);
118 return;
120 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
121 status_cb.Run(::media::PIPELINE_OK);
124 void VideoPipelineImpl::OnUpdateConfig(
125 const ::media::AudioDecoderConfig& audio_config,
126 const ::media::VideoDecoderConfig& video_config) {
127 if (video_config.IsValidConfig()) {
128 CMALOG(kLogControl) << "VideoPipelineImpl::OnUpdateConfig "
129 << video_config.AsHumanReadableString();
131 bool success = video_device_->SetConfig(video_config);
132 if (!success &&
133 !video_client_.av_pipeline_client.playback_error_cb.is_null()) {
134 video_client_.av_pipeline_client.playback_error_cb.Run(
135 ::media::PIPELINE_ERROR_DECODE);
140 void VideoPipelineImpl::OnNaturalSizeChanged(const gfx::Size& size) {
141 if (av_pipeline_impl_->GetState() != AvPipelineImpl::kPlaying)
142 return;
144 if (!video_client_.natural_size_changed_cb.is_null())
145 video_client_.natural_size_changed_cb.Run(size);
148 void VideoPipelineImpl::UpdateStatistics() {
149 if (video_client_.av_pipeline_client.statistics_cb.is_null())
150 return;
152 MediaComponentDevice::Statistics device_stats;
153 if (!video_device_->GetStatistics(&device_stats))
154 return;
156 ::media::PipelineStatistics current_stats;
157 current_stats.video_bytes_decoded = device_stats.decoded_bytes;
158 current_stats.video_frames_decoded = device_stats.decoded_samples;
159 current_stats.video_frames_dropped = device_stats.dropped_samples;
161 ::media::PipelineStatistics delta_stats;
162 delta_stats.video_bytes_decoded =
163 current_stats.video_bytes_decoded - previous_stats_.video_bytes_decoded;
164 delta_stats.video_frames_decoded =
165 current_stats.video_frames_decoded - previous_stats_.video_frames_decoded;
166 delta_stats.video_frames_dropped =
167 current_stats.video_frames_dropped - previous_stats_.video_frames_dropped;
169 previous_stats_ = current_stats;
171 video_client_.av_pipeline_client.statistics_cb.Run(delta_stats);
174 } // namespace media
175 } // namespace chromecast