/* * 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; struct AnotherPacketSource; struct ARTSPController; class DataSource; class IDataSource; struct IMediaHTTPService; struct MediaSource; class MediaBuffer; struct NuCachedSource2; struct NuPlayer::GenericSource : public NuPlayer::Source, public MediaBufferObserver // Modular DRM { 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 status_t getDefaultBufferingSettings( BufferingSettings* buffering /* nonnull */) override; virtual status_t setBufferingSettings(const BufferingSettings& buffering) override; 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, MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC) override; virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers); virtual bool isStreaming() const; virtual void setOffloadAudio(bool offload); // Modular DRM virtual void signalBufferReturned(MediaBuffer *buffer); virtual status_t prepareDrm( const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId, sp<ICrypto> *crypto); virtual status_t releaseDrm(); 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, kWhatStart, kWhatResume, kWhatSecureDecodersInstantiated, // Modular DRM kWhatPrepareDrm, kWhatReleaseDrm, }; 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: explicit BufferingMonitor(const sp<AMessage> ¬ify); void getDefaultBufferingSettings(BufferingSettings *buffering /* nonnull */); status_t setBufferingSettings(const BufferingSettings &buffering); // Set up state. void prepare(const sp<NuCachedSource2> &cachedSource, 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; 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; BufferingSettings mSettings; bool mOffloadAudio; int64_t mFirstDequeuedBufferRealUs; int64_t mFirstDequeuedBufferMediaUs; int64_t mlastDequeuedBufferMediaUs; void prepare_l(const sp<NuCachedSource2> &cachedSource, 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; // Secure codec is required. 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<MetaData> mFileMeta; 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(); int64_t getLastReadPosition(); void notifyPreparedAndCleanup(status_t err); void onSecureDecodersInstantiated(status_t err); void finishPrepareAsync(); status_t startSources(); void onGetFormatMeta(const sp<AMessage>& msg) const; sp<MetaData> doGetFormatMeta(bool audio) const; void onGetTrackInfo(const sp<AMessage>& msg) const; sp<AMessage> doGetTrackInfo(size_t trackIndex) const; void onGetSelectedTrack(const sp<AMessage>& msg) const; ssize_t doGetSelectedTrack(media_track_type type) const; void onSelectTrack(const sp<AMessage>& msg); status_t doSelectTrack(size_t trackIndex, bool select, int64_t timeUs); void onSeek(const sp<AMessage>& msg); status_t doSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode); void onPrepareAsync(); void fetchTextData( uint32_t what, media_track_type type, int32_t curGen, const sp<AnotherPacketSource>& packets, const 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, const sp<AnotherPacketSource>& packets, const sp<AMessage>& msg); sp<ABuffer> mediaBufferToABuffer( MediaBuffer *mbuf, media_track_type trackType); void postReadBuffer(media_track_type trackType); void onReadBuffer(const sp<AMessage>& msg); // When |mode| is MediaPlayerSeekMode::SEEK_CLOSEST, the buffer read shall // include an item indicating skipping rendering all buffers with timestamp // earlier than |seekTimeUs|. // For other modes, the buffer read will not include the item as above in order // to facilitate fast seek operation. void readBuffer( media_track_type trackType, int64_t seekTimeUs = -1ll, MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC, int64_t *actualTimeUs = NULL, bool formatChange = false); void queueDiscontinuityIfNeeded( bool seeking, bool formatChange, media_track_type trackType, Track *track); // Modular DRM // The source is DRM protected and is prepared for DRM. bool mIsDrmProtected; // releaseDrm has been processed. bool mIsDrmReleased; Vector<String8> mMimes; status_t checkDrmInfo(); status_t onPrepareDrm(const sp<AMessage> &msg); status_t onReleaseDrm(); DISALLOW_EVIL_CONSTRUCTORS(GenericSource); }; } // namespace android #endif // GENERIC_SOURCE_H_