OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/renderer/media/cma_renderer.h" | 5 #include "chromecast/renderer/media/cma_renderer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 media_pipeline_(std::move(media_pipeline)), | 54 media_pipeline_(std::move(media_pipeline)), |
55 audio_pipeline_(media_pipeline_->GetAudioPipeline()), | 55 audio_pipeline_(media_pipeline_->GetAudioPipeline()), |
56 video_pipeline_(media_pipeline_->GetVideoPipeline()), | 56 video_pipeline_(media_pipeline_->GetVideoPipeline()), |
57 video_renderer_sink_(video_renderer_sink), | 57 video_renderer_sink_(video_renderer_sink), |
58 state_(kUninitialized), | 58 state_(kUninitialized), |
59 is_pending_transition_(false), | 59 is_pending_transition_(false), |
60 has_audio_(false), | 60 has_audio_(false), |
61 has_video_(false), | 61 has_video_(false), |
62 received_audio_eos_(false), | 62 received_audio_eos_(false), |
63 received_video_eos_(false), | 63 received_video_eos_(false), |
64 initial_natural_size_(gfx::Size()), | |
65 initial_video_hole_created_(false), | |
66 gpu_factories_(gpu_factories), | 64 gpu_factories_(gpu_factories), |
67 time_interpolator_( | 65 time_interpolator_( |
68 new ::media::TimeDeltaInterpolator(&default_tick_clock_)), | 66 new ::media::TimeDeltaInterpolator(&default_tick_clock_)), |
69 playback_rate_(1.0), | 67 playback_rate_(1.0), |
70 weak_factory_(this) { | 68 weak_factory_(this) { |
71 weak_this_ = weak_factory_.GetWeakPtr(); | 69 weak_this_ = weak_factory_.GetWeakPtr(); |
72 thread_checker_.DetachFromThread(); | 70 thread_checker_.DetachFromThread(); |
73 | 71 |
74 time_interpolator_->SetUpperBound(base::TimeDelta()); | 72 time_interpolator_->SetUpperBound(base::TimeDelta()); |
75 } | 73 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 CMALOG(kLogControl) << __FUNCTION__ << ": " << time.InMilliseconds(); | 146 CMALOG(kLogControl) << __FUNCTION__ << ": " << time.InMilliseconds(); |
149 DCHECK(thread_checker_.CalledOnValidThread()); | 147 DCHECK(thread_checker_.CalledOnValidThread()); |
150 BeginStateTransition(); | 148 BeginStateTransition(); |
151 | 149 |
152 if (state_ == kError) { | 150 if (state_ == kError) { |
153 client_->OnError(::media::PIPELINE_ERROR_ABORT); | 151 client_->OnError(::media::PIPELINE_ERROR_ABORT); |
154 CompleteStateTransition(kError); | 152 CompleteStateTransition(kError); |
155 return; | 153 return; |
156 } | 154 } |
157 | 155 |
158 // Create a video hole frame just before starting playback. | |
159 // Note that instead of creating the video hole frame in Initialize(), we do | |
160 // it here because paint_cb_ (which eventually calls OnOpacityChanged) | |
161 // expects the current state to not be HaveNothing. And the place where | |
162 // the ready state is changed to HaveMetadata (OnPipelineMetadata) is | |
163 // right before the pipeline calls StartPlayingFrom (in | |
164 // Pipeline::StateTransitionTask). | |
165 if (HasVideo() && !initial_video_hole_created_) { | |
166 initial_video_hole_created_ = true; | |
167 video_renderer_sink_->PaintFrameUsingOldRenderingPath( | |
168 hole_frame_factory_->CreateHoleFrame(initial_natural_size_)); | |
169 } | |
170 | |
171 { | 156 { |
172 base::AutoLock auto_lock(time_interpolator_lock_); | 157 base::AutoLock auto_lock(time_interpolator_lock_); |
173 time_interpolator_.reset( | 158 time_interpolator_.reset( |
174 new ::media::TimeDeltaInterpolator(&default_tick_clock_)); | 159 new ::media::TimeDeltaInterpolator(&default_tick_clock_)); |
175 time_interpolator_->SetPlaybackRate(playback_rate_); | 160 time_interpolator_->SetPlaybackRate(playback_rate_); |
176 time_interpolator_->SetBounds(time, time); | 161 time_interpolator_->SetBounds(time, time); |
177 time_interpolator_->StartInterpolating(); | 162 time_interpolator_->StartInterpolating(); |
178 } | 163 } |
179 | 164 |
180 received_audio_eos_ = false; | 165 received_audio_eos_ = false; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 base::Bind(&CmaRenderer::OnNaturalSizeChanged, weak_this_)); | 308 base::Bind(&CmaRenderer::OnNaturalSizeChanged, weak_this_)); |
324 video_pipeline_->SetClient(client); | 309 video_pipeline_->SetClient(client); |
325 | 310 |
326 std::unique_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( | 311 std::unique_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( |
327 base::ThreadTaskRunnerHandle::Get(), media_task_runner_factory_, stream)); | 312 base::ThreadTaskRunnerHandle::Get(), media_task_runner_factory_, stream)); |
328 | 313 |
329 const ::media::VideoDecoderConfig& config = stream->video_decoder_config(); | 314 const ::media::VideoDecoderConfig& config = stream->video_decoder_config(); |
330 if (config.codec() == ::media::kCodecH264) | 315 if (config.codec() == ::media::kCodecH264) |
331 stream->EnableBitstreamConverter(); | 316 stream->EnableBitstreamConverter(); |
332 | 317 |
333 initial_natural_size_ = config.natural_size(); | |
334 | |
335 std::vector<::media::VideoDecoderConfig> configs; | 318 std::vector<::media::VideoDecoderConfig> configs; |
336 configs.push_back(config); | 319 configs.push_back(config); |
337 media_pipeline_->InitializeVideo(configs, std::move(frame_provider), | 320 media_pipeline_->InitializeVideo(configs, std::move(frame_provider), |
338 video_initialization_done_cb); | 321 video_initialization_done_cb); |
339 } | 322 } |
340 | 323 |
341 void CmaRenderer::OnVideoPipelineInitializeDone( | 324 void CmaRenderer::OnVideoPipelineInitializeDone( |
342 bool video_stream_present, | 325 bool video_stream_present, |
343 ::media::PipelineStatus status) { | 326 ::media::PipelineStatus status) { |
344 CMALOG(kLogControl) << __FUNCTION__ << ": state=" << state_; | 327 CMALOG(kLogControl) << __FUNCTION__ << ": state=" << state_; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 void CmaRenderer::OnStatisticsUpdated( | 373 void CmaRenderer::OnStatisticsUpdated( |
391 const ::media::PipelineStatistics& stats) { | 374 const ::media::PipelineStatistics& stats) { |
392 DCHECK(thread_checker_.CalledOnValidThread()); | 375 DCHECK(thread_checker_.CalledOnValidThread()); |
393 client_->OnStatisticsUpdate(stats); | 376 client_->OnStatisticsUpdate(stats); |
394 } | 377 } |
395 | 378 |
396 void CmaRenderer::OnNaturalSizeChanged(const gfx::Size& size) { | 379 void CmaRenderer::OnNaturalSizeChanged(const gfx::Size& size) { |
397 DCHECK(thread_checker_.CalledOnValidThread()); | 380 DCHECK(thread_checker_.CalledOnValidThread()); |
398 video_renderer_sink_->PaintFrameUsingOldRenderingPath( | 381 video_renderer_sink_->PaintFrameUsingOldRenderingPath( |
399 hole_frame_factory_->CreateHoleFrame(size)); | 382 hole_frame_factory_->CreateHoleFrame(size)); |
| 383 client_->OnVideoNaturalSizeChange(size); |
400 } | 384 } |
401 | 385 |
402 void CmaRenderer::OnPlaybackTimeUpdated(base::TimeDelta time, | 386 void CmaRenderer::OnPlaybackTimeUpdated(base::TimeDelta time, |
403 base::TimeDelta max_time, | 387 base::TimeDelta max_time, |
404 base::TimeTicks capture_time) { | 388 base::TimeTicks capture_time) { |
405 DCHECK(thread_checker_.CalledOnValidThread()); | 389 DCHECK(thread_checker_.CalledOnValidThread()); |
406 if (state_ != kPlaying) { | 390 if (state_ != kPlaying) { |
407 LOG(WARNING) << "Ignoring a late time update"; | 391 LOG(WARNING) << "Ignoring a late time update"; |
408 return; | 392 return; |
409 } | 393 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 is_pending_transition_ = true; | 450 is_pending_transition_ = true; |
467 } | 451 } |
468 | 452 |
469 void CmaRenderer::CompleteStateTransition(State new_state) { | 453 void CmaRenderer::CompleteStateTransition(State new_state) { |
470 state_ = new_state; | 454 state_ = new_state; |
471 is_pending_transition_ = false; | 455 is_pending_transition_ = false; |
472 } | 456 } |
473 | 457 |
474 } // namespace media | 458 } // namespace media |
475 } // namespace chromecast | 459 } // namespace chromecast |
OLD | NEW |