OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_codec_player.h" | 5 #include "media/base/android/media_codec_player.h" |
6 | 6 |
7 #include "base/barrier_closure.h" | 7 #include "base/barrier_closure.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 // Currently the unit tests wait for the MediaCodecPlayer destruction by | 91 // Currently the unit tests wait for the MediaCodecPlayer destruction by |
92 // watching the demuxer, which is destroyed as one of the member variables. | 92 // watching the demuxer, which is destroyed as one of the member variables. |
93 // Release the codecs here, before any member variable is destroyed to make | 93 // Release the codecs here, before any member variable is destroyed to make |
94 // the unit tests happy. | 94 // the unit tests happy. |
95 | 95 |
96 if (video_decoder_) | 96 if (video_decoder_) |
97 video_decoder_->ReleaseDecoderResources(); | 97 video_decoder_->ReleaseDecoderResources(); |
98 if (audio_decoder_) | 98 if (audio_decoder_) |
99 audio_decoder_->ReleaseDecoderResources(); | 99 audio_decoder_->ReleaseDecoderResources(); |
100 | 100 |
| 101 media_stat_->StopAndReport(); |
| 102 |
101 if (drm_bridge_) { | 103 if (drm_bridge_) { |
102 DCHECK(cdm_registration_id_); | 104 DCHECK(cdm_registration_id_); |
103 drm_bridge_->UnregisterPlayer(cdm_registration_id_); | 105 drm_bridge_->UnregisterPlayer(cdm_registration_id_); |
104 } | 106 } |
105 } | 107 } |
106 | 108 |
107 void MediaCodecPlayer::Initialize() { | 109 void MediaCodecPlayer::Initialize() { |
108 DVLOG(1) << __FUNCTION__; | 110 DVLOG(1) << __FUNCTION__; |
109 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 111 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
110 | 112 |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 default: | 801 default: |
800 // DVLOG(0) << __FUNCTION__ << " illegal state: " << AsString(state_); | 802 // DVLOG(0) << __FUNCTION__ << " illegal state: " << AsString(state_); |
801 // NOTREACHED(); | 803 // NOTREACHED(); |
802 // Ignore! There can be a race condition: audio posts OnStopDone, | 804 // Ignore! There can be a race condition: audio posts OnStopDone, |
803 // then video posts, then first OnStopDone arrives at which point | 805 // then video posts, then first OnStopDone arrives at which point |
804 // both streams are already stopped, then second OnStopDone arrives. When | 806 // both streams are already stopped, then second OnStopDone arrives. When |
805 // the second one arrives, the state us not kStateStopping any more. | 807 // the second one arrives, the state us not kStateStopping any more. |
806 return; | 808 return; |
807 } | 809 } |
808 | 810 |
| 811 media_stat_->StopAndReport(); |
| 812 |
809 // DetachListener to UI thread | 813 // DetachListener to UI thread |
810 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); | 814 ui_task_runner_->PostTask(FROM_HERE, detach_listener_cb_); |
811 | 815 |
812 if (AudioFinished() && VideoFinished()) | 816 if (AudioFinished() && VideoFinished()) |
813 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); | 817 ui_task_runner_->PostTask(FROM_HERE, completion_cb_); |
814 } | 818 } |
815 | 819 |
816 void MediaCodecPlayer::OnKeyRequired(DemuxerStream::Type type) { | 820 void MediaCodecPlayer::OnKeyRequired(DemuxerStream::Type type) { |
817 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 821 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
818 DVLOG(1) << __FUNCTION__ << " " << type; | 822 DVLOG(1) << __FUNCTION__ << " " << type; |
(...skipping 24 matching lines...) Expand all Loading... |
843 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) { | 847 void MediaCodecPlayer::OnStarvation(DemuxerStream::Type type) { |
844 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 848 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
845 DVLOG(1) << __FUNCTION__ << " stream type:" << type; | 849 DVLOG(1) << __FUNCTION__ << " stream type:" << type; |
846 | 850 |
847 if (state_ != kStatePlaying) | 851 if (state_ != kStatePlaying) |
848 return; // Ignore | 852 return; // Ignore |
849 | 853 |
850 SetState(kStateStopping); | 854 SetState(kStateStopping); |
851 RequestToStopDecoders(); | 855 RequestToStopDecoders(); |
852 SetPendingStart(true); | 856 SetPendingStart(true); |
| 857 |
| 858 media_stat_->AddStarvation(); |
853 } | 859 } |
854 | 860 |
855 void MediaCodecPlayer::OnTimeIntervalUpdate(DemuxerStream::Type type, | 861 void MediaCodecPlayer::OnTimeIntervalUpdate(DemuxerStream::Type type, |
856 base::TimeDelta now_playing, | 862 base::TimeDelta now_playing, |
857 base::TimeDelta last_buffered, | 863 base::TimeDelta last_buffered, |
858 bool postpone) { | 864 bool postpone) { |
859 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 865 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
860 | 866 |
861 DVLOG(2) << __FUNCTION__ << ": stream type:" << type << " [" << now_playing | 867 DVLOG(2) << __FUNCTION__ << ": stream type:" << type << " [" << now_playing |
862 << "," << last_buffered << "]" << (postpone ? " postpone" : ""); | 868 << "," << last_buffered << "]" << (postpone ? " postpone" : ""); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartDecoders() { | 1245 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartDecoders() { |
1240 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1246 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1241 | 1247 |
1242 if (!interpolator_.interpolating()) | 1248 if (!interpolator_.interpolating()) |
1243 interpolator_.StartInterpolating(); | 1249 interpolator_.StartInterpolating(); |
1244 | 1250 |
1245 base::TimeDelta current_time = GetInterpolatedTime(); | 1251 base::TimeDelta current_time = GetInterpolatedTime(); |
1246 | 1252 |
1247 DVLOG(1) << __FUNCTION__ << " current_time:" << current_time; | 1253 DVLOG(1) << __FUNCTION__ << " current_time:" << current_time; |
1248 | 1254 |
| 1255 // This methos needs to be called when decoder threads are not processing |
| 1256 // frames. |
| 1257 media_stat_->Start(); |
| 1258 |
1249 if (!AudioFinished()) { | 1259 if (!AudioFinished()) { |
1250 if (!audio_decoder_->Start(current_time)) | 1260 if (!audio_decoder_->Start(current_time)) |
1251 return kStartFailed; | 1261 return kStartFailed; |
1252 | 1262 |
1253 // Attach listener on UI thread | 1263 // Attach listener on UI thread |
1254 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_); | 1264 ui_task_runner_->PostTask(FROM_HERE, attach_listener_cb_); |
1255 } | 1265 } |
1256 | 1266 |
1257 if (!VideoFinished()) { | 1267 if (!VideoFinished()) { |
1258 if (!video_decoder_->Start(current_time)) | 1268 if (!video_decoder_->Start(current_time)) |
1259 return kStartFailed; | 1269 return kStartFailed; |
1260 } | 1270 } |
1261 | 1271 |
1262 return kStartOk; | 1272 return kStartOk; |
1263 } | 1273 } |
1264 | 1274 |
1265 void MediaCodecPlayer::StopDecoders() { | 1275 void MediaCodecPlayer::StopDecoders() { |
1266 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1276 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1267 DVLOG(1) << __FUNCTION__; | 1277 DVLOG(1) << __FUNCTION__; |
1268 | 1278 |
1269 video_decoder_->SyncStop(); | 1279 video_decoder_->SyncStop(); |
1270 audio_decoder_->SyncStop(); | 1280 audio_decoder_->SyncStop(); |
| 1281 |
| 1282 media_stat_->StopAndReport(); |
1271 } | 1283 } |
1272 | 1284 |
1273 void MediaCodecPlayer::RequestToStopDecoders() { | 1285 void MediaCodecPlayer::RequestToStopDecoders() { |
1274 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1286 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1275 DVLOG(1) << __FUNCTION__; | 1287 DVLOG(1) << __FUNCTION__; |
1276 | 1288 |
1277 bool do_audio = false; | 1289 bool do_audio = false; |
1278 bool do_video = false; | 1290 bool do_video = false; |
1279 | 1291 |
1280 if (audio_decoder_->IsPrefetchingOrPlaying()) | 1292 if (audio_decoder_->IsPrefetchingOrPlaying()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 | 1330 |
1319 if (audio_decoder_) | 1331 if (audio_decoder_) |
1320 audio_decoder_->ReleaseDecoderResources(); | 1332 audio_decoder_->ReleaseDecoderResources(); |
1321 | 1333 |
1322 if (video_decoder_) | 1334 if (video_decoder_) |
1323 video_decoder_->ReleaseDecoderResources(); | 1335 video_decoder_->ReleaseDecoderResources(); |
1324 | 1336 |
1325 // At this point decoder threads should not be running | 1337 // At this point decoder threads should not be running |
1326 if (interpolator_.interpolating()) | 1338 if (interpolator_.interpolating()) |
1327 interpolator_.StopInterpolating(); | 1339 interpolator_.StopInterpolating(); |
| 1340 |
| 1341 media_stat_->StopAndReport(); |
1328 } | 1342 } |
1329 | 1343 |
1330 void MediaCodecPlayer::CreateDecoders() { | 1344 void MediaCodecPlayer::CreateDecoders() { |
1331 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1345 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1332 DVLOG(1) << __FUNCTION__; | 1346 DVLOG(1) << __FUNCTION__; |
1333 | 1347 |
1334 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); | 1348 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); |
1335 | 1349 |
| 1350 media_stat_.reset(new MediaStatistics()); |
| 1351 |
1336 audio_decoder_.reset(new MediaCodecAudioDecoder( | 1352 audio_decoder_.reset(new MediaCodecAudioDecoder( |
1337 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1353 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
1338 media_weak_this_, DemuxerStream::AUDIO), | 1354 media_weak_this_, DemuxerStream::AUDIO), |
1339 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1355 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
1340 DemuxerStream::AUDIO), | 1356 DemuxerStream::AUDIO), |
1341 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, | 1357 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
1342 DemuxerStream::AUDIO), | 1358 DemuxerStream::AUDIO), |
1343 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, | 1359 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
1344 DemuxerStream::AUDIO), | 1360 DemuxerStream::AUDIO), |
1345 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, | 1361 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, |
1346 DemuxerStream::AUDIO), | 1362 DemuxerStream::AUDIO), |
1347 internal_error_cb_, | 1363 internal_error_cb_, |
1348 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1364 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
1349 DemuxerStream::AUDIO))); | 1365 DemuxerStream::AUDIO), |
| 1366 &media_stat_->AudioFrames())); |
1350 | 1367 |
1351 video_decoder_.reset(new MediaCodecVideoDecoder( | 1368 video_decoder_.reset(new MediaCodecVideoDecoder( |
1352 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1369 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
1353 media_weak_this_, DemuxerStream::VIDEO), | 1370 media_weak_this_, DemuxerStream::VIDEO), |
1354 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1371 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
1355 DemuxerStream::VIDEO), | 1372 DemuxerStream::VIDEO), |
1356 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, | 1373 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
1357 DemuxerStream::VIDEO), | 1374 DemuxerStream::VIDEO), |
1358 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, | 1375 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
1359 DemuxerStream::VIDEO), | 1376 DemuxerStream::VIDEO), |
1360 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, | 1377 base::Bind(&MediaCodecPlayer::OnKeyRequired, media_weak_this_, |
1361 DemuxerStream::VIDEO), | 1378 DemuxerStream::VIDEO), |
1362 internal_error_cb_, | 1379 internal_error_cb_, |
1363 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1380 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
1364 DemuxerStream::VIDEO), | 1381 DemuxerStream::VIDEO), |
1365 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 1382 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
1366 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 1383 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_), |
| 1384 &media_stat_->VideoFrames())); |
1367 } | 1385 } |
1368 | 1386 |
1369 bool MediaCodecPlayer::AudioFinished() const { | 1387 bool MediaCodecPlayer::AudioFinished() const { |
1370 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 1388 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
1371 } | 1389 } |
1372 | 1390 |
1373 bool MediaCodecPlayer::VideoFinished() const { | 1391 bool MediaCodecPlayer::VideoFinished() const { |
1374 return video_decoder_->IsCompleted() || !video_decoder_->HasStream(); | 1392 return video_decoder_->IsCompleted() || !video_decoder_->HasStream(); |
1375 } | 1393 } |
1376 | 1394 |
(...skipping 22 matching lines...) Expand all Loading... |
1399 RETURN_STRING(kStateWaitingForCrypto); | 1417 RETURN_STRING(kStateWaitingForCrypto); |
1400 RETURN_STRING(kStateWaitingForSeek); | 1418 RETURN_STRING(kStateWaitingForSeek); |
1401 RETURN_STRING(kStateError); | 1419 RETURN_STRING(kStateError); |
1402 } | 1420 } |
1403 return nullptr; // crash early | 1421 return nullptr; // crash early |
1404 } | 1422 } |
1405 | 1423 |
1406 #undef RETURN_STRING | 1424 #undef RETURN_STRING |
1407 | 1425 |
1408 } // namespace media | 1426 } // namespace media |
OLD | NEW |