| Index: media/renderers/renderer_impl.cc
|
| diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
|
| index c4fbf53d3ffa3d1badacd0621677c3aaab570ade..60adbc78a81d51094976657bf0f0a820ad60a8e2 100644
|
| --- a/media/renderers/renderer_impl.cc
|
| +++ b/media/renderers/renderer_impl.cc
|
| @@ -20,6 +20,7 @@
|
| #include "media/base/demuxer_stream_provider.h"
|
| #include "media/base/media_switches.h"
|
| #include "media/base/renderer_client.h"
|
| +#include "media/base/stream_position.h"
|
| #include "media/base/time_source.h"
|
| #include "media/base/video_decoder_config.h"
|
| #include "media/base/video_renderer.h"
|
| @@ -44,6 +45,9 @@ class RendererImpl::RendererClientInternal : public RendererClient {
|
| void OnStatisticsUpdate(const PipelineStatistics& stats) override {
|
| renderer_->OnStatisticsUpdate(stats);
|
| }
|
| + void OnFirstVideoFrameTimestampKnown(base::TimeDelta timestamp) override {
|
| + renderer_->OnFirstVideoFrameTimestampKnown(timestamp);
|
| + }
|
| void OnBufferingStateChange(BufferingState state) override {
|
| renderer_->OnBufferingStateChange(type_, state);
|
| }
|
| @@ -204,7 +208,7 @@ void RendererImpl::Flush(const base::Closure& flush_cb) {
|
| FlushAudioRenderer();
|
| }
|
|
|
| -void RendererImpl::StartPlayingFrom(base::TimeDelta time) {
|
| +void RendererImpl::StartPlayingFrom(StreamPosition position) {
|
| DVLOG(1) << __func__;
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|
| @@ -213,12 +217,16 @@ void RendererImpl::StartPlayingFrom(base::TimeDelta time) {
|
| return;
|
| }
|
|
|
| - time_source_->SetMediaTime(time);
|
| + time_source_->SetMediaTime(position.time);
|
|
|
| + // XXX: There's no synchronization b/w the renderers. Is it safe to assume the
|
| + // demuxers will give us frames close enough to one another? If not we could
|
| + // start the video renderer, wait until we know the time of the first frame,
|
| + // and then start the audio renderer.
|
| if (audio_renderer_)
|
| - audio_renderer_->StartPlaying();
|
| + audio_renderer_->StartPlayingFrom(position);
|
| if (video_renderer_)
|
| - video_renderer_->StartPlayingFrom(time);
|
| + video_renderer_->StartPlayingFrom(position);
|
| }
|
|
|
| void RendererImpl::RestartStreamPlayback(DemuxerStream* stream,
|
| @@ -262,7 +270,8 @@ void RendererImpl::RestartVideoRenderer(base::TimeDelta time) {
|
| DCHECK(video_renderer_);
|
| DCHECK_EQ(state_, STATE_PLAYING);
|
| video_ended_ = false;
|
| - video_renderer_->StartPlayingFrom(time);
|
| + // XXX: Converted without thought.
|
| + video_renderer_->StartPlayingFrom(StreamPosition::Precise(time));
|
| }
|
|
|
| void RendererImpl::RestartAudioRenderer(base::TimeDelta time) {
|
| @@ -272,7 +281,8 @@ void RendererImpl::RestartAudioRenderer(base::TimeDelta time) {
|
| DCHECK(time_source_);
|
| DCHECK(audio_renderer_);
|
| audio_ended_ = false;
|
| - audio_renderer_->StartPlaying();
|
| + // XXX: Converted without thought.
|
| + audio_renderer_->StartPlayingFrom(StreamPosition::Precise(time));
|
| }
|
|
|
| void RendererImpl::SetPlaybackRate(double playback_rate) {
|
| @@ -343,9 +353,6 @@ bool RendererImpl::GetWallClockTimes(
|
| std::vector<base::TimeTicks>* wall_clock_times) {
|
| // No BelongsToCurrentThread() checking because this can be called from other
|
| // threads.
|
| - //
|
| - // TODO(scherkus): Currently called from VideoRendererImpl's internal thread,
|
| - // which should go away at some point http://crbug.com/110814
|
| if (clockless_video_playback_enabled_for_testing_) {
|
| if (media_timestamps.empty()) {
|
| *wall_clock_times = std::vector<base::TimeTicks>(1,
|
| @@ -562,6 +569,16 @@ void RendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) {
|
| client_->OnStatisticsUpdate(stats);
|
| }
|
|
|
| +// XXX: Revisit: I don't really like this. I considered letting the video
|
| +// renderer own the wall clock time source and manage this itself, but it didn't
|
| +// work for some reason. Try again.
|
| +void RendererImpl::OnFirstVideoFrameTimestampKnown(base::TimeDelta timestamp) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + LOG(ERROR) << __func__ << " " << timestamp.InMicroseconds();
|
| + if (wall_clock_time_source_)
|
| + wall_clock_time_source_->SetMediaTime(timestamp);
|
| +}
|
| +
|
| namespace {
|
|
|
| const char* BufferingStateStr(BufferingState state) {
|
|
|