OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chromecast/browser/media/cast_renderer.h" | 5 #include "chromecast/browser/media/cast_renderer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "chromecast/base/task_runner_impl.h" | 9 #include "chromecast/base/task_runner_impl.h" |
10 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" | 10 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 // Maximum difference between audio frame PTS and video frame PTS | 25 // Maximum difference between audio frame PTS and video frame PTS |
26 // for frames read from the DemuxerStream. | 26 // for frames read from the DemuxerStream. |
27 const base::TimeDelta kMaxDeltaFetcher(base::TimeDelta::FromMilliseconds(2000)); | 27 const base::TimeDelta kMaxDeltaFetcher(base::TimeDelta::FromMilliseconds(2000)); |
28 } // namespace | 28 } // namespace |
29 | 29 |
30 CastRenderer::CastRenderer( | 30 CastRenderer::CastRenderer( |
31 const CreateMediaPipelineBackendCB& create_backend_cb, | 31 const CreateMediaPipelineBackendCB& create_backend_cb, |
32 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) | 32 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) |
33 : create_backend_cb_(create_backend_cb), | 33 : create_backend_cb_(create_backend_cb), |
34 task_runner_(task_runner), | 34 task_runner_(task_runner), |
| 35 client_(nullptr), |
35 media_task_runner_factory_( | 36 media_task_runner_factory_( |
36 new BalancedMediaTaskRunnerFactory(kMaxDeltaFetcher)) { | 37 new BalancedMediaTaskRunnerFactory(kMaxDeltaFetcher)), |
| 38 weak_factory_(this) { |
37 CMALOG(kLogControl) << __FUNCTION__ << ": " << this; | 39 CMALOG(kLogControl) << __FUNCTION__ << ": " << this; |
38 } | 40 } |
39 | 41 |
40 CastRenderer::~CastRenderer() { | 42 CastRenderer::~CastRenderer() { |
41 CMALOG(kLogControl) << __FUNCTION__ << ": " << this; | 43 CMALOG(kLogControl) << __FUNCTION__ << ": " << this; |
42 DCHECK(task_runner_->BelongsToCurrentThread()); | 44 DCHECK(task_runner_->BelongsToCurrentThread()); |
43 } | 45 } |
44 | 46 |
45 void CastRenderer::Initialize( | 47 void CastRenderer::Initialize( |
46 ::media::DemuxerStreamProvider* demuxer_stream_provider, | 48 ::media::DemuxerStreamProvider* demuxer_stream_provider, |
47 const ::media::PipelineStatusCB& init_cb, | 49 ::media::RendererClient* client, |
48 const ::media::StatisticsCB& statistics_cb, | 50 const ::media::PipelineStatusCB& init_cb) { |
49 const ::media::BufferingStateCB& buffering_state_cb, | |
50 const base::Closure& ended_cb, | |
51 const ::media::PipelineStatusCB& error_cb, | |
52 const base::Closure& waiting_for_decryption_key_cb) { | |
53 CMALOG(kLogControl) << __FUNCTION__ << ": " << this; | 51 CMALOG(kLogControl) << __FUNCTION__ << ": " << this; |
54 DCHECK(task_runner_->BelongsToCurrentThread()); | 52 DCHECK(task_runner_->BelongsToCurrentThread()); |
55 | 53 |
56 // Create pipeline backend. | 54 // Create pipeline backend. |
57 backend_task_runner_.reset(new TaskRunnerImpl()); | 55 backend_task_runner_.reset(new TaskRunnerImpl()); |
58 // TODO(erickung): crbug.com/443956. Need to provide right LoadType. | 56 // TODO(erickung): crbug.com/443956. Need to provide right LoadType. |
59 LoadType load_type = kLoadTypeMediaSource; | 57 LoadType load_type = kLoadTypeMediaSource; |
60 MediaPipelineDeviceParams::MediaSyncType sync_type = | 58 MediaPipelineDeviceParams::MediaSyncType sync_type = |
61 (load_type == kLoadTypeMediaStream) | 59 (load_type == kLoadTypeMediaStream) |
62 ? MediaPipelineDeviceParams::kModeIgnorePts | 60 ? MediaPipelineDeviceParams::kModeIgnorePts |
63 : MediaPipelineDeviceParams::kModeSyncPts; | 61 : MediaPipelineDeviceParams::kModeSyncPts; |
64 MediaPipelineDeviceParams params(sync_type, backend_task_runner_.get()); | 62 MediaPipelineDeviceParams params(sync_type, backend_task_runner_.get()); |
65 std::unique_ptr<MediaPipelineBackend> backend = | 63 std::unique_ptr<MediaPipelineBackend> backend = |
66 create_backend_cb_.Run(params); | 64 create_backend_cb_.Run(params); |
67 | 65 |
68 // Create pipeline. | 66 // Create pipeline. |
69 MediaPipelineClient pipeline_client; | 67 MediaPipelineClient pipeline_client; |
70 pipeline_client.error_cb = error_cb; | 68 pipeline_client.error_cb = |
71 pipeline_client.buffering_state_cb = buffering_state_cb; | 69 base::Bind(&CastRenderer::OnError, weak_factory_.GetWeakPtr()); |
| 70 pipeline_client.buffering_state_cb = base::Bind( |
| 71 &CastRenderer::OnBufferingStateChange, weak_factory_.GetWeakPtr()); |
72 pipeline_.reset(new MediaPipelineImpl); | 72 pipeline_.reset(new MediaPipelineImpl); |
73 pipeline_->SetClient(pipeline_client); | 73 pipeline_->SetClient(pipeline_client); |
74 pipeline_->Initialize(load_type, std::move(backend)); | 74 pipeline_->Initialize(load_type, std::move(backend)); |
75 | 75 |
76 // Initialize audio. | 76 // Initialize audio. |
77 ::media::DemuxerStream* audio_stream = | 77 ::media::DemuxerStream* audio_stream = |
78 demuxer_stream_provider->GetStream(::media::DemuxerStream::AUDIO); | 78 demuxer_stream_provider->GetStream(::media::DemuxerStream::AUDIO); |
79 if (audio_stream) { | 79 if (audio_stream) { |
80 AvPipelineClient audio_client; | 80 AvPipelineClient audio_client; |
81 audio_client.wait_for_key_cb = waiting_for_decryption_key_cb; | 81 audio_client.wait_for_key_cb = base::Bind( |
82 audio_client.eos_cb = | 82 &CastRenderer::OnWaitingForDecryptionKey, weak_factory_.GetWeakPtr()); |
83 base::Bind(&CastRenderer::OnEos, base::Unretained(this), STREAM_AUDIO); | 83 audio_client.eos_cb = base::Bind(&CastRenderer::OnEnded, |
84 audio_client.playback_error_cb = error_cb; | 84 weak_factory_.GetWeakPtr(), STREAM_AUDIO); |
85 audio_client.statistics_cb = statistics_cb; | 85 audio_client.playback_error_cb = |
| 86 base::Bind(&CastRenderer::OnError, weak_factory_.GetWeakPtr()); |
| 87 audio_client.statistics_cb = base::Bind(&CastRenderer::OnStatisticsUpdate, |
| 88 weak_factory_.GetWeakPtr()); |
86 std::unique_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( | 89 std::unique_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( |
87 task_runner_, media_task_runner_factory_, audio_stream)); | 90 task_runner_, media_task_runner_factory_, audio_stream)); |
88 ::media::PipelineStatus status = | 91 ::media::PipelineStatus status = |
89 pipeline_->InitializeAudio(audio_stream->audio_decoder_config(), | 92 pipeline_->InitializeAudio(audio_stream->audio_decoder_config(), |
90 audio_client, std::move(frame_provider)); | 93 audio_client, std::move(frame_provider)); |
91 if (status != ::media::PIPELINE_OK) { | 94 if (status != ::media::PIPELINE_OK) { |
92 init_cb.Run(status); | 95 init_cb.Run(status); |
93 return; | 96 return; |
94 } | 97 } |
95 audio_stream->EnableBitstreamConverter(); | 98 audio_stream->EnableBitstreamConverter(); |
96 } | 99 } |
97 | 100 |
98 // Initialize video. | 101 // Initialize video. |
99 ::media::DemuxerStream* video_stream = | 102 ::media::DemuxerStream* video_stream = |
100 demuxer_stream_provider->GetStream(::media::DemuxerStream::VIDEO); | 103 demuxer_stream_provider->GetStream(::media::DemuxerStream::VIDEO); |
101 if (video_stream) { | 104 if (video_stream) { |
102 VideoPipelineClient video_client; | 105 VideoPipelineClient video_client; |
103 // TODO(alokp): Set VideoPipelineClient::natural_size_changed_cb. | 106 // TODO(alokp): Set VideoPipelineClient::natural_size_changed_cb. |
104 video_client.av_pipeline_client.wait_for_key_cb = | 107 video_client.av_pipeline_client.wait_for_key_cb = base::Bind( |
105 waiting_for_decryption_key_cb; | 108 &CastRenderer::OnWaitingForDecryptionKey, weak_factory_.GetWeakPtr()); |
106 video_client.av_pipeline_client.eos_cb = | 109 video_client.av_pipeline_client.eos_cb = base::Bind( |
107 base::Bind(&CastRenderer::OnEos, base::Unretained(this), STREAM_VIDEO); | 110 &CastRenderer::OnEnded, weak_factory_.GetWeakPtr(), STREAM_VIDEO); |
108 video_client.av_pipeline_client.playback_error_cb = error_cb; | 111 video_client.av_pipeline_client.playback_error_cb = |
109 video_client.av_pipeline_client.statistics_cb = statistics_cb; | 112 base::Bind(&CastRenderer::OnError, weak_factory_.GetWeakPtr()); |
| 113 video_client.av_pipeline_client.statistics_cb = base::Bind( |
| 114 &CastRenderer::OnStatisticsUpdate, weak_factory_.GetWeakPtr()); |
110 // TODO(alokp): Change MediaPipelineImpl API to accept a single config | 115 // TODO(alokp): Change MediaPipelineImpl API to accept a single config |
111 // after CmaRenderer is deprecated. | 116 // after CmaRenderer is deprecated. |
112 std::vector<::media::VideoDecoderConfig> video_configs; | 117 std::vector<::media::VideoDecoderConfig> video_configs; |
113 video_configs.push_back(video_stream->video_decoder_config()); | 118 video_configs.push_back(video_stream->video_decoder_config()); |
114 std::unique_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( | 119 std::unique_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( |
115 task_runner_, media_task_runner_factory_, video_stream)); | 120 task_runner_, media_task_runner_factory_, video_stream)); |
116 ::media::PipelineStatus status = pipeline_->InitializeVideo( | 121 ::media::PipelineStatus status = pipeline_->InitializeVideo( |
117 video_configs, video_client, std::move(frame_provider)); | 122 video_configs, video_client, std::move(frame_provider)); |
118 if (status != ::media::PIPELINE_OK) { | 123 if (status != ::media::PIPELINE_OK) { |
119 init_cb.Run(status); | 124 init_cb.Run(status); |
120 return; | 125 return; |
121 } | 126 } |
122 video_stream->EnableBitstreamConverter(); | 127 video_stream->EnableBitstreamConverter(); |
123 } | 128 } |
124 | 129 |
125 ended_cb_ = ended_cb; | 130 client_ = client; |
126 init_cb.Run(::media::PIPELINE_OK); | 131 init_cb.Run(::media::PIPELINE_OK); |
127 } | 132 } |
128 | 133 |
129 void CastRenderer::SetCdm(::media::CdmContext* cdm_context, | 134 void CastRenderer::SetCdm(::media::CdmContext* cdm_context, |
130 const ::media::CdmAttachedCB& cdm_attached_cb) { | 135 const ::media::CdmAttachedCB& cdm_attached_cb) { |
131 DCHECK(task_runner_->BelongsToCurrentThread()); | 136 DCHECK(task_runner_->BelongsToCurrentThread()); |
132 NOTIMPLEMENTED(); | 137 NOTIMPLEMENTED(); |
133 } | 138 } |
134 | 139 |
135 void CastRenderer::Flush(const base::Closure& flush_cb) { | 140 void CastRenderer::Flush(const base::Closure& flush_cb) { |
(...skipping 27 matching lines...) Expand all Loading... |
163 bool CastRenderer::HasAudio() { | 168 bool CastRenderer::HasAudio() { |
164 DCHECK(task_runner_->BelongsToCurrentThread()); | 169 DCHECK(task_runner_->BelongsToCurrentThread()); |
165 return pipeline_->HasAudio(); | 170 return pipeline_->HasAudio(); |
166 } | 171 } |
167 | 172 |
168 bool CastRenderer::HasVideo() { | 173 bool CastRenderer::HasVideo() { |
169 DCHECK(task_runner_->BelongsToCurrentThread()); | 174 DCHECK(task_runner_->BelongsToCurrentThread()); |
170 return pipeline_->HasVideo(); | 175 return pipeline_->HasVideo(); |
171 } | 176 } |
172 | 177 |
173 void CastRenderer::OnEos(Stream stream) { | 178 void CastRenderer::OnError(::media::PipelineStatus status) { |
| 179 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 180 client_->OnError(status); |
| 181 } |
| 182 |
| 183 void CastRenderer::OnEnded(Stream stream) { |
| 184 DCHECK(task_runner_->BelongsToCurrentThread()); |
174 DCHECK(!eos_[stream]); | 185 DCHECK(!eos_[stream]); |
175 eos_[stream] = true; | 186 eos_[stream] = true; |
176 CMALOG(kLogControl) << __FUNCTION__ << ": eos_audio=" << eos_[STREAM_AUDIO] | 187 CMALOG(kLogControl) << __FUNCTION__ << ": eos_audio=" << eos_[STREAM_AUDIO] |
177 << " eos_video=" << eos_[STREAM_VIDEO]; | 188 << " eos_video=" << eos_[STREAM_VIDEO]; |
178 if (eos_[STREAM_AUDIO] && eos_[STREAM_VIDEO]) | 189 if (eos_[STREAM_AUDIO] && eos_[STREAM_VIDEO]) |
179 ended_cb_.Run(); | 190 client_->OnEnded(); |
| 191 } |
| 192 |
| 193 void CastRenderer::OnStatisticsUpdate( |
| 194 const ::media::PipelineStatistics& stats) { |
| 195 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 196 client_->OnStatisticsUpdate(stats); |
| 197 } |
| 198 |
| 199 void CastRenderer::OnBufferingStateChange(::media::BufferingState state) { |
| 200 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 201 client_->OnBufferingStateChange(state); |
| 202 } |
| 203 |
| 204 void CastRenderer::OnWaitingForDecryptionKey() { |
| 205 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 206 client_->OnWaitingForDecryptionKey(); |
180 } | 207 } |
181 | 208 |
182 } // namespace media | 209 } // namespace media |
183 } // namespace chromecast | 210 } // namespace chromecast |
OLD | NEW |