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

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

Issue 23545029: EME: Handle NO_KEY and resume playback after key is added. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase only Created 7 years, 3 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
« no previous file with comments | « media/base/android/media_source_player.h ('k') | no next file » | 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) 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>
8
7 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
9 #include "base/barrier_closure.h" 11 #include "base/barrier_closure.h"
10 #include "base/basictypes.h" 12 #include "base/basictypes.h"
11 #include "base/bind.h" 13 #include "base/bind.h"
12 #include "base/logging.h" 14 #include "base/logging.h"
13 #include "media/base/android/audio_decoder_job.h" 15 #include "media/base/android/audio_decoder_job.h"
14 #include "media/base/android/media_drm_bridge.h" 16 #include "media/base/android/media_drm_bridge.h"
15 #include "media/base/android/media_player_manager.h" 17 #include "media/base/android/media_player_manager.h"
16 #include "media/base/android/video_decoder_job.h" 18 #include "media/base/android/video_decoder_job.h"
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 pending_event_ = NO_EVENT_PENDING; 180 pending_event_ = NO_EVENT_PENDING;
179 surface_ = gfx::ScopedJavaSurface(); 181 surface_ = gfx::ScopedJavaSurface();
180 ReleaseMediaResourcesFromManager(); 182 ReleaseMediaResourcesFromManager();
181 } 183 }
182 184
183 void MediaSourcePlayer::SetVolume(double volume) { 185 void MediaSourcePlayer::SetVolume(double volume) {
184 volume_ = volume; 186 volume_ = volume;
185 SetVolumeInternal(); 187 SetVolumeInternal();
186 } 188 }
187 189
190 void MediaSourcePlayer::OnKeyAdded() {
191 DVLOG(1) << __FUNCTION__;
192 if (playing_)
193 StartInternal();
194 }
195
188 bool MediaSourcePlayer::CanPause() { 196 bool MediaSourcePlayer::CanPause() {
189 return Seekable(); 197 return Seekable();
190 } 198 }
191 199
192 bool MediaSourcePlayer::CanSeekForward() { 200 bool MediaSourcePlayer::CanSeekForward() {
193 return Seekable(); 201 return Seekable();
194 } 202 }
195 203
196 bool MediaSourcePlayer::CanSeekBackward() { 204 bool MediaSourcePlayer::CanSeekBackward() {
197 return Seekable(); 205 return Seekable();
198 } 206 }
199 207
200 bool MediaSourcePlayer::IsPlayerReady() { 208 bool MediaSourcePlayer::IsPlayerReady() {
201 return audio_decoder_job_ || video_decoder_job_; 209 return audio_decoder_job_ || video_decoder_job_;
202 } 210 }
203 211
204 void MediaSourcePlayer::StartInternal() { 212 void MediaSourcePlayer::StartInternal() {
205 DVLOG(1) << __FUNCTION__; 213 DVLOG(1) << __FUNCTION__;
206 // If there are pending events, wait for them finish. 214 // If there are pending events, wait for them finish.
207 if (pending_event_ != NO_EVENT_PENDING) 215 if (pending_event_ != NO_EVENT_PENDING)
208 return; 216 return;
209 217
210 // Create decoder jobs if they are not created 218 // Create decoder jobs if they are not created
211 ConfigureAudioDecoderJob(); 219 ConfigureAudioDecoderJob();
212 ConfigureVideoDecoderJob(); 220 ConfigureVideoDecoderJob();
213 221
214
215 // If one of the decoder job is not ready, do nothing. 222 // If one of the decoder job is not ready, do nothing.
216 if ((HasAudio() && !audio_decoder_job_) || 223 if ((HasAudio() && !audio_decoder_job_) ||
217 (HasVideo() && !video_decoder_job_)) { 224 (HasVideo() && !video_decoder_job_)) {
218 return; 225 return;
219 } 226 }
220 227
221 audio_finished_ = false; 228 audio_finished_ = false;
222 video_finished_ = false; 229 video_finished_ = false;
223 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 230 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
224 ProcessPendingEvents(); 231 ProcessPendingEvents();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); 346 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_));
340 clock_.SetMaxTime(audio_timestamp_helper_->GetTimestamp()); 347 clock_.SetMaxTime(audio_timestamp_helper_->GetTimestamp());
341 } else { 348 } else {
342 clock_.SetMaxTime(presentation_timestamp); 349 clock_.SetMaxTime(presentation_timestamp);
343 } 350 }
344 351
345 OnTimeUpdated(); 352 OnTimeUpdated();
346 } 353 }
347 354
348 void MediaSourcePlayer::ProcessPendingEvents() { 355 void MediaSourcePlayer::ProcessPendingEvents() {
349 DVLOG(1) << __FUNCTION__ << " : 0x" 356 DVLOG(1) << __FUNCTION__ << " : 0x" << std::hex << pending_event_;
350 << std::hex << pending_event_;
351 // Wait for all the decoding jobs to finish before processing pending tasks. 357 // Wait for all the decoding jobs to finish before processing pending tasks.
352 if ((audio_decoder_job_ && audio_decoder_job_->is_decoding()) || 358 if (video_decoder_job_ && video_decoder_job_->is_decoding()) {
353 (video_decoder_job_ && video_decoder_job_->is_decoding())) { 359 DVLOG(1) << __FUNCTION__ << " : A video job is still decoding.";
354 DVLOG(1) << __FUNCTION__ << " : A job is still decoding.";
355 return; 360 return;
356 } 361 }
357 362
363 if (audio_decoder_job_ && audio_decoder_job_->is_decoding()) {
364 DVLOG(1) << __FUNCTION__ << " : An audio job is still decoding.";
365 return;
366 }
367
358 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) { 368 if (IsEventPending(PREFETCH_DONE_EVENT_PENDING)) {
359 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending."; 369 DVLOG(1) << __FUNCTION__ << " : PREFETCH_DONE still pending.";
360 return; 370 return;
361 } 371 }
362 372
363 if (IsEventPending(SEEK_EVENT_PENDING)) { 373 if (IsEventPending(SEEK_EVENT_PENDING)) {
364 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT."; 374 DVLOG(1) << __FUNCTION__ << " : Handling SEEK_EVENT.";
365 ClearDecodingData(); 375 ClearDecodingData();
366 manager()->OnMediaSeekRequest( 376 manager()->OnMediaSeekRequest(
367 player_id(), GetCurrentTime(), ++seek_request_id_); 377 player_id(), GetCurrentTime(), ++seek_request_id_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 415
406 // Now that all pending events have been handled, resume decoding if we are 416 // Now that all pending events have been handled, resume decoding if we are
407 // still playing. 417 // still playing.
408 if (playing_) 418 if (playing_)
409 StartInternal(); 419 StartInternal();
410 } 420 }
411 421
412 void MediaSourcePlayer::MediaDecoderCallback( 422 void MediaSourcePlayer::MediaDecoderCallback(
413 bool is_audio, MediaCodecStatus status, 423 bool is_audio, MediaCodecStatus status,
414 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { 424 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) {
415 DVLOG(1) << __FUNCTION__; 425 DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status;
416 if (is_audio) 426 if (is_audio)
417 decoder_starvation_callback_.Cancel(); 427 decoder_starvation_callback_.Cancel();
418 428
419 if (status == MEDIA_CODEC_ERROR) { 429 if (status == MEDIA_CODEC_ERROR) {
420 Release(); 430 Release();
421 OnMediaError(MEDIA_ERROR_DECODE); 431 OnMediaError(MEDIA_ERROR_DECODE);
422 return; 432 return;
423 } 433 }
424 434
425 if (pending_event_ != NO_EVENT_PENDING) { 435 if (pending_event_ != NO_EVENT_PENDING) {
426 ProcessPendingEvents(); 436 ProcessPendingEvents();
427 return; 437 return;
428 } 438 }
429 439
430 if (status == MEDIA_CODEC_OK && (is_audio || !HasAudio())) { 440 if (status == MEDIA_CODEC_OK && (is_audio || !HasAudio())) {
431 UpdateTimestamps(presentation_timestamp, audio_output_bytes); 441 UpdateTimestamps(presentation_timestamp, audio_output_bytes);
432 } 442 }
433 443
434 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) { 444 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
435 PlaybackCompleted(is_audio); 445 PlaybackCompleted(is_audio);
436 return; 446 return;
437 } 447 }
438 448
439 if (!playing_) { 449 if (!playing_) {
440 if (is_audio || !HasAudio()) 450 if (is_audio || !HasAudio())
441 clock_.Pause(); 451 clock_.Pause();
442 return; 452 return;
443 } 453 }
444 454
455 if (status == MEDIA_CODEC_NO_KEY)
456 return;
457
445 base::TimeDelta current_timestamp = GetCurrentTime(); 458 base::TimeDelta current_timestamp = GetCurrentTime();
446 if (is_audio) { 459 if (is_audio) {
447 if (status == MEDIA_CODEC_OK) { 460 if (status == MEDIA_CODEC_OK) {
448 base::TimeDelta timeout = 461 base::TimeDelta timeout =
449 audio_timestamp_helper_->GetTimestamp() - current_timestamp; 462 audio_timestamp_helper_->GetTimestamp() - current_timestamp;
450 StartStarvationCallback(timeout); 463 StartStarvationCallback(timeout);
451 } 464 }
452 DecodeMoreAudio(); 465 DecodeMoreAudio();
453 return; 466 return;
454 } 467 }
455 468
456 if (!HasAudio() && status == MEDIA_CODEC_OK) { 469 if (!HasAudio() && status == MEDIA_CODEC_OK) {
457 DCHECK(current_timestamp <= presentation_timestamp); 470 DCHECK(current_timestamp <= presentation_timestamp);
458 // For video only streams, fps can be estimated from the difference 471 // For video only streams, fps can be estimated from the difference
459 // between the previous and current presentation timestamps. The 472 // between the previous and current presentation timestamps. The
460 // previous presentation timestamp is equal to current_timestamp. 473 // previous presentation timestamp is equal to current_timestamp.
461 // TODO(qinmin): determine whether 2 is a good coefficient for estimating 474 // TODO(qinmin): determine whether 2 is a good coefficient for estimating
462 // video frame timeout. 475 // video frame timeout.
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 695
683 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 696 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
684 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 697 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
685 DCHECK_NE(event, NO_EVENT_PENDING); 698 DCHECK_NE(event, NO_EVENT_PENDING);
686 DCHECK(IsEventPending(event)); 699 DCHECK(IsEventPending(event));
687 700
688 pending_event_ &= ~event; 701 pending_event_ &= ~event;
689 } 702 }
690 703
691 } // namespace media 704 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698