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

Side by Side Diff: media/base/android/media_source_player.cc

Issue 376013003: Rename media::Clock to media::TimeDeltaInterpolator and update API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/android/media_source_player.h" 5 #include "media/base/android/media_source_player.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
(...skipping 20 matching lines...) Expand all
31 scoped_ptr<DemuxerAndroid> demuxer, 31 scoped_ptr<DemuxerAndroid> demuxer,
32 const GURL& frame_url) 32 const GURL& frame_url)
33 : MediaPlayerAndroid(player_id, 33 : MediaPlayerAndroid(player_id,
34 manager, 34 manager,
35 request_media_resources_cb, 35 request_media_resources_cb,
36 release_media_resources_cb, 36 release_media_resources_cb,
37 frame_url), 37 frame_url),
38 demuxer_(demuxer.Pass()), 38 demuxer_(demuxer.Pass()),
39 pending_event_(NO_EVENT_PENDING), 39 pending_event_(NO_EVENT_PENDING),
40 playing_(false), 40 playing_(false),
41 clock_(&default_tick_clock_), 41 interpolator_(&default_tick_clock_),
42 doing_browser_seek_(false), 42 doing_browser_seek_(false),
43 pending_seek_(false), 43 pending_seek_(false),
44 drm_bridge_(NULL), 44 drm_bridge_(NULL),
45 cdm_registration_id_(0), 45 cdm_registration_id_(0),
46 is_waiting_for_key_(false), 46 is_waiting_for_key_(false),
47 is_waiting_for_audio_decoder_(false), 47 is_waiting_for_audio_decoder_(false),
48 is_waiting_for_video_decoder_(false), 48 is_waiting_for_video_decoder_(false),
49 weak_factory_(this) { 49 weak_factory_(this) {
50 audio_decoder_job_.reset(new AudioDecoderJob( 50 audio_decoder_job_.reset(new AudioDecoderJob(
51 base::Bind(&DemuxerAndroid::RequestDemuxerData, 51 base::Bind(&DemuxerAndroid::RequestDemuxerData,
52 base::Unretained(demuxer_.get()), 52 base::Unretained(demuxer_.get()),
53 DemuxerStream::AUDIO), 53 DemuxerStream::AUDIO),
54 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, 54 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
55 weak_factory_.GetWeakPtr()))); 55 weak_factory_.GetWeakPtr())));
56 video_decoder_job_.reset(new VideoDecoderJob( 56 video_decoder_job_.reset(new VideoDecoderJob(
57 base::Bind(&DemuxerAndroid::RequestDemuxerData, 57 base::Bind(&DemuxerAndroid::RequestDemuxerData,
58 base::Unretained(demuxer_.get()), 58 base::Unretained(demuxer_.get()),
59 DemuxerStream::VIDEO), 59 DemuxerStream::VIDEO),
60 base::Bind(request_media_resources_cb_, player_id), 60 base::Bind(request_media_resources_cb_, player_id),
61 base::Bind(release_media_resources_cb_, player_id), 61 base::Bind(release_media_resources_cb_, player_id),
62 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, 62 base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged,
63 weak_factory_.GetWeakPtr()))); 63 weak_factory_.GetWeakPtr())));
64 demuxer_->Initialize(this); 64 demuxer_->Initialize(this);
65 clock_.SetMaxTime(base::TimeDelta()); 65 interpolator_.SetUpperBound(base::TimeDelta());
66 weak_this_ = weak_factory_.GetWeakPtr(); 66 weak_this_ = weak_factory_.GetWeakPtr();
67 } 67 }
68 68
69 MediaSourcePlayer::~MediaSourcePlayer() { 69 MediaSourcePlayer::~MediaSourcePlayer() {
70 Release(); 70 Release();
71 DCHECK_EQ(!drm_bridge_, !cdm_registration_id_); 71 DCHECK_EQ(!drm_bridge_, !cdm_registration_id_);
72 if (drm_bridge_) { 72 if (drm_bridge_) {
73 drm_bridge_->UnregisterPlayer(cdm_registration_id_); 73 drm_bridge_->UnregisterPlayer(cdm_registration_id_);
74 cdm_registration_id_ = 0; 74 cdm_registration_id_ = 0;
75 } 75 }
76 } 76 }
77 77
78 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 78 void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) {
79 DVLOG(1) << __FUNCTION__; 79 DVLOG(1) << __FUNCTION__;
80 if (!video_decoder_job_->SetVideoSurface(surface.Pass())) 80 if (!video_decoder_job_->SetVideoSurface(surface.Pass()))
81 return; 81 return;
82 // Retry video decoder creation. 82 // Retry video decoder creation.
83 RetryDecoderCreation(false, true); 83 RetryDecoderCreation(false, true);
84 } 84 }
85 85
86 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding( 86 void MediaSourcePlayer::ScheduleSeekEventAndStopDecoding(
87 base::TimeDelta seek_time) { 87 base::TimeDelta seek_time) {
88 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")"; 88 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ")";
89 DCHECK(!IsEventPending(SEEK_EVENT_PENDING)); 89 DCHECK(!IsEventPending(SEEK_EVENT_PENDING));
90 90
91 pending_seek_ = false; 91 pending_seek_ = false;
92 92
93 clock_.SetTime(seek_time, seek_time); 93 interpolator_.SetInterpolationRange(seek_time, seek_time);
94 94
95 if (audio_decoder_job_->is_decoding()) 95 if (audio_decoder_job_->is_decoding())
96 audio_decoder_job_->StopDecode(); 96 audio_decoder_job_->StopDecode();
97 if (video_decoder_job_->is_decoding()) 97 if (video_decoder_job_->is_decoding())
98 video_decoder_job_->StopDecode(); 98 video_decoder_job_->StopDecode();
99 99
100 SetPendingEvent(SEEK_EVENT_PENDING); 100 SetPendingEvent(SEEK_EVENT_PENDING);
101 ProcessPendingEvents(); 101 ProcessPendingEvents();
102 } 102 }
103 103
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 pending_seek_ = true; 166 pending_seek_ = true;
167 pending_seek_time_ = timestamp; 167 pending_seek_time_ = timestamp;
168 return; 168 return;
169 } 169 }
170 170
171 doing_browser_seek_ = false; 171 doing_browser_seek_ = false;
172 ScheduleSeekEventAndStopDecoding(timestamp); 172 ScheduleSeekEventAndStopDecoding(timestamp);
173 } 173 }
174 174
175 base::TimeDelta MediaSourcePlayer::GetCurrentTime() { 175 base::TimeDelta MediaSourcePlayer::GetCurrentTime() {
176 return std::min(clock_.Elapsed(), duration_); 176 return std::min(interpolator_.GetInterpolatedTime(), duration_);
177 } 177 }
178 178
179 base::TimeDelta MediaSourcePlayer::GetDuration() { 179 base::TimeDelta MediaSourcePlayer::GetDuration() {
180 return duration_; 180 return duration_;
181 } 181 }
182 182
183 void MediaSourcePlayer::Release() { 183 void MediaSourcePlayer::Release() {
184 DVLOG(1) << __FUNCTION__; 184 DVLOG(1) << __FUNCTION__;
185 185
186 is_surface_in_use_ = false; 186 is_surface_in_use_ = false;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 // I-frame later than the requested one due to data removal or GC. Update 321 // I-frame later than the requested one due to data removal or GC. Update
322 // player clock to the actual seek target. 322 // player clock to the actual seek target.
323 if (doing_browser_seek_) { 323 if (doing_browser_seek_) {
324 DCHECK(actual_browser_seek_time != kNoTimestamp()); 324 DCHECK(actual_browser_seek_time != kNoTimestamp());
325 base::TimeDelta seek_time = actual_browser_seek_time; 325 base::TimeDelta seek_time = actual_browser_seek_time;
326 // A browser seek must not jump into the past. Ideally, it seeks to the 326 // A browser seek must not jump into the past. Ideally, it seeks to the
327 // requested time, but it might jump into the future. 327 // requested time, but it might jump into the future.
328 DCHECK(seek_time >= GetCurrentTime()); 328 DCHECK(seek_time >= GetCurrentTime());
329 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " 329 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
330 << seek_time.InSecondsF(); 330 << seek_time.InSecondsF();
331 clock_.SetTime(seek_time, seek_time); 331 interpolator_.SetInterpolationRange(seek_time, seek_time);
332 audio_decoder_job_->SetBaseTimestamp(seek_time); 332 audio_decoder_job_->SetBaseTimestamp(seek_time);
333 } else { 333 } else {
334 DCHECK(actual_browser_seek_time == kNoTimestamp()); 334 DCHECK(actual_browser_seek_time == kNoTimestamp());
335 } 335 }
336 336
337 base::TimeDelta current_time = GetCurrentTime(); 337 base::TimeDelta current_time = GetCurrentTime();
338 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| 338 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
339 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| 339 // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
340 // is calculated from decoder output, while preroll relies on the access 340 // is calculated from decoder output, while preroll relies on the access
341 // unit's timestamp. There are some differences between the two. 341 // unit's timestamp. There are some differences between the two.
342 preroll_timestamp_ = current_time; 342 preroll_timestamp_ = current_time;
343 if (HasAudio()) 343 if (HasAudio())
344 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 344 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
345 if (HasVideo()) 345 if (HasVideo())
346 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 346 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
347 347
348 if (!doing_browser_seek_) 348 if (!doing_browser_seek_)
349 manager()->OnSeekComplete(player_id(), current_time); 349 manager()->OnSeekComplete(player_id(), current_time);
350 350
351 ProcessPendingEvents(); 351 ProcessPendingEvents();
352 } 352 }
353 353
354 void MediaSourcePlayer::UpdateTimestamps( 354 void MediaSourcePlayer::UpdateTimestamps(
355 base::TimeDelta current_presentation_timestamp, 355 base::TimeDelta current_presentation_timestamp,
356 base::TimeDelta max_presentation_timestamp) { 356 base::TimeDelta max_presentation_timestamp) {
357 clock_.SetTime(current_presentation_timestamp, max_presentation_timestamp); 357 interpolator_.SetInterpolationRange(current_presentation_timestamp,
358 max_presentation_timestamp);
358 manager()->OnTimeUpdate(player_id(), GetCurrentTime()); 359 manager()->OnTimeUpdate(player_id(), GetCurrentTime());
359 } 360 }
360 361
361 void MediaSourcePlayer::ProcessPendingEvents() { 362 void MediaSourcePlayer::ProcessPendingEvents() {
362 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_; 363 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
363 // Wait for all the decoding jobs to finish before processing pending tasks. 364 // Wait for all the decoding jobs to finish before processing pending tasks.
364 if (video_decoder_job_->is_decoding()) { 365 if (video_decoder_job_->is_decoding()) {
365 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding."; 366 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
366 return; 367 return;
367 } 368 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 if (pending_event_ != NO_EVENT_PENDING) { 483 if (pending_event_ != NO_EVENT_PENDING) {
483 ProcessPendingEvents(); 484 ProcessPendingEvents();
484 return; 485 return;
485 } 486 }
486 487
487 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) 488 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
488 return; 489 return;
489 490
490 if (!playing_) { 491 if (!playing_) {
491 if (is_clock_manager) 492 if (is_clock_manager)
492 clock_.Pause(); 493 interpolator_.StopInterpolating();
493 return; 494 return;
494 } 495 }
495 496
496 if (status == MEDIA_CODEC_NO_KEY) { 497 if (status == MEDIA_CODEC_NO_KEY) {
497 is_waiting_for_key_ = true; 498 is_waiting_for_key_ = true;
498 return; 499 return;
499 } 500 }
500 501
501 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is 502 // If the status is MEDIA_CODEC_STOPPED, stop decoding new data. The player is
502 // in the middle of a seek or stop event and needs to wait for the IPCs to 503 // in the middle of a seek or stop event and needs to wait for the IPCs to
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 is_waiting_for_video_decoder_ = true; 565 is_waiting_for_video_decoder_ = true;
565 if (!IsEventPending(DECODER_CREATION_EVENT_PENDING)) 566 if (!IsEventPending(DECODER_CREATION_EVENT_PENDING))
566 SetPendingEvent(DECODER_CREATION_EVENT_PENDING); 567 SetPendingEvent(DECODER_CREATION_EVENT_PENDING);
567 } 568 }
568 569
569 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { 570 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
570 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")"; 571 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
571 572
572 if (AudioFinished() && VideoFinished()) { 573 if (AudioFinished() && VideoFinished()) {
573 playing_ = false; 574 playing_ = false;
574 clock_.Pause(); 575 interpolator_.StopInterpolating();
575 start_time_ticks_ = base::TimeTicks(); 576 start_time_ticks_ = base::TimeTicks();
576 manager()->OnPlaybackComplete(player_id()); 577 manager()->OnPlaybackComplete(player_id());
577 } 578 }
578 } 579 }
579 580
580 void MediaSourcePlayer::ClearDecodingData() { 581 void MediaSourcePlayer::ClearDecodingData() {
581 DVLOG(1) << __FUNCTION__; 582 DVLOG(1) << __FUNCTION__;
582 audio_decoder_job_->Flush(); 583 audio_decoder_job_->Flush();
583 video_decoder_job_->Flush(); 584 video_decoder_job_->Flush();
584 start_time_ticks_ = base::TimeTicks(); 585 start_time_ticks_ = base::TimeTicks();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 if (pending_event_ != NO_EVENT_PENDING) { 664 if (pending_event_ != NO_EVENT_PENDING) {
664 ProcessPendingEvents(); 665 ProcessPendingEvents();
665 return; 666 return;
666 } 667 }
667 668
668 if (!playing_) 669 if (!playing_)
669 return; 670 return;
670 671
671 start_time_ticks_ = base::TimeTicks::Now(); 672 start_time_ticks_ = base::TimeTicks::Now();
672 start_presentation_timestamp_ = GetCurrentTime(); 673 start_presentation_timestamp_ = GetCurrentTime();
673 if (!clock_.IsPlaying()) 674 if (!interpolator_.interpolating())
acolwell GONE FROM CHROMIUM 2014/07/09 20:17:30 :)
674 clock_.Play(); 675 interpolator_.StartInterpolating();
675 676
676 if (!AudioFinished()) 677 if (!AudioFinished())
677 DecodeMoreAudio(); 678 DecodeMoreAudio();
678 679
679 if (!VideoFinished()) 680 if (!VideoFinished())
680 DecodeMoreVideo(); 681 DecodeMoreVideo();
681 } 682 }
682 683
683 void MediaSourcePlayer::OnDemuxerConfigsChanged() { 684 void MediaSourcePlayer::OnDemuxerConfigsChanged() {
684 manager()->OnMediaMetadataChanged( 685 manager()->OnMediaMetadataChanged(
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // release MediaDrm when the video is paused, or when the device goes to 750 // release MediaDrm when the video is paused, or when the device goes to
750 // sleep (see http://crbug.com/272421). 751 // sleep (see http://crbug.com/272421).
751 NOTREACHED() << "CDM detachment not supported."; 752 NOTREACHED() << "CDM detachment not supported.";
752 DCHECK(drm_bridge_); 753 DCHECK(drm_bridge_);
753 audio_decoder_job_->SetDrmBridge(NULL); 754 audio_decoder_job_->SetDrmBridge(NULL);
754 video_decoder_job_->SetDrmBridge(NULL); 755 video_decoder_job_->SetDrmBridge(NULL);
755 drm_bridge_ = NULL; 756 drm_bridge_ = NULL;
756 } 757 }
757 758
758 } // namespace media 759 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698