123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- /*
- **
- ** Copyright 2008, 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 ANDROID_MEDIAPLAYERSERVICE_H
- #define ANDROID_MEDIAPLAYERSERVICE_H
- #include <arpa/inet.h>
- #include <utils/threads.h>
- #include <utils/Errors.h>
- #include <utils/KeyedVector.h>
- #include <utils/String8.h>
- #include <utils/Vector.h>
- #include <media/MediaPlayerInterface.h>
- #include <media/Metadata.h>
- #include <media/stagefright/foundation/ABase.h>
- #include <system/audio.h>
- namespace android {
- struct AudioPlaybackRate;
- class AudioTrack;
- struct AVSyncSettings;
- class DeathNotifier;
- class IDataSource;
- class IMediaRecorder;
- class IMediaMetadataRetriever;
- class IRemoteDisplay;
- class IRemoteDisplayClient;
- class MediaRecorderClient;
- #define CALLBACK_ANTAGONIZER 0
- #if CALLBACK_ANTAGONIZER
- class Antagonizer {
- public:
- Antagonizer(const sp<MediaPlayerBase::Listener> &listener);
- void start() { mActive = true; }
- void stop() { mActive = false; }
- void kill();
- private:
- static const int interval;
- Antagonizer();
- static int callbackThread(void* cookie);
- Mutex mLock;
- Condition mCondition;
- bool mExit;
- bool mActive;
- sp<MediaPlayerBase::Listener> mListener;
- };
- #endif
- class MediaPlayerService : public BnMediaPlayerService
- {
- class Client;
- class AudioOutput : public MediaPlayerBase::AudioSink
- {
- class CallbackData;
- public:
- AudioOutput(
- audio_session_t sessionId,
- uid_t uid,
- int pid,
- const audio_attributes_t * attr,
- const sp<AudioSystem::AudioDeviceCallback>& deviceCallback);
- virtual ~AudioOutput();
- virtual bool ready() const { return mTrack != 0; }
- virtual ssize_t bufferSize() const;
- virtual ssize_t frameCount() const;
- virtual ssize_t channelCount() const;
- virtual ssize_t frameSize() const;
- virtual uint32_t latency() const;
- virtual float msecsPerFrame() const;
- virtual status_t getPosition(uint32_t *position) const;
- virtual status_t getTimestamp(AudioTimestamp &ts) const;
- virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
- virtual status_t getFramesWritten(uint32_t *frameswritten) const;
- virtual audio_session_t getSessionId() const;
- virtual uint32_t getSampleRate() const;
- virtual int64_t getBufferDurationInUs() const;
- virtual status_t open(
- uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
- audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- const audio_offload_info_t *offloadInfo = NULL,
- bool doNotReconnect = false,
- uint32_t suggestedFrameCount = 0);
- virtual status_t start();
- virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
- virtual void stop();
- virtual void flush();
- virtual void pause();
- virtual void close();
- void setAudioStreamType(audio_stream_type_t streamType);
- virtual audio_stream_type_t getAudioStreamType() const { return mStreamType; }
- void setAudioAttributes(const audio_attributes_t * attributes);
- void setVolume(float left, float right);
- virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
- virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
- status_t setAuxEffectSendLevel(float level);
- status_t attachAuxEffect(int effectId);
- virtual status_t dump(int fd, const Vector<String16>& args) const;
- static bool isOnEmulator();
- static int getMinBufferCount();
- void setNextOutput(const sp<AudioOutput>& nextOutput);
- void switchToNextOutput();
- virtual bool needsTrailingPadding() { return mNextOutput == NULL; }
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual media::VolumeShaper::Status applyVolumeShaper(
- const sp<media::VolumeShaper::Configuration>& configuration,
- const sp<media::VolumeShaper::Operation>& operation) override;
- virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;
- // AudioRouting
- virtual status_t setOutputDevice(audio_port_handle_t deviceId);
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
- virtual status_t enableAudioDeviceCallback(bool enabled);
- private:
- static void setMinBufferCount();
- static void CallbackWrapper(
- int event, void *me, void *info);
- void deleteRecycledTrack_l();
- void close_l();
- status_t updateTrack();
- sp<AudioTrack> mTrack;
- sp<AudioTrack> mRecycledTrack;
- sp<AudioOutput> mNextOutput;
- AudioCallback mCallback;
- void * mCallbackCookie;
- CallbackData * mCallbackData;
- audio_stream_type_t mStreamType;
- audio_attributes_t * mAttributes;
- float mLeftVolume;
- float mRightVolume;
- AudioPlaybackRate mPlaybackRate;
- uint32_t mSampleRateHz; // sample rate of the content, as set in open()
- float mMsecsPerFrame;
- size_t mFrameSize;
- audio_session_t mSessionId;
- uid_t mUid;
- int mPid;
- float mSendLevel;
- int mAuxEffectId;
- audio_output_flags_t mFlags;
- sp<media::VolumeHandler> mVolumeHandler;
- audio_port_handle_t mSelectedDeviceId;
- audio_port_handle_t mRoutedDeviceId;
- bool mDeviceCallbackEnabled;
- wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
- mutable Mutex mLock;
- // static variables below not protected by mutex
- static bool mIsOnEmulator;
- static int mMinBufferCount; // 12 for emulator; otherwise 4
- // CallbackData is what is passed to the AudioTrack as the "user" data.
- // We need to be able to target this to a different Output on the fly,
- // so we can't use the Output itself for this.
- class CallbackData {
- friend AudioOutput;
- public:
- explicit CallbackData(AudioOutput *cookie) {
- mData = cookie;
- mSwitching = false;
- }
- AudioOutput * getOutput() const { return mData; }
- void setOutput(AudioOutput* newcookie) { mData = newcookie; }
- // lock/unlock are used by the callback before accessing the payload of this object
- void lock() const { mLock.lock(); }
- void unlock() const { mLock.unlock(); }
- // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
- // to the next sink.
- // tryBeginTrackSwitch() returns true only if it obtains the lock.
- bool tryBeginTrackSwitch() {
- LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
- if (mLock.tryLock() != OK) {
- return false;
- }
- mSwitching = true;
- return true;
- }
- void endTrackSwitch() {
- if (mSwitching) {
- mLock.unlock();
- }
- mSwitching = false;
- }
- private:
- AudioOutput * mData;
- mutable Mutex mLock; // a recursive mutex might make this unnecessary.
- bool mSwitching;
- DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
- };
- }; // AudioOutput
- public:
- static void instantiate();
- // IMediaPlayerService interface
- virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName);
- void removeMediaRecorderClient(const wp<MediaRecorderClient>& client);
- virtual sp<IMediaMetadataRetriever> createMetadataRetriever();
- virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client,
- audio_session_t audioSessionId);
- virtual sp<IMediaCodecList> getCodecList() const;
- virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
- const sp<IRemoteDisplayClient>& client, const String8& iface);
- virtual status_t dump(int fd, const Vector<String16>& args);
- void removeClient(const wp<Client>& client);
- bool hasClient(wp<Client> client);
- enum {
- MEDIASERVER_PROCESS_DEATH = 0,
- MEDIAEXTRACTOR_PROCESS_DEATH = 1,
- MEDIACODEC_PROCESS_DEATH = 2,
- AUDIO_PROCESS_DEATH = 3, // currently no need to track this
- CAMERA_PROCESS_DEATH = 4
- };
- // Collect info of the codec usage from media player and media recorder
- virtual void addBatteryData(uint32_t params);
- // API for the Battery app to pull the data of codecs usage
- virtual status_t pullBatteryData(Parcel* reply);
- private:
- struct BatteryTracker {
- BatteryTracker();
- // Collect info of the codec usage from media player and media recorder
- void addBatteryData(uint32_t params);
- // API for the Battery app to pull the data of codecs usage
- status_t pullBatteryData(Parcel* reply);
- private:
- // For battery usage tracking purpose
- struct BatteryUsageInfo {
- // how many streams are being played by one UID
- int refCount;
- // a temp variable to store the duration(ms) of audio codecs
- // when we start a audio codec, we minus the system time from audioLastTime
- // when we pause it, we add the system time back to the audioLastTime
- // so after the pause, audioLastTime = pause time - start time
- // if multiple audio streams are played (or recorded), then audioLastTime
- // = the total playing time of all the streams
- int32_t audioLastTime;
- // when all the audio streams are being paused, we assign audioLastTime to
- // this variable, so this value could be provided to the battery app
- // in the next pullBatteryData call
- int32_t audioTotalTime;
- int32_t videoLastTime;
- int32_t videoTotalTime;
- };
- KeyedVector<int, BatteryUsageInfo> mBatteryData;
- enum {
- SPEAKER,
- OTHER_AUDIO_DEVICE,
- SPEAKER_AND_OTHER,
- NUM_AUDIO_DEVICES
- };
- struct BatteryAudioFlingerUsageInfo {
- int refCount; // how many audio streams are being played
- int deviceOn[NUM_AUDIO_DEVICES]; // whether the device is currently used
- int32_t lastTime[NUM_AUDIO_DEVICES]; // in ms
- // totalTime[]: total time of audio output devices usage
- int32_t totalTime[NUM_AUDIO_DEVICES]; // in ms
- };
- // This varialble is used to record the usage of audio output device
- // for battery app
- BatteryAudioFlingerUsageInfo mBatteryAudio;
- mutable Mutex mLock;
- };
- BatteryTracker mBatteryTracker;
- class Client : public BnMediaPlayer {
- // IMediaPlayer interface
- virtual void disconnect();
- virtual status_t setVideoSurfaceTexture(
- const sp<IGraphicBufferProducer>& bufferProducer);
- virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
- virtual status_t getBufferingSettings(
- BufferingSettings* buffering /* nonnull */) override;
- virtual status_t prepareAsync();
- virtual status_t start();
- virtual status_t stop();
- virtual status_t pause();
- virtual status_t isPlaying(bool* state);
- virtual status_t setPlaybackSettings(const AudioPlaybackRate& rate);
- virtual status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
- virtual status_t setSyncSettings(const AVSyncSettings& rate, float videoFpsHint);
- virtual status_t getSyncSettings(AVSyncSettings* rate /* nonnull */,
- float* videoFps /* nonnull */);
- virtual status_t seekTo(
- int msec,
- MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC);
- virtual status_t getCurrentPosition(int* msec);
- virtual status_t getDuration(int* msec);
- virtual status_t reset();
- virtual status_t notifyAt(int64_t mediaTimeUs);
- virtual status_t setAudioStreamType(audio_stream_type_t type);
- virtual status_t setLooping(int loop);
- virtual status_t setVolume(float leftVolume, float rightVolume);
- virtual status_t invoke(const Parcel& request, Parcel *reply);
- virtual status_t setMetadataFilter(const Parcel& filter);
- virtual status_t getMetadata(bool update_only,
- bool apply_filter,
- Parcel *reply);
- virtual status_t setAuxEffectSendLevel(float level);
- virtual status_t attachAuxEffect(int effectId);
- virtual status_t setParameter(int key, const Parcel &request);
- virtual status_t getParameter(int key, Parcel *reply);
- virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint);
- virtual status_t getRetransmitEndpoint(struct sockaddr_in* endpoint);
- virtual status_t setNextPlayer(const sp<IMediaPlayer>& player);
- virtual media::VolumeShaper::Status applyVolumeShaper(
- const sp<media::VolumeShaper::Configuration>& configuration,
- const sp<media::VolumeShaper::Operation>& operation) override;
- virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;
- sp<MediaPlayerBase> createPlayer(player_type playerType);
- virtual status_t setDataSource(
- const sp<IMediaHTTPService> &httpService,
- const char *url,
- const KeyedVector<String8, String8> *headers);
- virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
- virtual status_t setDataSource(const sp<IStreamSource> &source);
- virtual status_t setDataSource(const sp<IDataSource> &source);
- sp<MediaPlayerBase> setDataSource_pre(player_type playerType);
- status_t setDataSource_post(const sp<MediaPlayerBase>& p,
- status_t status);
- void notify(int msg, int ext1, int ext2, const Parcel *obj);
- pid_t pid() const { return mPid; }
- virtual status_t dump(int fd, const Vector<String16>& args);
- audio_session_t getAudioSessionId() { return mAudioSessionId; }
- // Modular DRM
- virtual status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId);
- virtual status_t releaseDrm();
- // AudioRouting
- virtual status_t setOutputDevice(audio_port_handle_t deviceId);
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
- virtual status_t enableAudioDeviceCallback(bool enabled);
- private:
- class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
- {
- public:
- AudioDeviceUpdatedNotifier(const sp<MediaPlayerBase>& listener) {
- mListener = listener;
- }
- ~AudioDeviceUpdatedNotifier() {}
- virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId);
- private:
- wp<MediaPlayerBase> mListener;
- };
- friend class MediaPlayerService;
- Client( const sp<MediaPlayerService>& service,
- pid_t pid,
- int32_t connId,
- const sp<IMediaPlayerClient>& client,
- audio_session_t audioSessionId,
- uid_t uid);
- Client();
- virtual ~Client();
- void deletePlayer();
- sp<MediaPlayerBase> getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; }
- // @param type Of the metadata to be tested.
- // @return true if the metadata should be dropped according to
- // the filters.
- bool shouldDropMetadata(media::Metadata::Type type) const;
- // Add a new element to the set of metadata updated. Noop if
- // the element exists already.
- // @param type Of the metadata to be recorded.
- void addNewMetadataUpdate(media::Metadata::Type type);
- // Disconnect from the currently connected ANativeWindow.
- void disconnectNativeWindow_l();
- status_t setAudioAttributes_l(const Parcel &request);
- class Listener : public MediaPlayerBase::Listener {
- public:
- Listener(const wp<Client> &client) : mClient(client) {}
- virtual ~Listener() {}
- virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
- sp<Client> client = mClient.promote();
- if (client != NULL) {
- client->notify(msg, ext1, ext2, obj);
- }
- }
- private:
- wp<Client> mClient;
- };
- mutable Mutex mLock;
- sp<MediaPlayerBase> mPlayer;
- sp<MediaPlayerService> mService;
- sp<IMediaPlayerClient> mClient;
- sp<AudioOutput> mAudioOutput;
- pid_t mPid;
- status_t mStatus;
- bool mLoop;
- int32_t mConnId;
- audio_session_t mAudioSessionId;
- audio_attributes_t * mAudioAttributes;
- uid_t mUid;
- sp<ANativeWindow> mConnectedWindow;
- sp<IBinder> mConnectedWindowBinder;
- struct sockaddr_in mRetransmitEndpoint;
- bool mRetransmitEndpointValid;
- sp<Client> mNextClient;
- sp<MediaPlayerBase::Listener> mListener;
- // Metadata filters.
- media::Metadata::Filter mMetadataAllow; // protected by mLock
- media::Metadata::Filter mMetadataDrop; // protected by mLock
- // Metadata updated. For each MEDIA_INFO_METADATA_UPDATE
- // notification we try to update mMetadataUpdated which is a
- // set: no duplicate.
- // getMetadata clears this set.
- media::Metadata::Filter mMetadataUpdated; // protected by mLock
- std::vector<DeathNotifier> mDeathNotifiers;
- sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedListener;
- #if CALLBACK_ANTAGONIZER
- Antagonizer* mAntagonizer;
- #endif
- }; // Client
- // ----------------------------------------------------------------------------
- MediaPlayerService();
- virtual ~MediaPlayerService();
- mutable Mutex mLock;
- SortedVector< wp<Client> > mClients;
- SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
- int32_t mNextConnId;
- };
- // ----------------------------------------------------------------------------
- }; // namespace android
- #endif // ANDROID_MEDIAPLAYERSERVICE_H
|