| /* |
| * Copyright (C) 2012 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 GENERIC_SOURCE_H_ |
| |
| #define GENERIC_SOURCE_H_ |
| |
| #include "NuPlayer.h" |
| #include "NuPlayerSource.h" |
| |
| #include "ATSParser.h" |
| |
| #include <media/mediaplayer.h> |
| |
| namespace android { |
| |
| class DecryptHandle; |
| class DrmManagerClient; |
| struct AnotherPacketSource; |
| struct ARTSPController; |
| class DataSource; |
| class IDataSource; |
| struct IMediaHTTPService; |
| struct MediaSource; |
| class MediaBuffer; |
| struct NuCachedSource2; |
| class WVMExtractor; |
| |
| struct NuPlayer::GenericSource : public NuPlayer::Source { |
| GenericSource(const sp<AMessage> ¬ify, bool uidValid, uid_t uid); |
| |
| status_t setDataSource( |
| const sp<IMediaHTTPService> &httpService, |
| const char *url, |
| const KeyedVector<String8, String8> *headers); |
| |
| status_t setDataSource(int fd, int64_t offset, int64_t length); |
| |
| status_t setDataSource(const sp<DataSource>& dataSource); |
| |
| virtual void prepareAsync(); |
| |
| virtual void start(); |
| virtual void stop(); |
| virtual void pause(); |
| virtual void resume(); |
| |
| virtual void disconnect(); |
| |
| virtual status_t feedMoreTSData(); |
| |
| virtual sp<MetaData> getFileFormatMeta() const; |
| |
| virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit); |
| |
| virtual status_t getDuration(int64_t *durationUs); |
| virtual size_t getTrackCount() const; |
| virtual sp<AMessage> getTrackInfo(size_t trackIndex) const; |
| virtual ssize_t getSelectedTrack(media_track_type type) const; |
| virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs); |
| virtual status_t seekTo(int64_t seekTimeUs); |
| |
| virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers); |
| |
| virtual bool isStreaming() const; |
| |
| virtual void setOffloadAudio(bool offload); |
| |
| protected: |
| virtual ~GenericSource(); |
| |
| virtual void onMessageReceived(const sp<AMessage> &msg); |
| |
| virtual sp<MetaData> getFormatMeta(bool audio); |
| |
| private: |
| enum { |
| kWhatPrepareAsync, |
| kWhatFetchSubtitleData, |
| kWhatFetchTimedTextData, |
| kWhatSendSubtitleData, |
| kWhatSendGlobalTimedTextData, |
| kWhatSendTimedTextData, |
| kWhatChangeAVSource, |
| kWhatPollBuffering, |
| kWhatGetFormat, |
| kWhatGetSelectedTrack, |
| kWhatSelectTrack, |
| kWhatSeek, |
| kWhatReadBuffer, |
| kWhatStopWidevine, |
| kWhatStart, |
| kWhatResume, |
| kWhatSecureDecodersInstantiated, |
| }; |
| |
| struct Track { |
| size_t mIndex; |
| sp<IMediaSource> mSource; |
| sp<AnotherPacketSource> mPackets; |
| }; |
| |
| // Helper to monitor buffering status. The polling happens every second. |
| // When necessary, it will send out buffering events to the player. |
| struct BufferingMonitor : public AHandler { |
| public: |
| BufferingMonitor(const sp<AMessage> ¬ify); |
| |
| // Set up state. |
| void prepare(const sp<NuCachedSource2> &cachedSource, |
| const sp<WVMExtractor> &wvmExtractor, |
| int64_t durationUs, |
| int64_t bitrate, |
| bool isStreaming); |
| // Stop and reset buffering monitor. |
| void stop(); |
| // Cancel the current monitor task. |
| void cancelPollBuffering(); |
| // Restart the monitor task. |
| void restartPollBuffering(); |
| // Stop buffering task and send out corresponding events. |
| void stopBufferingIfNecessary(); |
| // Make sure data source is getting data. |
| void ensureCacheIsFetching(); |
| // Update media time of just extracted buffer from data source. |
| void updateQueuedTime(bool isAudio, int64_t timeUs); |
| |
| // Set the offload mode. |
| void setOffloadAudio(bool offload); |
| // Update media time of last dequeued buffer which is sent to the decoder. |
| void updateDequeuedBufferTime(int64_t mediaUs); |
| |
| protected: |
| virtual ~BufferingMonitor(); |
| virtual void onMessageReceived(const sp<AMessage> &msg); |
| |
| private: |
| enum { |
| kWhatPollBuffering, |
| }; |
| |
| sp<AMessage> mNotify; |
| |
| sp<NuCachedSource2> mCachedSource; |
| sp<WVMExtractor> mWVMExtractor; |
| int64_t mDurationUs; |
| int64_t mBitrate; |
| bool mIsStreaming; |
| |
| int64_t mAudioTimeUs; |
| int64_t mVideoTimeUs; |
| int32_t mPollBufferingGeneration; |
| bool mPrepareBuffering; |
| bool mBuffering; |
| int32_t mPrevBufferPercentage; |
| |
| mutable Mutex mLock; |
| |
| bool mOffloadAudio; |
| int64_t mFirstDequeuedBufferRealUs; |
| int64_t mFirstDequeuedBufferMediaUs; |
| int64_t mlastDequeuedBufferMediaUs; |
| |
| void prepare_l(const sp<NuCachedSource2> &cachedSource, |
| const sp<WVMExtractor> &wvmExtractor, |
| int64_t durationUs, |
| int64_t bitrate, |
| bool isStreaming); |
| void cancelPollBuffering_l(); |
| void notifyBufferingUpdate_l(int32_t percentage); |
| void startBufferingIfNecessary_l(); |
| void stopBufferingIfNecessary_l(); |
| void sendCacheStats_l(); |
| void ensureCacheIsFetching_l(); |
| int64_t getLastReadPosition_l(); |
| void onPollBuffering_l(); |
| void schedulePollBuffering_l(); |
| }; |
| |
| Vector<sp<IMediaSource> > mSources; |
| Track mAudioTrack; |
| int64_t mAudioTimeUs; |
| int64_t mAudioLastDequeueTimeUs; |
| Track mVideoTrack; |
| int64_t mVideoTimeUs; |
| int64_t mVideoLastDequeueTimeUs; |
| Track mSubtitleTrack; |
| Track mTimedTextTrack; |
| |
| int32_t mFetchSubtitleDataGeneration; |
| int32_t mFetchTimedTextDataGeneration; |
| int64_t mDurationUs; |
| bool mAudioIsVorbis; |
| bool mIsWidevine; |
| bool mIsSecure; |
| bool mIsStreaming; |
| bool mUIDValid; |
| uid_t mUID; |
| sp<IMediaHTTPService> mHTTPService; |
| AString mUri; |
| KeyedVector<String8, String8> mUriHeaders; |
| int mFd; |
| int64_t mOffset; |
| int64_t mLength; |
| |
| sp<DataSource> mDataSource; |
| sp<NuCachedSource2> mCachedSource; |
| sp<DataSource> mHttpSource; |
| sp<WVMExtractor> mWVMExtractor; |
| sp<MetaData> mFileMeta; |
| DrmManagerClient *mDrmManagerClient; |
| sp<DecryptHandle> mDecryptHandle; |
| bool mStarted; |
| bool mStopRead; |
| int64_t mBitrate; |
| sp<BufferingMonitor> mBufferingMonitor; |
| uint32_t mPendingReadBufferTypes; |
| sp<ABuffer> mGlobalTimedText; |
| |
| mutable Mutex mReadBufferLock; |
| mutable Mutex mDisconnectLock; |
| |
| sp<ALooper> mLooper; |
| sp<ALooper> mBufferingMonitorLooper; |
| |
| void resetDataSource(); |
| |
| status_t initFromDataSource(); |
| void checkDrmStatus(const sp<DataSource>& dataSource); |
| int64_t getLastReadPosition(); |
| void setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position); |
| |
| void notifyPreparedAndCleanup(status_t err); |
| void onSecureDecodersInstantiated(status_t err); |
| void finishPrepareAsync(); |
| status_t startSources(); |
| |
| void onGetFormatMeta(sp<AMessage> msg) const; |
| sp<MetaData> doGetFormatMeta(bool audio) const; |
| |
| void onGetSelectedTrack(sp<AMessage> msg) const; |
| ssize_t doGetSelectedTrack(media_track_type type) const; |
| |
| void onSelectTrack(sp<AMessage> msg); |
| status_t doSelectTrack(size_t trackIndex, bool select, int64_t timeUs); |
| |
| void onSeek(sp<AMessage> msg); |
| status_t doSeek(int64_t seekTimeUs); |
| |
| void onPrepareAsync(); |
| |
| void fetchTextData( |
| uint32_t what, media_track_type type, |
| int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg); |
| |
| void sendGlobalTextData( |
| uint32_t what, |
| int32_t curGen, sp<AMessage> msg); |
| |
| void sendTextData( |
| uint32_t what, media_track_type type, |
| int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg); |
| |
| sp<ABuffer> mediaBufferToABuffer( |
| MediaBuffer *mbuf, |
| media_track_type trackType, |
| int64_t seekTimeUs, |
| int64_t *actualTimeUs = NULL); |
| |
| void postReadBuffer(media_track_type trackType); |
| void onReadBuffer(sp<AMessage> msg); |
| void readBuffer( |
| media_track_type trackType, |
| int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL, bool formatChange = false); |
| |
| void queueDiscontinuityIfNeeded( |
| bool seeking, bool formatChange, media_track_type trackType, Track *track); |
| |
| DISALLOW_EVIL_CONSTRUCTORS(GenericSource); |
| }; |
| |
| } // namespace android |
| |
| #endif // GENERIC_SOURCE_H_ |