media_source_player.cc revision 3551c9c881056c480085172ff9840cab31610854
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 3// found in the LICENSE file. 4 5#include "media/base/android/media_source_player.h" 6 7#include "base/android/jni_android.h" 8#include "base/android/jni_string.h" 9#include "base/basictypes.h" 10#include "base/bind.h" 11#include "base/logging.h" 12#include "media/base/android/audio_decoder_job.h" 13#include "media/base/android/media_drm_bridge.h" 14#include "media/base/android/media_player_manager.h" 15#include "media/base/android/video_decoder_job.h" 16#include "media/base/audio_timestamp_helper.h" 17 18namespace { 19 20// Use 16bit PCM for audio output. Keep this value in sync with the output 21// format we passed to AudioTrack in MediaCodecBridge. 22const int kBytesPerAudioOutputSample = 2; 23} 24 25namespace media { 26 27MediaSourcePlayer::MediaSourcePlayer( 28 int player_id, 29 MediaPlayerManager* manager) 30 : MediaPlayerAndroid(player_id, manager), 31 pending_event_(NO_EVENT_PENDING), 32 seek_request_id_(0), 33 width_(0), 34 height_(0), 35 audio_codec_(kUnknownAudioCodec), 36 video_codec_(kUnknownVideoCodec), 37 num_channels_(0), 38 sampling_rate_(0), 39 audio_finished_(true), 40 video_finished_(true), 41 playing_(false), 42 is_audio_encrypted_(false), 43 is_video_encrypted_(false), 44 volume_(-1.0), 45 clock_(&default_tick_clock_), 46 reconfig_audio_decoder_(false), 47 reconfig_video_decoder_(false), 48 audio_access_unit_index_(0), 49 video_access_unit_index_(0), 50 waiting_for_audio_data_(false), 51 waiting_for_video_data_(false), 52 sync_decoder_jobs_(true), 53 weak_this_(this), 54 drm_bridge_(NULL) { 55} 56 57MediaSourcePlayer::~MediaSourcePlayer() { 58 Release(); 59} 60 61void MediaSourcePlayer::SetVideoSurface(gfx::ScopedJavaSurface surface) { 62 // Ignore non-empty surface that is unprotected if |is_video_encrypted_| is 63 // true. 64 if (is_video_encrypted_ && !surface.IsEmpty() && !surface.is_protected()) 65 return; 66 67 surface_ = surface.Pass(); 68 pending_event_ |= SURFACE_CHANGE_EVENT_PENDING; 69 if (pending_event_ & SEEK_EVENT_PENDING) { 70 // Waiting for the seek to finish. 71 return; 72 } 73 // Setting a new surface will require a new MediaCodec to be created. 74 // Request a seek so that the new decoder will decode an I-frame first. 75 // Or otherwise, the new MediaCodec might crash. See b/8950387. 76 pending_event_ |= SEEK_EVENT_PENDING; 77 ProcessPendingEvents(); 78} 79 80bool MediaSourcePlayer::Seekable() { 81 // If the duration TimeDelta, converted to milliseconds from microseconds, 82 // is >= 2^31, then the media is assumed to be unbounded and unseekable. 83 // 2^31 is the bound due to java player using 32-bit integer for time 84 // values at millisecond resolution. 85 return duration_ < 86 base::TimeDelta::FromMilliseconds(std::numeric_limits<int32>::max()); 87} 88 89void MediaSourcePlayer::Start() { 90 playing_ = true; 91 92 if (is_video_encrypted_) 93 manager()->OnProtectedSurfaceRequested(player_id()); 94 95 StartInternal(); 96} 97 98void MediaSourcePlayer::Pause() { 99 // Since decoder jobs have their own thread, decoding is not fully paused 100 // until all the decoder jobs call MediaDecoderCallback(). It is possible 101 // that Start() is called while the player is waiting for 102 // MediaDecoderCallback(). In that case, decoding will continue when 103 // MediaDecoderCallback() is called. 104 playing_ = false; 105 start_time_ticks_ = base::TimeTicks(); 106} 107 108bool MediaSourcePlayer::IsPlaying() { 109 return playing_; 110} 111 112int MediaSourcePlayer::GetVideoWidth() { 113 return width_; 114} 115 116int MediaSourcePlayer::GetVideoHeight() { 117 return height_; 118} 119 120void MediaSourcePlayer::SeekTo(base::TimeDelta timestamp) { 121 clock_.SetTime(timestamp, timestamp); 122 if (audio_timestamp_helper_) 123 audio_timestamp_helper_->SetBaseTimestamp(timestamp); 124 pending_event_ |= SEEK_EVENT_PENDING; 125 ProcessPendingEvents(); 126} 127 128base::TimeDelta MediaSourcePlayer::GetCurrentTime() { 129 return clock_.Elapsed(); 130} 131 132base::TimeDelta MediaSourcePlayer::GetDuration() { 133 return duration_; 134} 135 136void MediaSourcePlayer::Release() { 137 ClearDecodingData(); 138 audio_decoder_job_.reset(); 139 video_decoder_job_.reset(); 140 reconfig_audio_decoder_ = false; 141 reconfig_video_decoder_ = false; 142 playing_ = false; 143 pending_event_ = NO_EVENT_PENDING; 144 surface_ = gfx::ScopedJavaSurface(); 145 ReleaseMediaResourcesFromManager(); 146} 147 148void MediaSourcePlayer::SetVolume(double volume) { 149 volume_ = volume; 150 SetVolumeInternal(); 151} 152 153bool MediaSourcePlayer::CanPause() { 154 return Seekable(); 155} 156 157bool MediaSourcePlayer::CanSeekForward() { 158 return Seekable(); 159} 160 161bool MediaSourcePlayer::CanSeekBackward() { 162 return Seekable(); 163} 164 165bool MediaSourcePlayer::IsPlayerReady() { 166 return audio_decoder_job_ || video_decoder_job_; 167} 168 169void MediaSourcePlayer::StartInternal() { 170 // If there are pending events, wait for them finish. 171 if (pending_event_ != NO_EVENT_PENDING) 172 return; 173 174 // Create decoder jobs if they are not created 175 ConfigureAudioDecoderJob(); 176 ConfigureVideoDecoderJob(); 177 178 179 // If one of the decoder job is not ready, do nothing. 180 if ((HasAudio() && !audio_decoder_job_) || 181 (HasVideo() && !video_decoder_job_)) { 182 return; 183 } 184 185 audio_finished_ = false; 186 video_finished_ = false; 187 sync_decoder_jobs_ = true; 188 SyncAndStartDecoderJobs(); 189} 190 191void MediaSourcePlayer::DemuxerReady( 192 const MediaPlayerHostMsg_DemuxerReady_Params& params) { 193 duration_ = base::TimeDelta::FromMilliseconds(params.duration_ms); 194 clock_.SetDuration(duration_); 195 196 audio_codec_ = params.audio_codec; 197 num_channels_ = params.audio_channels; 198 sampling_rate_ = params.audio_sampling_rate; 199 is_audio_encrypted_ = params.is_audio_encrypted; 200 audio_extra_data_ = params.audio_extra_data; 201 if (HasAudio()) { 202 DCHECK_GT(num_channels_, 0); 203 audio_timestamp_helper_.reset(new AudioTimestampHelper(sampling_rate_)); 204 audio_timestamp_helper_->SetBaseTimestamp(GetCurrentTime()); 205 } else { 206 audio_timestamp_helper_.reset(); 207 } 208 209 video_codec_ = params.video_codec; 210 width_ = params.video_size.width(); 211 height_ = params.video_size.height(); 212 is_video_encrypted_ = params.is_video_encrypted; 213 214 OnMediaMetadataChanged(duration_, width_, height_, true); 215 216 if (pending_event_ & CONFIG_CHANGE_EVENT_PENDING) { 217 if (reconfig_audio_decoder_) 218 ConfigureAudioDecoderJob(); 219 220 // If there is a pending surface change, we can merge it with the config 221 // change. 222 if (reconfig_video_decoder_) { 223 pending_event_ &= ~SURFACE_CHANGE_EVENT_PENDING; 224 ConfigureVideoDecoderJob(); 225 } 226 pending_event_ &= ~CONFIG_CHANGE_EVENT_PENDING; 227 if (playing_) 228 StartInternal(); 229 } 230} 231 232void MediaSourcePlayer::ReadFromDemuxerAck( 233 const MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) { 234 DCHECK_LT(0u, params.access_units.size()); 235 if (params.type == DemuxerStream::AUDIO) 236 waiting_for_audio_data_ = false; 237 else 238 waiting_for_video_data_ = false; 239 240 // If there is a pending seek request, ignore the data from the chunk demuxer. 241 // The data will be requested later when OnSeekRequestAck() is called. 242 if (pending_event_ & SEEK_EVENT_PENDING) 243 return; 244 245 if (params.type == DemuxerStream::AUDIO) { 246 DCHECK_EQ(0u, audio_access_unit_index_); 247 received_audio_ = params; 248 } else { 249 DCHECK_EQ(0u, video_access_unit_index_); 250 received_video_ = params; 251 } 252 253 if (pending_event_ != NO_EVENT_PENDING || !playing_) 254 return; 255 256 if (sync_decoder_jobs_) { 257 SyncAndStartDecoderJobs(); 258 return; 259 } 260 261 if (params.type == DemuxerStream::AUDIO) 262 DecodeMoreAudio(); 263 else 264 DecodeMoreVideo(); 265} 266 267void MediaSourcePlayer::DurationChanged(const base::TimeDelta& duration) { 268 duration_ = duration; 269 clock_.SetDuration(duration_); 270} 271 272void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) { 273 // Currently we don't support DRM change during the middle of playback, even 274 // if the player is paused. 275 // TODO(qinmin): support DRM change after playback has started. 276 // http://crbug.com/253792. 277 if (GetCurrentTime() > base::TimeDelta()) { 278 LOG(INFO) << "Setting DRM bridge after play back has started. " 279 << "This is not well supported!"; 280 } 281 282 drm_bridge_ = drm_bridge; 283 284 if (playing_) 285 StartInternal(); 286} 287 288void MediaSourcePlayer::OnSeekRequestAck(unsigned seek_request_id) { 289 DVLOG(1) << "OnSeekRequestAck(" << seek_request_id << ")"; 290 // Do nothing until the most recent seek request is processed. 291 if (seek_request_id_ != seek_request_id) 292 return; 293 pending_event_ &= ~SEEK_EVENT_PENDING; 294 OnSeekComplete(); 295 ProcessPendingEvents(); 296} 297 298void MediaSourcePlayer::UpdateTimestamps( 299 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { 300 if (audio_output_bytes > 0) { 301 audio_timestamp_helper_->AddFrames( 302 audio_output_bytes / (kBytesPerAudioOutputSample * num_channels_)); 303 clock_.SetMaxTime(audio_timestamp_helper_->GetTimestamp()); 304 } else { 305 clock_.SetMaxTime(presentation_timestamp); 306 } 307 308 OnTimeUpdated(); 309} 310 311void MediaSourcePlayer::ProcessPendingEvents() { 312 // Wait for all the decoding jobs to finish before processing pending tasks. 313 if ((audio_decoder_job_ && audio_decoder_job_->is_decoding()) || 314 (video_decoder_job_ && video_decoder_job_->is_decoding())) { 315 return; 316 } 317 318 if (pending_event_ & SEEK_EVENT_PENDING) { 319 ClearDecodingData(); 320 manager()->OnMediaSeekRequest( 321 player_id(), GetCurrentTime(), ++seek_request_id_); 322 return; 323 } 324 325 start_time_ticks_ = base::TimeTicks(); 326 if (pending_event_ & CONFIG_CHANGE_EVENT_PENDING) { 327 DCHECK(reconfig_audio_decoder_ || reconfig_video_decoder_); 328 manager()->OnMediaConfigRequest(player_id()); 329 return; 330 } 331 332 if (pending_event_ & SURFACE_CHANGE_EVENT_PENDING) { 333 video_decoder_job_.reset(); 334 ConfigureVideoDecoderJob(); 335 pending_event_ &= ~SURFACE_CHANGE_EVENT_PENDING; 336 } 337 338 if (playing_) 339 StartInternal(); 340} 341 342void MediaSourcePlayer::MediaDecoderCallback( 343 bool is_audio, MediaDecoderJob::DecodeStatus decode_status, 344 const base::TimeDelta& presentation_timestamp, size_t audio_output_bytes) { 345 if (is_audio && audio_decoder_job_) 346 audio_decoder_job_->OnDecodeCompleted(); 347 if (!is_audio && video_decoder_job_) 348 video_decoder_job_->OnDecodeCompleted(); 349 350 if (is_audio) 351 decoder_starvation_callback_.Cancel(); 352 353 if (decode_status == MediaDecoderJob::DECODE_FAILED) { 354 Release(); 355 OnMediaError(MEDIA_ERROR_DECODE); 356 return; 357 } 358 359 // If the input reaches input EOS, there is no need to request new data. 360 if (decode_status != MediaDecoderJob::DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER && 361 decode_status != MediaDecoderJob::DECODE_INPUT_END_OF_STREAM) { 362 if (is_audio) 363 audio_access_unit_index_++; 364 else 365 video_access_unit_index_++; 366 } 367 368 if (pending_event_ != NO_EVENT_PENDING) { 369 ProcessPendingEvents(); 370 return; 371 } 372 373 if (decode_status == MediaDecoderJob::DECODE_SUCCEEDED && 374 (is_audio || !HasAudio())) { 375 UpdateTimestamps(presentation_timestamp, audio_output_bytes); 376 } 377 378 if (decode_status == MediaDecoderJob::DECODE_OUTPUT_END_OF_STREAM) { 379 PlaybackCompleted(is_audio); 380 return; 381 } 382 383 if (!playing_) { 384 if (is_audio || !HasAudio()) 385 clock_.Pause(); 386 return; 387 } 388 389 if (sync_decoder_jobs_) { 390 SyncAndStartDecoderJobs(); 391 return; 392 } 393 394 base::TimeDelta current_timestamp = GetCurrentTime(); 395 if (is_audio) { 396 if (decode_status == MediaDecoderJob::DECODE_SUCCEEDED) { 397 base::TimeDelta timeout = 398 audio_timestamp_helper_->GetTimestamp() - current_timestamp; 399 StartStarvationCallback(timeout); 400 } 401 if (!HasAudioData()) 402 RequestAudioData(); 403 else 404 DecodeMoreAudio(); 405 return; 406 } 407 408 if (!HasAudio() && decode_status == MediaDecoderJob::DECODE_SUCCEEDED) { 409 DCHECK(current_timestamp <= presentation_timestamp); 410 // For video only streams, fps can be estimated from the difference 411 // between the previous and current presentation timestamps. The 412 // previous presentation timestamp is equal to current_timestamp. 413 // TODO(qinmin): determine whether 2 is a good coefficient for estimating 414 // video frame timeout. 415 StartStarvationCallback(2 * (presentation_timestamp - current_timestamp)); 416 } 417 if (!HasVideoData()) 418 RequestVideoData(); 419 else 420 DecodeMoreVideo(); 421} 422 423void MediaSourcePlayer::DecodeMoreAudio() { 424 DCHECK(!audio_decoder_job_->is_decoding()); 425 DCHECK(HasAudioData()); 426 427 if (DemuxerStream::kConfigChanged == 428 received_audio_.access_units[audio_access_unit_index_].status) { 429 // Wait for demuxer ready message. 430 reconfig_audio_decoder_ = true; 431 pending_event_ |= CONFIG_CHANGE_EVENT_PENDING; 432 received_audio_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); 433 audio_access_unit_index_ = 0; 434 ProcessPendingEvents(); 435 return; 436 } 437 438 audio_decoder_job_->Decode( 439 received_audio_.access_units[audio_access_unit_index_], 440 start_time_ticks_, start_presentation_timestamp_, 441 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 442 weak_this_.GetWeakPtr(), true)); 443} 444 445void MediaSourcePlayer::DecodeMoreVideo() { 446 DVLOG(1) << "DecodeMoreVideo()"; 447 DCHECK(!video_decoder_job_->is_decoding()); 448 DCHECK(HasVideoData()); 449 450 if (DemuxerStream::kConfigChanged == 451 received_video_.access_units[video_access_unit_index_].status) { 452 // Wait for demuxer ready message. 453 reconfig_video_decoder_ = true; 454 pending_event_ |= CONFIG_CHANGE_EVENT_PENDING; 455 received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); 456 video_access_unit_index_ = 0; 457 ProcessPendingEvents(); 458 return; 459 } 460 461 DVLOG(3) << "VideoDecoderJob::Decode(" << video_access_unit_index_ << ", " 462 << start_time_ticks_.ToInternalValue() << ", " 463 << start_presentation_timestamp_.InMilliseconds() << ")"; 464 video_decoder_job_->Decode( 465 received_video_.access_units[video_access_unit_index_], 466 start_time_ticks_, start_presentation_timestamp_, 467 base::Bind(&MediaSourcePlayer::MediaDecoderCallback, 468 weak_this_.GetWeakPtr(), false)); 469} 470 471void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { 472 if (is_audio) 473 audio_finished_ = true; 474 else 475 video_finished_ = true; 476 477 if ((!HasAudio() || audio_finished_) && (!HasVideo() || video_finished_)) { 478 playing_ = false; 479 clock_.Pause(); 480 start_time_ticks_ = base::TimeTicks(); 481 OnPlaybackComplete(); 482 } 483} 484 485void MediaSourcePlayer::ClearDecodingData() { 486 DVLOG(1) << "ClearDecodingData()"; 487 if (audio_decoder_job_) 488 audio_decoder_job_->Flush(); 489 if (video_decoder_job_) 490 video_decoder_job_->Flush(); 491 start_time_ticks_ = base::TimeTicks(); 492 received_audio_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); 493 received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); 494 audio_access_unit_index_ = 0; 495 video_access_unit_index_ = 0; 496 waiting_for_audio_data_ = false; 497 waiting_for_video_data_ = false; 498} 499 500bool MediaSourcePlayer::HasVideo() { 501 return kUnknownVideoCodec != video_codec_; 502} 503 504bool MediaSourcePlayer::HasAudio() { 505 return kUnknownAudioCodec != audio_codec_; 506} 507 508void MediaSourcePlayer::ConfigureAudioDecoderJob() { 509 if (!HasAudio()) { 510 audio_decoder_job_.reset(); 511 return; 512 } 513 514 // Create audio decoder job only if config changes. 515 if (audio_decoder_job_ && !reconfig_audio_decoder_) 516 return; 517 518 base::android::ScopedJavaLocalRef<jobject> media_codec; 519 if (is_audio_encrypted_) { 520 if (drm_bridge_) { 521 media_codec = drm_bridge_->GetMediaCrypto(); 522 // TODO(qinmin): currently we assume MediaCrypto is available whenever 523 // MediaDrmBridge is constructed. This will change if we want to support 524 // more general uses cases of EME. 525 DCHECK(!media_codec.is_null()); 526 } else { 527 // Don't create the decoder job if |drm_bridge_| is not set, 528 // so StartInternal() will not proceed. 529 LOG(INFO) << "MediaDrmBridge is not available when creating decoder " 530 << "for encrypted audio stream."; 531 return; 532 } 533 } 534 535 audio_decoder_job_.reset(AudioDecoderJob::Create( 536 audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0], 537 audio_extra_data_.size(), media_codec.obj())); 538 539 if (audio_decoder_job_) { 540 SetVolumeInternal(); 541 reconfig_audio_decoder_ = false; 542 } 543} 544 545void MediaSourcePlayer::ConfigureVideoDecoderJob() { 546 if (!HasVideo() || surface_.IsEmpty()) { 547 video_decoder_job_.reset(); 548 return; 549 } 550 551 // Create video decoder job only if config changes. 552 if (video_decoder_job_ && !reconfig_video_decoder_) 553 return; 554 555 base::android::ScopedJavaLocalRef<jobject> media_crypto; 556 if (is_video_encrypted_) { 557 if (drm_bridge_) { 558 media_crypto = drm_bridge_->GetMediaCrypto(); 559 DCHECK(!media_crypto.is_null()); 560 } else { 561 LOG(INFO) << "MediaDrmBridge is not available when creating decoder " 562 << "for encrypted video stream."; 563 return; 564 } 565 } 566 567 // Release the old VideoDecoderJob first so the surface can get released. 568 // Android does not allow 2 MediaCodec instances use the same surface. 569 video_decoder_job_.reset(); 570 // Create the new VideoDecoderJob. 571 video_decoder_job_.reset(VideoDecoderJob::Create( 572 video_codec_, gfx::Size(width_, height_), surface_.j_surface().obj(), 573 media_crypto.obj())); 574 if (video_decoder_job_) 575 reconfig_video_decoder_ = false; 576 577 // Inform the fullscreen view the player is ready. 578 // TODO(qinmin): refactor MediaPlayerBridge so that we have a better way 579 // to inform ContentVideoView. 580 OnMediaMetadataChanged(duration_, width_, height_, true); 581} 582 583void MediaSourcePlayer::OnDecoderStarved() { 584 sync_decoder_jobs_ = true; 585} 586 587void MediaSourcePlayer::StartStarvationCallback( 588 const base::TimeDelta& timeout) { 589 decoder_starvation_callback_.Reset( 590 base::Bind(&MediaSourcePlayer::OnDecoderStarved, 591 weak_this_.GetWeakPtr())); 592 base::MessageLoop::current()->PostDelayedTask( 593 FROM_HERE, decoder_starvation_callback_.callback(), timeout); 594} 595 596void MediaSourcePlayer::SyncAndStartDecoderJobs() { 597 // For streams with both audio and video, send the request for video too. 598 // However, don't wait for the response so that we won't have lots of 599 // noticeable pauses in the audio. Video will sync with audio by itself. 600 if (HasVideo() && !HasVideoData()) { 601 RequestVideoData(); 602 if (!HasAudio()) 603 return; 604 } 605 if (HasAudio() && !HasAudioData()) { 606 RequestAudioData(); 607 return; 608 } 609 start_time_ticks_ = base::TimeTicks::Now(); 610 start_presentation_timestamp_ = GetCurrentTime(); 611 if (!clock_.IsPlaying()) 612 clock_.Play(); 613 if (HasAudioData() && !audio_decoder_job_->is_decoding()) 614 DecodeMoreAudio(); 615 if (HasVideoData() && !video_decoder_job_->is_decoding()) 616 DecodeMoreVideo(); 617 sync_decoder_jobs_ = false; 618} 619 620void MediaSourcePlayer::RequestAudioData() { 621 DVLOG(2) << "RequestAudioData()"; 622 DCHECK(HasAudio()); 623 624 if (waiting_for_audio_data_) 625 return; 626 627 manager()->OnReadFromDemuxer(player_id(), DemuxerStream::AUDIO); 628 received_audio_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); 629 audio_access_unit_index_ = 0; 630 waiting_for_audio_data_ = true; 631} 632 633void MediaSourcePlayer::RequestVideoData() { 634 DVLOG(2) << "RequestVideoData()"; 635 DCHECK(HasVideo()); 636 if (waiting_for_video_data_) 637 return; 638 639 manager()->OnReadFromDemuxer(player_id(), DemuxerStream::VIDEO); 640 received_video_ = MediaPlayerHostMsg_ReadFromDemuxerAck_Params(); 641 video_access_unit_index_ = 0; 642 waiting_for_video_data_ = true; 643} 644 645bool MediaSourcePlayer::HasAudioData() const { 646 return audio_access_unit_index_ < received_audio_.access_units.size(); 647} 648 649bool MediaSourcePlayer::HasVideoData() const { 650 return video_access_unit_index_ < received_video_.access_units.size(); 651} 652 653void MediaSourcePlayer::SetVolumeInternal() { 654 if (audio_decoder_job_ && volume_ >= 0) 655 audio_decoder_job_.get()->SetVolume(volume_); 656} 657 658} // namespace media 659