Index: media/base/android/media_codec_player_state.cc |
diff --git a/media/base/android/media_codec_player_state.cc b/media/base/android/media_codec_player_state.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bb20d0b69553757d2789d7658b2e2d768b3fc961 |
--- /dev/null |
+++ b/media/base/android/media_codec_player_state.cc |
@@ -0,0 +1,138 @@ |
+#include "media/base/android/media_codec_player_state.h" |
+#include "media/base/android/media_codec_player.h" |
+#include "media/base/buffers.h" |
+ |
+namespace media { |
+ |
+// Every method is called on the Media thread |
+ |
+// MediaCodecPlayerState (superclass) |
+ |
+// By default, set configs for the future use |
+void MediaCodecPlayerState::EventDemuxerConfigsAvailable( |
+ MediaCodecPlayer* player, const DemuxerConfigs& configs) { |
+ player->SetDemuxerConfigs(configs); |
+} |
+ |
+// By default, set the Error state that blocks all events |
+void MediaCodecPlayerState::EventError(MediaCodecPlayer* player) { |
+ player->SetState(StateError::Instance()); |
+} |
+ |
+// Stop decoders synchronously. |
+// TODO: as it seems to work for every state, consider moving Release() |
+// out of the state machine. |
+void MediaCodecPlayerState::EventRelease(MediaCodecPlayer* player) { |
+ player->SetState(StatePaused::Instance()); |
+ player->ReleaseDecoderResources(); |
+} |
+ |
+ |
+// StatePaused |
+ |
+void StatePaused::EventStart(MediaCodecPlayer* player) { |
+ player->SetState(StatePrefetching::Instance()); |
+ player->StartPrefetchDecoders(); |
+} |
+ |
+ |
+// StatePrefetching |
+ |
+void StatePrefetching::EventPause(MediaCodecPlayer* player) { |
+ player->SetState(StatePaused::Instance()); |
qinmin
2015/05/14 19:52:58
I have bad feelings about these call sequences, an
Tima Vaisburd
2015/05/15 00:12:40
Yes, it does look somewhat weird. The code like
|
+ player->StopDecoders(); |
+} |
+ |
+void StatePrefetching::EventPrefetchDone(MediaCodecPlayer* player) { |
+ if (!player->HasAudio() && !player->HasVideo()) { |
+ // No configuration at all, let's wait for it. |
+ // Although it probably should never happen here, |
+ // after the data has come from demuxer. |
+ player->SetState(StateWaitingForConfig::Instance()); |
+ return; |
+ } |
+ |
+ if (player->HasVideo() && !player->HasPendingSurface()) { |
+ player->SetState(StateWaitingForSurface::Instance()); |
+ return; |
+ } |
+ |
+ player->SetState(StatePlaying::Instance()); |
+ player->StartPlaybackDecoders(); |
+} |
+ |
+ |
+// StateWaitingForConfig |
+ |
+void StateWaitingForConfig::EventDemuxerConfigsAvailable( |
+ MediaCodecPlayer* player, const DemuxerConfigs& configs) { |
+ |
+ player->SetDemuxerConfigs(configs); |
+ |
+ if (player->HasVideo() && !player->HasPendingSurface()) { |
+ player->SetState(StateWaitingForSurface::Instance()); |
+ return; |
+ } |
+ |
+ player->SetState(StatePlaying::Instance()); |
+ player->StartPlaybackDecoders(); |
+} |
+ |
+void StateWaitingForConfig::EventPause(MediaCodecPlayer* player) { |
+ player->SetState(StatePaused::Instance()); |
+} |
+ |
+ |
+// StateWaitingForSurface |
+ |
+void StateWaitingForSurface::EventSetVideoSurface(MediaCodecPlayer* player) { |
+ player->SetState(StatePlaying::Instance()); |
+ player->StartPlaybackDecoders(); |
+} |
+ |
+void StateWaitingForSurface::EventPause(MediaCodecPlayer* player) { |
+ player->SetState(StatePaused::Instance()); |
+ player->StopDecoders(); |
+} |
+ |
+ |
+// StatePlaying |
+ |
+void StatePlaying::EventPause(MediaCodecPlayer* player) { |
+ player->SetState(StateStopping::Instance()); |
+ player->RequestToStopDecoders(); |
+} |
+ |
+void StatePlaying::EventStarvation(MediaCodecPlayer* player) { |
+ player->SetState(StateStopping::Instance()); |
+ player->RequestToStopDecoders(); |
+ player->SetPendingStart(true); |
+} |
+ |
+void StatePlaying::EventStopDone(MediaCodecPlayer* player) { |
+ // Unexpected stop means completion |
+ player->SetState(StatePaused::Instance()); |
+} |
+ |
+void StatePlaying::EventError(MediaCodecPlayer* player) { |
+ player->SetState(StateError::Instance()); |
+ player->ReleaseDecoderResources(); |
+} |
+ |
+ |
+// StateStopping |
+ |
+void StateStopping::EventStart(MediaCodecPlayer* player) { |
+ player->SetPendingStart(true); |
+} |
+ |
+void StateStopping::EventStopDone(MediaCodecPlayer* player) { |
+ if (player->HasPendingStart()) { |
+ player->SetState(StatePrefetching::Instance()); |
+ player->StartPrefetchDecoders(); |
+ } else { |
+ player->SetState(StatePaused::Instance()); |
+ } |
+} |
+ |
+} // namespace media |