| 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..c3571f4591c6759cd3832995c8b50f3fef1be5ae
|
| --- /dev/null
|
| +++ b/media/base/android/media_codec_player_state.cc
|
| @@ -0,0 +1,140 @@
|
| +#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());
|
| + 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
|
|
|