/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef AWESOME_PLAYER_H_ #define AWESOME_PLAYER_H_ #include "NuHTTPDataSource.h" #include "TimedEventQueue.h" #include #include #include #include #include namespace android { struct AudioPlayer; struct DataSource; struct MediaBuffer; struct MediaExtractor; struct MediaSource; struct NuCachedSource2; struct ALooper; struct ARTSPController; struct ARTPSession; struct UDPPusher; struct AwesomeRenderer : public RefBase { AwesomeRenderer() {} virtual void render(MediaBuffer *buffer) = 0; private: AwesomeRenderer(const AwesomeRenderer &); AwesomeRenderer &operator=(const AwesomeRenderer &); }; struct AwesomePlayer { AwesomePlayer(); ~AwesomePlayer(); void setListener(const wp &listener); status_t setDataSource( const char *uri, const KeyedVector *headers = NULL); status_t setDataSource(int fd, int64_t offset, int64_t length); void reset(); status_t prepare(); status_t prepare_l(); status_t prepareAsync(); status_t prepareAsync_l(); status_t play(); status_t pause(); bool isPlaying() const; void setISurface(const sp &isurface); void setAudioSink(const sp &audioSink); status_t setLooping(bool shouldLoop); status_t getDuration(int64_t *durationUs); status_t getPosition(int64_t *positionUs); status_t seekTo(int64_t timeUs); status_t getVideoDimensions(int32_t *width, int32_t *height) const; status_t suspend(); status_t resume(); // This is a mask of MediaExtractor::Flags. uint32_t flags() const; void postAudioEOS(); void postAudioSeekComplete(); private: friend struct AwesomeEvent; enum { PLAYING = 1, LOOPING = 2, FIRST_FRAME = 4, PREPARING = 8, PREPARED = 16, AT_EOS = 32, PREPARE_CANCELLED = 64, CACHE_UNDERRUN = 128, AUDIO_AT_EOS = 256, VIDEO_AT_EOS = 512, AUTO_LOOPING = 1024, }; mutable Mutex mLock; Mutex mMiscStateLock; OMXClient mClient; TimedEventQueue mQueue; bool mQueueStarted; wp mListener; sp mISurface; sp mAudioSink; SystemTimeSource mSystemTimeSource; TimeSource *mTimeSource; String8 mUri; KeyedVector mUriHeaders; sp mFileSource; sp mVideoTrack; sp mVideoSource; sp mVideoRenderer; bool mVideoRendererIsPreview; sp mAudioTrack; sp mAudioSource; AudioPlayer *mAudioPlayer; int64_t mDurationUs; uint32_t mFlags; uint32_t mExtractorFlags; int32_t mVideoWidth, mVideoHeight; int64_t mTimeSourceDeltaUs; int64_t mVideoTimeUs; bool mSeeking; bool mSeekNotificationSent; int64_t mSeekTimeUs; bool mWatchForAudioSeekComplete; bool mWatchForAudioEOS; sp mVideoEvent; bool mVideoEventPending; sp mStreamDoneEvent; bool mStreamDoneEventPending; sp mBufferingEvent; bool mBufferingEventPending; sp mCheckAudioStatusEvent; bool mAudioStatusEventPending; sp mAsyncPrepareEvent; Condition mPreparedCondition; bool mIsAsyncPrepare; status_t mPrepareResult; status_t mStreamDoneStatus; void postVideoEvent_l(int64_t delayUs = -1); void postBufferingEvent_l(); void postStreamDoneEvent_l(status_t status); void postCheckAudioStatusEvent_l(); status_t play_l(); MediaBuffer *mLastVideoBuffer; MediaBuffer *mVideoBuffer; sp mConnectingDataSource; sp mCachedSource; sp mLooper; sp mRTSPController; sp mRTPSession; sp mRTPPusher, mRTCPPusher; struct SuspensionState { String8 mUri; KeyedVector mUriHeaders; sp mFileSource; uint32_t mFlags; int64_t mPositionUs; void *mLastVideoFrame; size_t mLastVideoFrameSize; int32_t mColorFormat; int32_t mVideoWidth, mVideoHeight; int32_t mDecodedWidth, mDecodedHeight; SuspensionState() : mLastVideoFrame(NULL) { } ~SuspensionState() { if (mLastVideoFrame) { free(mLastVideoFrame); mLastVideoFrame = NULL; } } } *mSuspensionState; status_t setDataSource_l( const char *uri, const KeyedVector *headers = NULL); status_t setDataSource_l(const sp &dataSource); status_t setDataSource_l(const sp &extractor); void reset_l(); void partial_reset_l(); status_t seekTo_l(int64_t timeUs); status_t pause_l(bool at_eos = false); void initRenderer_l(); void seekAudioIfNecessary_l(); void cancelPlayerEvents(bool keepBufferingGoing = false); void setAudioSource(sp source); status_t initAudioDecoder(); void setVideoSource(sp source); status_t initVideoDecoder(uint32_t flags = 0); void onStreamDone(); void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0); void onVideoEvent(); void onBufferingUpdate(); void onCheckAudioStatus(); void onPrepareAsyncEvent(); void abortPrepare(status_t err); void finishAsyncPrepare_l(); bool getCachedDuration_l(int64_t *durationUs, bool *eos); status_t finishSetDataSource_l(); static bool ContinuePreparation(void *cookie); AwesomePlayer(const AwesomePlayer &); AwesomePlayer &operator=(const AwesomePlayer &); }; } // namespace android #endif // AWESOME_PLAYER_H_