Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1659)

Side by Side Diff: media/base/pipeline_impl.cc

Issue 2366373003: Not for submission. fastSeek prototype. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/base/renderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/base/pipeline_impl.h" 5 #include "media/base/pipeline_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
18 #include "base/synchronization/waitable_event.h" 18 #include "base/synchronization/waitable_event.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
21 #include "media/base/demuxer.h" 21 #include "media/base/demuxer.h"
22 #include "media/base/media_log.h" 22 #include "media/base/media_log.h"
23 #include "media/base/media_switches.h" 23 #include "media/base/media_switches.h"
24 #include "media/base/renderer.h" 24 #include "media/base/renderer.h"
25 #include "media/base/renderer_client.h" 25 #include "media/base/renderer_client.h"
26 #include "media/base/serial_runner.h" 26 #include "media/base/serial_runner.h"
27 #include "media/base/stream_position.h"
27 #include "media/base/text_renderer.h" 28 #include "media/base/text_renderer.h"
28 #include "media/base/text_track_config.h" 29 #include "media/base/text_track_config.h"
29 #include "media/base/timestamp_constants.h" 30 #include "media/base/timestamp_constants.h"
30 #include "media/base/video_decoder_config.h" 31 #include "media/base/video_decoder_config.h"
31 32
32 static const double kDefaultPlaybackRate = 0.0; 33 static const double kDefaultPlaybackRate = 0.0;
33 static const float kDefaultVolume = 1.0f; 34 static const float kDefaultVolume = 1.0f;
34 35
35 namespace media { 36 namespace media {
36 37
37 class PipelineImpl::RendererWrapper : public DemuxerHost, 38 class PipelineImpl::RendererWrapper : public DemuxerHost,
38 public RendererClient { 39 public RendererClient {
39 public: 40 public:
40 RendererWrapper(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, 41 RendererWrapper(scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
41 scoped_refptr<MediaLog> media_log); 42 scoped_refptr<MediaLog> media_log);
42 ~RendererWrapper() final; 43 ~RendererWrapper() final;
43 44
44 void Start(Demuxer* demuxer, 45 void Start(Demuxer* demuxer,
45 std::unique_ptr<Renderer> renderer, 46 std::unique_ptr<Renderer> renderer,
46 std::unique_ptr<TextRenderer> text_renderer, 47 std::unique_ptr<TextRenderer> text_renderer,
47 base::WeakPtr<PipelineImpl> weak_pipeline); 48 base::WeakPtr<PipelineImpl> weak_pipeline);
48 void Stop(const base::Closure& stop_cb); 49 void Stop(const base::Closure& stop_cb);
49 void Seek(base::TimeDelta time); 50 void Seek(StreamPosition position);
50 void Suspend(); 51 void Suspend();
51 void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time); 52 void Resume(std::unique_ptr<Renderer> renderer, base::TimeDelta time);
52 void SetPlaybackRate(double playback_rate); 53 void SetPlaybackRate(double playback_rate);
53 void SetVolume(float volume); 54 void SetVolume(float volume);
54 base::TimeDelta GetMediaTime() const; 55 base::TimeDelta GetMediaTime() const;
55 Ranges<base::TimeDelta> GetBufferedTimeRanges() const; 56 Ranges<base::TimeDelta> GetBufferedTimeRanges() const;
56 bool DidLoadingProgress(); 57 bool DidLoadingProgress();
57 PipelineStatistics GetStatistics() const; 58 PipelineStatistics GetStatistics() const;
58 void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); 59 void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb);
59 60
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 void SetDuration(base::TimeDelta duration) final; 103 void SetDuration(base::TimeDelta duration) final;
103 void OnDemuxerError(PipelineStatus error) final; 104 void OnDemuxerError(PipelineStatus error) final;
104 void AddTextStream(DemuxerStream* text_stream, 105 void AddTextStream(DemuxerStream* text_stream,
105 const TextTrackConfig& config) final; 106 const TextTrackConfig& config) final;
106 void RemoveTextStream(DemuxerStream* text_stream) final; 107 void RemoveTextStream(DemuxerStream* text_stream) final;
107 108
108 // RendererClient implementation. 109 // RendererClient implementation.
109 void OnError(PipelineStatus error) final; 110 void OnError(PipelineStatus error) final;
110 void OnEnded() final; 111 void OnEnded() final;
111 void OnStatisticsUpdate(const PipelineStatistics& stats) final; 112 void OnStatisticsUpdate(const PipelineStatistics& stats) final;
113 void OnFirstVideoFrameTimestampKnown(base::TimeDelta timestamp) final;
112 void OnBufferingStateChange(BufferingState state) final; 114 void OnBufferingStateChange(BufferingState state) final;
113 void OnWaitingForDecryptionKey() final; 115 void OnWaitingForDecryptionKey() final;
114 void OnVideoNaturalSizeChange(const gfx::Size& size) final; 116 void OnVideoNaturalSizeChange(const gfx::Size& size) final;
115 void OnVideoOpacityChange(bool opaque) final; 117 void OnVideoOpacityChange(bool opaque) final;
116 void OnDurationChange(base::TimeDelta duration) final; 118 void OnDurationChange(base::TimeDelta duration) final;
117 119
118 // TextRenderer tasks and notifications. 120 // TextRenderer tasks and notifications.
119 void OnTextRendererEnded(); 121 void OnTextRendererEnded();
120 void AddTextStreamTask(DemuxerStream* text_stream, 122 void AddTextStreamTask(DemuxerStream* text_stream,
121 const TextTrackConfig& config); 123 const TextTrackConfig& config);
122 void RemoveTextStreamTask(DemuxerStream* text_stream); 124 void RemoveTextStreamTask(DemuxerStream* text_stream);
123 125
124 // Common handlers for notifications from renderers and demuxer. 126 // Common handlers for notifications from renderers and demuxer.
125 void OnPipelineError(PipelineStatus error); 127 void OnPipelineError(PipelineStatus error);
126 void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb, 128 void OnCdmAttached(const CdmAttachedCB& cdm_attached_cb,
127 CdmContext* cdm_context, 129 CdmContext* cdm_context,
128 bool success); 130 bool success);
129 void CheckPlaybackEnded(); 131 void CheckPlaybackEnded();
130 132
131 // State transition tasks. 133 // State transition tasks.
132 void SetState(State next_state); 134 void SetState(State next_state);
133 void CompleteSeek(base::TimeDelta seek_time, PipelineStatus status); 135 void CompleteSeek(StreamPosition position, PipelineStatus status);
134 void CompleteSuspend(PipelineStatus status); 136 void CompleteSuspend(PipelineStatus status);
135 void InitializeDemuxer(const PipelineStatusCB& done_cb); 137 void InitializeDemuxer(const PipelineStatusCB& done_cb);
136 void InitializeRenderer(const PipelineStatusCB& done_cb); 138 void InitializeRenderer(const PipelineStatusCB& done_cb);
137 void DestroyRenderer(); 139 void DestroyRenderer();
138 void ReportMetadata(); 140 void ReportMetadata();
139 141
140 const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; 142 const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
141 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 143 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
142 const scoped_refptr<MediaLog> media_log_; 144 const scoped_refptr<MediaLog> media_log_;
143 145
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 fns.Push(base::Bind(&RendererWrapper::InitializeDemuxer, weak_this_)); 244 fns.Push(base::Bind(&RendererWrapper::InitializeDemuxer, weak_this_));
243 245
244 // Once the demuxer is initialized successfully, media metadata must be 246 // Once the demuxer is initialized successfully, media metadata must be
245 // available - report the metadata to client. 247 // available - report the metadata to client.
246 fns.Push(base::Bind(&RendererWrapper::ReportMetadata, weak_this_)); 248 fns.Push(base::Bind(&RendererWrapper::ReportMetadata, weak_this_));
247 249
248 // Initialize renderer. 250 // Initialize renderer.
249 fns.Push(base::Bind(&RendererWrapper::InitializeRenderer, weak_this_)); 251 fns.Push(base::Bind(&RendererWrapper::InitializeRenderer, weak_this_));
250 252
251 // Run tasks. 253 // Run tasks.
252 pending_callbacks_ = 254 pending_callbacks_ = SerialRunner::Run(
253 SerialRunner::Run(fns, base::Bind(&RendererWrapper::CompleteSeek, 255 fns, base::Bind(&RendererWrapper::CompleteSeek, weak_this_,
254 weak_this_, base::TimeDelta())); 256 StreamPosition::Precise(base::TimeDelta())));
255 } 257 }
256 258
257 void PipelineImpl::RendererWrapper::Stop(const base::Closure& stop_cb) { 259 void PipelineImpl::RendererWrapper::Stop(const base::Closure& stop_cb) {
258 DCHECK(media_task_runner_->BelongsToCurrentThread()); 260 DCHECK(media_task_runner_->BelongsToCurrentThread());
259 DCHECK(state_ != kStopping && state_ != kStopped); 261 DCHECK(state_ != kStopping && state_ != kStopped);
260 262
261 SetState(kStopping); 263 SetState(kStopping);
262 264
263 if (shared_state_.statistics.video_frames_decoded > 0) { 265 if (shared_state_.statistics.video_frames_decoded > 0) {
264 UMA_HISTOGRAM_COUNTS("Media.DroppedFrameCount", 266 UMA_HISTOGRAM_COUNTS("Media.DroppedFrameCount",
(...skipping 18 matching lines...) Expand all
283 285
284 // Post the stop callback to enqueue it after the tasks that may have been 286 // Post the stop callback to enqueue it after the tasks that may have been
285 // posted by Demuxer and Renderer during stopping. Note that in theory the 287 // posted by Demuxer and Renderer during stopping. Note that in theory the
286 // tasks posted by Demuxer/Renderer may post even more tasks that will get 288 // tasks posted by Demuxer/Renderer may post even more tasks that will get
287 // enqueued after |stop_cb|. This may be problematic because Demuxer may 289 // enqueued after |stop_cb|. This may be problematic because Demuxer may
288 // get destroyed as soon as |stop_cb| is run. In practice this is not a 290 // get destroyed as soon as |stop_cb| is run. In practice this is not a
289 // problem, but ideally Demuxer should be destroyed on the media thread. 291 // problem, but ideally Demuxer should be destroyed on the media thread.
290 media_task_runner_->PostTask(FROM_HERE, stop_cb); 292 media_task_runner_->PostTask(FROM_HERE, stop_cb);
291 } 293 }
292 294
293 void PipelineImpl::RendererWrapper::Seek(base::TimeDelta time) { 295 void PipelineImpl::RendererWrapper::Seek(StreamPosition position) {
294 DCHECK(media_task_runner_->BelongsToCurrentThread()); 296 DCHECK(media_task_runner_->BelongsToCurrentThread());
295 297
296 // Suppress seeking if we're not fully started. 298 // Suppress seeking if we're not fully started.
297 if (state_ != kPlaying) { 299 if (state_ != kPlaying) {
298 DCHECK(state_ == kStopping || state_ == kStopped) 300 DCHECK(state_ == kStopping || state_ == kStopped)
299 << "Receive seek in unexpected state: " << state_; 301 << "Receive seek in unexpected state: " << state_;
300 OnPipelineError(PIPELINE_ERROR_INVALID_STATE); 302 OnPipelineError(PIPELINE_ERROR_INVALID_STATE);
301 return; 303 return;
302 } 304 }
303 305
304 base::TimeDelta seek_timestamp = std::max(time, demuxer_->GetStartTime()); 306 position.time = std::max(position.time, demuxer_->GetStartTime());
305 307
306 SetState(kSeeking); 308 SetState(kSeeking);
307 renderer_ended_ = false; 309 renderer_ended_ = false;
308 text_renderer_ended_ = false; 310 text_renderer_ended_ = false;
309 311
310 // Queue asynchronous actions required to start. 312 // Queue asynchronous actions required to start.
311 DCHECK(!pending_callbacks_); 313 DCHECK(!pending_callbacks_);
312 SerialRunner::Queue bound_fns; 314 SerialRunner::Queue bound_fns;
313 315
314 // Abort any reads the renderer may be blocked on. 316 // Abort any reads the renderer may be blocked on.
(...skipping 10 matching lines...) Expand all
325 bound_fns.Push(base::Bind(&Renderer::Flush, 327 bound_fns.Push(base::Bind(&Renderer::Flush,
326 base::Unretained(shared_state_.renderer.get()))); 328 base::Unretained(shared_state_.renderer.get())));
327 329
328 if (text_renderer_) { 330 if (text_renderer_) {
329 bound_fns.Push(base::Bind(&TextRenderer::Flush, 331 bound_fns.Push(base::Bind(&TextRenderer::Flush,
330 base::Unretained(text_renderer_.get()))); 332 base::Unretained(text_renderer_.get())));
331 } 333 }
332 334
333 // Seek demuxer. 335 // Seek demuxer.
334 bound_fns.Push( 336 bound_fns.Push(
335 base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), seek_timestamp)); 337 base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), position.time));
336 338
337 // Run tasks. 339 // Run tasks.
338 pending_callbacks_ = SerialRunner::Run( 340 pending_callbacks_ = SerialRunner::Run(
339 bound_fns, 341 bound_fns,
340 base::Bind(&RendererWrapper::CompleteSeek, weak_this_, seek_timestamp)); 342 base::Bind(&RendererWrapper::CompleteSeek, weak_this_, position));
341 } 343 }
342 344
343 void PipelineImpl::RendererWrapper::Suspend() { 345 void PipelineImpl::RendererWrapper::Suspend() {
344 DCHECK(media_task_runner_->BelongsToCurrentThread()); 346 DCHECK(media_task_runner_->BelongsToCurrentThread());
345 347
346 // Suppress suspending if we're not playing. 348 // Suppress suspending if we're not playing.
347 if (state_ != kPlaying) { 349 if (state_ != kPlaying) {
348 DCHECK(state_ == kStopping || state_ == kStopped) 350 DCHECK(state_ == kStopping || state_ == kStopped)
349 << "Receive suspend in unexpected state: " << state_; 351 << "Receive suspend in unexpected state: " << state_;
350 OnPipelineError(PIPELINE_ERROR_INVALID_STATE); 352 OnPipelineError(PIPELINE_ERROR_INVALID_STATE);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 std::max(timestamp, demuxer_->GetStartTime()); 405 std::max(timestamp, demuxer_->GetStartTime());
404 406
405 // Queue the asynchronous actions required to start playback. 407 // Queue the asynchronous actions required to start playback.
406 SerialRunner::Queue fns; 408 SerialRunner::Queue fns;
407 409
408 fns.Push( 410 fns.Push(
409 base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), start_timestamp)); 411 base::Bind(&Demuxer::Seek, base::Unretained(demuxer_), start_timestamp));
410 412
411 fns.Push(base::Bind(&RendererWrapper::InitializeRenderer, weak_this_)); 413 fns.Push(base::Bind(&RendererWrapper::InitializeRenderer, weak_this_));
412 414
415 // XXX: Revisit.
413 pending_callbacks_ = SerialRunner::Run( 416 pending_callbacks_ = SerialRunner::Run(
414 fns, 417 fns, base::Bind(&RendererWrapper::CompleteSeek, weak_this_,
415 base::Bind(&RendererWrapper::CompleteSeek, weak_this_, start_timestamp)); 418 StreamPosition::Precise(timestamp)));
416 } 419 }
417 420
418 void PipelineImpl::RendererWrapper::SetPlaybackRate(double playback_rate) { 421 void PipelineImpl::RendererWrapper::SetPlaybackRate(double playback_rate) {
419 DCHECK(media_task_runner_->BelongsToCurrentThread()); 422 DCHECK(media_task_runner_->BelongsToCurrentThread());
420 423
421 playback_rate_ = playback_rate; 424 playback_rate_ = playback_rate;
422 if (state_ == kPlaying) 425 if (state_ == kPlaying)
423 shared_state_.renderer->SetPlaybackRate(playback_rate_); 426 shared_state_.renderer->SetPlaybackRate(playback_rate_);
424 } 427 }
425 428
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 DCHECK(shared_state_.renderer); 603 DCHECK(shared_state_.renderer);
601 604
602 base::TimeDelta currTime = (state_ == kPlaying) 605 base::TimeDelta currTime = (state_ == kPlaying)
603 ? shared_state_.renderer->GetMediaTime() 606 ? shared_state_.renderer->GetMediaTime()
604 : demuxer_->GetStartTime(); 607 : demuxer_->GetStartTime();
605 demuxer_->OnSelectedVideoTrackChanged(selectedTrackId, currTime); 608 demuxer_->OnSelectedVideoTrackChanged(selectedTrackId, currTime);
606 } 609 }
607 610
608 void PipelineImpl::RendererWrapper::OnStatisticsUpdate( 611 void PipelineImpl::RendererWrapper::OnStatisticsUpdate(
609 const PipelineStatistics& stats) { 612 const PipelineStatistics& stats) {
610 DVLOG(3) << __func__;
611 DCHECK(media_task_runner_->BelongsToCurrentThread()); 613 DCHECK(media_task_runner_->BelongsToCurrentThread());
612 614
613 base::AutoLock auto_lock(shared_state_lock_); 615 base::AutoLock auto_lock(shared_state_lock_);
614 shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded; 616 shared_state_.statistics.audio_bytes_decoded += stats.audio_bytes_decoded;
615 shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded; 617 shared_state_.statistics.video_bytes_decoded += stats.video_bytes_decoded;
616 shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded; 618 shared_state_.statistics.video_frames_decoded += stats.video_frames_decoded;
617 shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped; 619 shared_state_.statistics.video_frames_dropped += stats.video_frames_dropped;
618 shared_state_.statistics.audio_memory_usage += stats.audio_memory_usage; 620 shared_state_.statistics.audio_memory_usage += stats.audio_memory_usage;
619 shared_state_.statistics.video_memory_usage += stats.video_memory_usage; 621 shared_state_.statistics.video_memory_usage += stats.video_memory_usage;
620 } 622 }
621 623
624 void PipelineImpl::RendererWrapper::OnFirstVideoFrameTimestampKnown(
625 base::TimeDelta timestamp) {}
626
622 void PipelineImpl::RendererWrapper::OnBufferingStateChange( 627 void PipelineImpl::RendererWrapper::OnBufferingStateChange(
623 BufferingState state) { 628 BufferingState state) {
624 DCHECK(media_task_runner_->BelongsToCurrentThread()); 629 DCHECK(media_task_runner_->BelongsToCurrentThread());
625 DVLOG(2) << __func__ << "(" << state << ") "; 630 DVLOG(2) << __func__ << "(" << state << ") ";
626 631
627 main_task_runner_->PostTask( 632 main_task_runner_->PostTask(
628 FROM_HERE, 633 FROM_HERE,
629 base::Bind(&PipelineImpl::OnBufferingStateChange, weak_pipeline_, state)); 634 base::Bind(&PipelineImpl::OnBufferingStateChange, weak_pipeline_, state));
630 } 635 }
631 636
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 746
742 void PipelineImpl::RendererWrapper::SetState(State next_state) { 747 void PipelineImpl::RendererWrapper::SetState(State next_state) {
743 DCHECK(media_task_runner_->BelongsToCurrentThread()); 748 DCHECK(media_task_runner_->BelongsToCurrentThread());
744 DVLOG(1) << PipelineImpl::GetStateString(state_) << " -> " 749 DVLOG(1) << PipelineImpl::GetStateString(state_) << " -> "
745 << PipelineImpl::GetStateString(next_state); 750 << PipelineImpl::GetStateString(next_state);
746 751
747 state_ = next_state; 752 state_ = next_state;
748 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); 753 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state));
749 } 754 }
750 755
751 void PipelineImpl::RendererWrapper::CompleteSeek(base::TimeDelta seek_time, 756 void PipelineImpl::RendererWrapper::CompleteSeek(StreamPosition position,
752 PipelineStatus status) { 757 PipelineStatus status) {
753 DCHECK(media_task_runner_->BelongsToCurrentThread()); 758 DCHECK(media_task_runner_->BelongsToCurrentThread());
754 DCHECK(state_ == kStarting || state_ == kSeeking || state_ == kResuming); 759 DCHECK(state_ == kStarting || state_ == kSeeking || state_ == kResuming);
755 760
756 DCHECK(pending_callbacks_); 761 DCHECK(pending_callbacks_);
757 pending_callbacks_.reset(); 762 pending_callbacks_.reset();
758 763
759 if (status != PIPELINE_OK) { 764 if (status != PIPELINE_OK) {
760 OnPipelineError(status); 765 OnPipelineError(status);
761 return; 766 return;
762 } 767 }
763 768
764 shared_state_.renderer->StartPlayingFrom( 769 position.time = std::max(position.time, demuxer_->GetStartTime());
765 std::max(seek_time, demuxer_->GetStartTime())); 770 shared_state_.renderer->StartPlayingFrom(position);
771
766 { 772 {
767 base::AutoLock auto_lock(shared_state_lock_); 773 base::AutoLock auto_lock(shared_state_lock_);
768 shared_state_.suspend_timestamp = kNoTimestamp; 774 shared_state_.suspend_timestamp = kNoTimestamp;
769 } 775 }
770 776
771 if (text_renderer_) 777 if (text_renderer_)
772 text_renderer_->StartPlaying(); 778 text_renderer_->StartPlaying();
773 779
774 shared_state_.renderer->SetPlaybackRate(playback_rate_); 780 shared_state_.renderer->SetPlaybackRate(playback_rate_);
775 shared_state_.renderer->SetVolume(volume_); 781 shared_state_.renderer->SetVolume(volume_);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 // Reset all callbacks and client handle. 971 // Reset all callbacks and client handle.
966 seek_cb_.Reset(); 972 seek_cb_.Reset();
967 suspend_cb_.Reset(); 973 suspend_cb_.Reset();
968 client_ = nullptr; 974 client_ = nullptr;
969 975
970 // Invalidate self weak pointers effectively canceling all pending 976 // Invalidate self weak pointers effectively canceling all pending
971 // notifications in the message queue. 977 // notifications in the message queue.
972 weak_factory_.InvalidateWeakPtrs(); 978 weak_factory_.InvalidateWeakPtrs();
973 } 979 }
974 980
975 void PipelineImpl::Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb) { 981 void PipelineImpl::Seek(StreamPosition position,
976 DVLOG(2) << __func__ << " to " << time.InMicroseconds(); 982 const PipelineStatusCB& seek_cb) {
983 DVLOG(2) << __func__ << "(" << ToString(position) << ")";
977 DCHECK(thread_checker_.CalledOnValidThread()); 984 DCHECK(thread_checker_.CalledOnValidThread());
978 DCHECK(!seek_cb.is_null()); 985 DCHECK(!seek_cb.is_null());
979 986
980 if (!IsRunning()) { 987 if (!IsRunning()) {
981 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek()."; 988 DLOG(ERROR) << "Media pipeline isn't running. Ignoring Seek().";
982 return; 989 return;
983 } 990 }
984 991
985 DCHECK(seek_cb_.is_null()); 992 DCHECK(seek_cb_.is_null());
986 seek_cb_ = seek_cb; 993 seek_cb_ = seek_cb;
987 last_media_time_ = base::TimeDelta(); 994 last_media_time_ = base::TimeDelta();
988 media_task_runner_->PostTask( 995 media_task_runner_->PostTask(
989 FROM_HERE, base::Bind(&RendererWrapper::Seek, 996 FROM_HERE,
990 base::Unretained(renderer_wrapper_.get()), time)); 997 base::Bind(&RendererWrapper::Seek,
998 base::Unretained(renderer_wrapper_.get()), position));
991 } 999 }
992 1000
993 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) { 1001 void PipelineImpl::Suspend(const PipelineStatusCB& suspend_cb) {
994 DVLOG(2) << __func__; 1002 DVLOG(2) << __func__;
995 DCHECK(!suspend_cb.is_null()); 1003 DCHECK(!suspend_cb.is_null());
996 1004
997 DCHECK(IsRunning()); 1005 DCHECK(IsRunning());
998 DCHECK(suspend_cb_.is_null()); 1006 DCHECK(suspend_cb_.is_null());
999 suspend_cb_ = suspend_cb; 1007 suspend_cb_ = suspend_cb;
1000 1008
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 DCHECK(thread_checker_.CalledOnValidThread()); 1077 DCHECK(thread_checker_.CalledOnValidThread());
1070 1078
1071 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime(); 1079 base::TimeDelta media_time = renderer_wrapper_->GetMediaTime();
1072 1080
1073 // Clamp current media time to the last reported value, this prevents higher 1081 // Clamp current media time to the last reported value, this prevents higher
1074 // level clients from seeing time go backwards based on inaccurate or spurious 1082 // level clients from seeing time go backwards based on inaccurate or spurious
1075 // delay values reported to the AudioClock. 1083 // delay values reported to the AudioClock.
1076 // 1084 //
1077 // It is expected that such events are transient and will be recovered as 1085 // It is expected that such events are transient and will be recovered as
1078 // rendering continues over time. 1086 // rendering continues over time.
1087
1088 // XXX: Revisit. Do we even need this logic?
1089 /*
1079 if (media_time < last_media_time_) { 1090 if (media_time < last_media_time_) {
1080 DVLOG(2) << __func__ << ": actual=" << media_time 1091 DVLOG(2) << __func__ << ": actual=" << media_time
1081 << " clamped=" << last_media_time_; 1092 << " clamped=" << last_media_time_;
1082 return last_media_time_; 1093 return last_media_time_;
1083 } 1094 }
1095 */
1084 1096
1085 DVLOG(3) << __FUNCTION__ << ": " << media_time.InMilliseconds() << " ms"; 1097 DVLOG(3) << __FUNCTION__ << ": " << media_time.InMilliseconds() << " ms";
1086 last_media_time_ = media_time; 1098 last_media_time_ = media_time;
1087 return last_media_time_; 1099 return last_media_time_;
1088 } 1100 }
1089 1101
1090 Ranges<base::TimeDelta> PipelineImpl::GetBufferedTimeRanges() const { 1102 Ranges<base::TimeDelta> PipelineImpl::GetBufferedTimeRanges() const {
1091 DCHECK(thread_checker_.CalledOnValidThread()); 1103 DCHECK(thread_checker_.CalledOnValidThread());
1092 return renderer_wrapper_->GetBufferedTimeRanges(); 1104 return renderer_wrapper_->GetBufferedTimeRanges();
1093 } 1105 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 void PipelineImpl::OnSuspendDone() { 1265 void PipelineImpl::OnSuspendDone() {
1254 DVLOG(3) << __func__; 1266 DVLOG(3) << __func__;
1255 DCHECK(thread_checker_.CalledOnValidThread()); 1267 DCHECK(thread_checker_.CalledOnValidThread());
1256 DCHECK(IsRunning()); 1268 DCHECK(IsRunning());
1257 1269
1258 DCHECK(!suspend_cb_.is_null()); 1270 DCHECK(!suspend_cb_.is_null());
1259 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK); 1271 base::ResetAndReturn(&suspend_cb_).Run(PIPELINE_OK);
1260 } 1272 }
1261 1273
1262 } // namespace media 1274 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/base/renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698