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