blob: 0e58ec2dbd54b91401b44d1b6538cccecd8aaff7 [file] [log] [blame]
/*
* Copyright (C) 2010 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 NU_PLAYER_H_
#define NU_PLAYER_H_
#include <media/AudioResamplerPublic.h>
#include <mediadrm/ICrypto.h>
#include <media/MediaPlayerInterface.h>
#include <media/stagefright/foundation/AHandler.h>
namespace android {
struct ABuffer;
struct AMessage;
struct AudioPlaybackRate;
struct AVSyncSettings;
class IDataSource;
struct MediaClock;
class MetaData;
struct NuPlayerDriver;
struct NuPlayer : public AHandler {
explicit NuPlayer(pid_t pid, const sp<MediaClock> &mediaClock);
void setUID(uid_t uid);
void init(const wp<NuPlayerDriver> &driver);
void setDataSourceAsync(const sp<IStreamSource> &source);
void setDataSourceAsync(
const sp<IMediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers);
void setDataSourceAsync(int fd, int64_t offset, int64_t length);
void setDataSourceAsync(const sp<DataSource> &source);
status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */);
status_t setBufferingSettings(const BufferingSettings& buffering);
void prepareAsync();
void setVideoSurfaceTextureAsync(
const sp<IGraphicBufferProducer> &bufferProducer);
void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
status_t setPlaybackSettings(const AudioPlaybackRate &rate);
status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
void start();
void pause();
// Will notify the driver through "notifyResetComplete" once finished.
void resetAsync();
// Request a notification when specified media time is reached.
status_t notifyAt(int64_t mediaTimeUs);
// Will notify the driver through "notifySeekComplete" once finished
// and needNotify is true.
void seekToAsync(
int64_t seekTimeUs,
MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC,
bool needNotify = false);
status_t setVideoScalingMode(int32_t mode);
status_t getTrackInfo(Parcel* reply) const;
status_t getSelectedTrack(int32_t type, Parcel* reply) const;
status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
status_t getCurrentPosition(int64_t *mediaUs);
void getStats(Vector<sp<AMessage> > *trackStats);
sp<MetaData> getFileMeta();
float getFrameRate();
// Modular DRM
status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
status_t releaseDrm();
const char *getDataSourceType();
void updateInternalTimers();
protected:
virtual ~NuPlayer();
virtual void onMessageReceived(const sp<AMessage> &msg);
public:
struct NuPlayerStreamListener;
struct Source;
private:
struct Decoder;
struct DecoderBase;
struct DecoderPassThrough;
struct CCDecoder;
struct GenericSource;
struct HTTPLiveSource;
struct Renderer;
struct RTSPSource;
struct StreamingSource;
struct Action;
struct SeekAction;
struct SetSurfaceAction;
struct ResumeDecoderAction;
struct FlushDecoderAction;
struct PostMessageAction;
struct SimpleAction;
enum {
kWhatSetDataSource = '=DaS',
kWhatPrepare = 'prep',
kWhatSetVideoSurface = '=VSu',
kWhatSetAudioSink = '=AuS',
kWhatMoreDataQueued = 'more',
kWhatConfigPlayback = 'cfPB',
kWhatConfigSync = 'cfSy',
kWhatGetPlaybackSettings = 'gPbS',
kWhatGetSyncSettings = 'gSyS',
kWhatStart = 'strt',
kWhatScanSources = 'scan',
kWhatVideoNotify = 'vidN',
kWhatAudioNotify = 'audN',
kWhatClosedCaptionNotify = 'capN',
kWhatRendererNotify = 'renN',
kWhatReset = 'rset',
kWhatNotifyTime = 'nfyT',
kWhatSeek = 'seek',
kWhatPause = 'paus',
kWhatResume = 'rsme',
kWhatPollDuration = 'polD',
kWhatSourceNotify = 'srcN',
kWhatGetTrackInfo = 'gTrI',
kWhatGetSelectedTrack = 'gSel',
kWhatSelectTrack = 'selT',
kWhatGetBufferingSettings = 'gBus',
kWhatSetBufferingSettings = 'sBuS',
kWhatPrepareDrm = 'pDrm',
kWhatReleaseDrm = 'rDrm',
kWhatMediaClockNotify = 'mckN',
};
wp<NuPlayerDriver> mDriver;
bool mUIDValid;
uid_t mUID;
pid_t mPID;
const sp<MediaClock> mMediaClock;
Mutex mSourceLock; // guard |mSource|.
sp<Source> mSource;
uint32_t mSourceFlags;
sp<Surface> mSurface;
sp<MediaPlayerBase::AudioSink> mAudioSink;
sp<DecoderBase> mVideoDecoder;
bool mOffloadAudio;
sp<DecoderBase> mAudioDecoder;
Mutex mDecoderLock; // guard |mAudioDecoder| and |mVideoDecoder|.
sp<CCDecoder> mCCDecoder;
sp<Renderer> mRenderer;
sp<ALooper> mRendererLooper;
int32_t mAudioDecoderGeneration;
int32_t mVideoDecoderGeneration;
int32_t mRendererGeneration;
Mutex mPlayingTimeLock;
int64_t mLastStartedPlayingTimeNs;
void updatePlaybackTimer(bool stopping, const char *where);
void startPlaybackTimer(const char *where);
int64_t mLastStartedRebufferingTimeNs;
void startRebufferingTimer();
void updateRebufferingTimer(bool stopping, bool exitingPlayback);
int64_t mPreviousSeekTimeUs;
List<sp<Action> > mDeferredActions;
bool mAudioEOS;
bool mVideoEOS;
bool mScanSourcesPending;
int32_t mScanSourcesGeneration;
int32_t mPollDurationGeneration;
int32_t mTimedTextGeneration;
enum FlushStatus {
NONE,
FLUSHING_DECODER,
FLUSHING_DECODER_SHUTDOWN,
SHUTTING_DOWN_DECODER,
FLUSHED,
SHUT_DOWN,
};
enum FlushCommand {
FLUSH_CMD_NONE,
FLUSH_CMD_FLUSH,
FLUSH_CMD_SHUTDOWN,
};
// Status of flush responses from the decoder and renderer.
bool mFlushComplete[2][2];
FlushStatus mFlushingAudio;
FlushStatus mFlushingVideo;
// Status of flush responses from the decoder and renderer.
bool mResumePending;
int32_t mVideoScalingMode;
AudioPlaybackRate mPlaybackSettings;
AVSyncSettings mSyncSettings;
float mVideoFpsHint;
bool mStarted;
bool mPrepared;
bool mResetting;
bool mSourceStarted;
bool mAudioDecoderError;
bool mVideoDecoderError;
// Actual pause state, either as requested by client or due to buffering.
bool mPaused;
// Pause state as requested by client. Note that if mPausedByClient is
// true, mPaused is always true; if mPausedByClient is false, mPaused could
// still become true, when we pause internally due to buffering.
bool mPausedByClient;
// Pause state as requested by source (internally) due to buffering
bool mPausedForBuffering;
// Modular DRM
sp<ICrypto> mCrypto;
bool mIsDrmProtected;
typedef enum {
DATA_SOURCE_TYPE_NONE,
DATA_SOURCE_TYPE_HTTP_LIVE,
DATA_SOURCE_TYPE_RTSP,
DATA_SOURCE_TYPE_GENERIC_URL,
DATA_SOURCE_TYPE_GENERIC_FD,
DATA_SOURCE_TYPE_MEDIA,
DATA_SOURCE_TYPE_STREAM,
} DATA_SOURCE_TYPE;
std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
inline const sp<DecoderBase> &getDecoder(bool audio) {
return audio ? mAudioDecoder : mVideoDecoder;
}
inline void clearFlushComplete() {
mFlushComplete[0][0] = false;
mFlushComplete[0][1] = false;
mFlushComplete[1][0] = false;
mFlushComplete[1][1] = false;
}
void tryOpenAudioSinkForOffload(
const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo);
void closeAudioSink();
void restartAudio(
int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder);
void determineAudioModeChange(const sp<AMessage> &audioFormat);
status_t instantiateDecoder(
bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange = true);
status_t onInstantiateSecureDecoders();
void updateVideoSize(
const sp<AMessage> &inputFormat,
const sp<AMessage> &outputFormat = NULL);
void notifyListener(int msg, int ext1, int ext2, const Parcel *in = NULL);
void handleFlushComplete(bool audio, bool isDecoder);
void finishFlushIfPossible();
void onStart(
int64_t startPositionUs = -1,
MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC);
void onResume();
void onPause();
bool audioDecoderStillNeeded();
void flushDecoder(bool audio, bool needShutdown);
void finishResume();
void notifyDriverSeekComplete();
void postScanSources();
void schedulePollDuration();
void cancelPollDuration();
void processDeferredActions();
void performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode);
void performDecoderFlush(FlushCommand audio, FlushCommand video);
void performReset();
void performScanSources();
void performSetSurface(const sp<Surface> &wrapper);
void performResumeDecoders(bool needNotify);
void onSourceNotify(const sp<AMessage> &msg);
void onClosedCaptionNotify(const sp<AMessage> &msg);
void queueDecoderShutdown(
bool audio, bool video, const sp<AMessage> &reply);
void sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex);
void sendTimedMetaData(const sp<ABuffer> &buffer);
void sendTimedTextData(const sp<ABuffer> &buffer);
void writeTrackInfo(Parcel* reply, const sp<AMessage>& format) const;
status_t onPrepareDrm(const sp<AMessage> &msg);
status_t onReleaseDrm();
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
};
} // namespace android
#endif // NU_PLAYER_H_