316 lines
9.8 KiB
C++
316 lines
9.8 KiB
C++
/*
|
|
* 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.
|
|
*
|
|
* This file was modified by Dolby Laboratories, Inc. The portions of the
|
|
* code that are surrounded by "DOLBY..." are copyrighted and
|
|
* licensed separately, as follows:
|
|
*
|
|
* (C) 2015-2016 Dolby Laboratories, Inc.
|
|
*
|
|
* 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 <media/MediaPlayerInterface.h>
|
|
#include <media/stagefright/foundation/AHandler.h>
|
|
|
|
namespace android {
|
|
|
|
struct ABuffer;
|
|
struct AMessage;
|
|
struct AudioPlaybackRate;
|
|
struct AVSyncSettings;
|
|
class IDataSource;
|
|
class MetaData;
|
|
struct NuPlayerDriver;
|
|
|
|
struct NuPlayer : public AHandler {
|
|
NuPlayer(pid_t pid);
|
|
|
|
void setUID(uid_t uid);
|
|
|
|
void setDriver(const wp<NuPlayerDriver> &driver);
|
|
|
|
void setDataSourceAsync(const sp<IStreamSource> &source);
|
|
|
|
virtual 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);
|
|
|
|
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();
|
|
|
|
// Will notify the driver through "notifySeekComplete" once finished
|
|
// and needNotify is true.
|
|
void seekToAsync(int64_t seekTimeUs, 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> > *mTrackStats);
|
|
|
|
sp<MetaData> getFileMeta();
|
|
float getFrameRate();
|
|
|
|
protected:
|
|
virtual ~NuPlayer();
|
|
|
|
virtual void onMessageReceived(const sp<AMessage> &msg);
|
|
virtual bool ifDecodedPCMOffload() {return false;}
|
|
virtual void setDecodedPcmOffload(bool /*decodePcmOffload*/) {}
|
|
virtual bool canOffloadDecodedPCMStream(const sp<MetaData> /*meta*/,
|
|
bool /*hasVideo*/, bool /*isStreaming*/, audio_stream_type_t /*streamType*/) {return false;}
|
|
static bool IsHTTPLiveURL(const char *url);
|
|
public:
|
|
struct NuPlayerStreamListener;
|
|
struct Source;
|
|
|
|
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;
|
|
|
|
protected:
|
|
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',
|
|
kWhatSeek = 'seek',
|
|
kWhatPause = 'paus',
|
|
kWhatResume = 'rsme',
|
|
kWhatPollDuration = 'polD',
|
|
kWhatSourceNotify = 'srcN',
|
|
kWhatGetTrackInfo = 'gTrI',
|
|
kWhatGetSelectedTrack = 'gSel',
|
|
kWhatSelectTrack = 'selT',
|
|
};
|
|
|
|
wp<NuPlayerDriver> mDriver;
|
|
bool mUIDValid;
|
|
uid_t mUID;
|
|
pid_t mPID;
|
|
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;
|
|
sp<CCDecoder> mCCDecoder;
|
|
sp<Renderer> mRenderer;
|
|
sp<ALooper> mRendererLooper;
|
|
int32_t mAudioDecoderGeneration;
|
|
int32_t mVideoDecoderGeneration;
|
|
int32_t mRendererGeneration;
|
|
|
|
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;
|
|
|
|
// 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;
|
|
|
|
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);
|
|
|
|
virtual 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);
|
|
void onResume();
|
|
void onPause();
|
|
|
|
bool audioDecoderStillNeeded();
|
|
|
|
void flushDecoder(bool audio, bool needShutdown);
|
|
|
|
void finishResume();
|
|
void notifyDriverSeekComplete();
|
|
|
|
void postScanSources();
|
|
|
|
void schedulePollDuration();
|
|
void cancelPollDuration();
|
|
|
|
void processDeferredActions();
|
|
|
|
virtual void performSeek(int64_t seekTimeUs);
|
|
void performDecoderFlush(FlushCommand audio, FlushCommand video);
|
|
void performReset();
|
|
void performScanSources();
|
|
void performSetSurface(const sp<Surface> &wrapper);
|
|
void performResumeDecoders(bool needNotify);
|
|
|
|
virtual 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;
|
|
#ifdef DOLBY_ENABLE
|
|
void onDolbyMessageReceived();
|
|
#endif // DOLBY_END
|
|
|
|
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
|
|
};
|
|
|
|
} // namespace android
|
|
|
|
#endif // NU_PLAYER_H_
|