/*
* Copyright (C) 2007 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_MEDIAPLAYER_H
#define ANDROID_MEDIAPLAYER_H
#include <utils/IMemory.h>
#include <ui/Surface.h>
#include <media/IMediaPlayerClient.h>
#include <media/IMediaPlayer.h>
#include <media/IMediaPlayerService.h>
#include <utils/SortedVector.h>
namespace android {
enum media_event_type {
MEDIA_NOP = 0, // interface test message
MEDIA_PREPARED = 1,
MEDIA_PLAYBACK_COMPLETE = 2,
MEDIA_BUFFERING_UPDATE = 3,
MEDIA_SEEK_COMPLETE = 4,
MEDIA_SET_VIDEO_SIZE = 5,
MEDIA_ERROR = 100,
MEDIA_INFO = 200,
};
// Generic error codes for the media player framework. Errors are fatal, the
// playback must abort.
//
// Errors are communicated back to the client using the
// MediaPlayerListener::notify method defined below.
// In this situation, 'notify' is invoked with the following:
// 'msg' is set to MEDIA_ERROR.
// 'ext1' should be a value from the enum media_error_type.
// 'ext2' contains an implementation dependant error code to provide
// more details. Should default to 0 when not used.
//
// The codes are distributed as follow:
// 0xx: Reserved
// 1xx: Android Player errors. Something went wrong inside the MediaPlayer.
// 2xx: Media errors (e.g Codec not supported). There is a problem with the
// media itself.
// 3xx: Runtime errors. Some extraordinary condition arose making the playback
// impossible.
//
enum media_error_type {
// 0xx
MEDIA_ERROR_UNKNOWN = 1,
// 1xx
MEDIA_ERROR_SERVER_DIED = 100,
// 2xx
MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200,
// 3xx
};
// Info and warning codes for the media player framework. These are non fatal,
// the playback is going on but there might be some user visible issues.
//
// Info and warning messages are communicated back to the client using the
// MediaPlayerListener::notify method defined below. In this situation,
// 'notify' is invoked with the following:
// 'msg' is set to MEDIA_INFO.
// 'ext1' should be a value from the enum media_info_type.
// 'ext2' contains an implementation dependant error code to provide
// more details. Should default to 0 when not used.
//
// The codes are distributed as follow:
// 0xx: Reserved
// 7xx: Android Player info/warning (e.g player lagging behind.)
// 8xx: Media info/warning (e.g media badly interleaved.)
//
enum media_info_type {
// 0xx
MEDIA_INFO_UNKNOWN = 1,
// 7xx
// The video is too complex for the decoder: it can't decode frames fast
// enough. Possibly only the audio plays fine at this stage.
MEDIA_INFO_VIDEO_TRACK_LAGGING = 700,
// 8xx
// Bad interleaving means that a media has been improperly interleaved or not
// interleaved at all, e.g has all the video samples first then all the audio
// ones. Video is playing but a lot of disk seek may be happening.
MEDIA_INFO_BAD_INTERLEAVING = 800,
// The media is not seekable (e.g live stream).
MEDIA_INFO_NOT_SEEKABLE = 801,
};
enum media_player_states {
MEDIA_PLAYER_STATE_ERROR = 0,
MEDIA_PLAYER_IDLE = 1 << 0,
MEDIA_PLAYER_INITIALIZED = 1 << 1,
MEDIA_PLAYER_PREPARING = 1 << 2,
MEDIA_PLAYER_PREPARED = 1 << 3,
MEDIA_PLAYER_STARTED = 1 << 4,
MEDIA_PLAYER_PAUSED = 1 << 5,
MEDIA_PLAYER_STOPPED = 1 << 6,
MEDIA_PLAYER_PLAYBACK_COMPLETE = 1 << 7
};
// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class MediaPlayerListener: virtual public RefBase
{
public:
virtual void notify(int msg, int ext1, int ext2) = 0;
};
class MediaPlayer : public BnMediaPlayerClient
{
public:
MediaPlayer();
~MediaPlayer();
void onFirstRef();
void disconnect();
status_t setDataSource(const char *url);
status_t setDataSource(int fd, int64_t offset, int64_t length);
status_t setVideoSurface(const sp<Surface>& surface);
status_t setListener(const sp<MediaPlayerListener>& listener);
status_t prepare();
status_t prepareAsync();
status_t start();
status_t stop();
status_t pause();
bool isPlaying();
status_t getVideoWidth(int *w);
status_t getVideoHeight(int *h);
status_t seekTo(int msec);
status_t getCurrentPosition(int *msec);
status_t getDuration(int *msec);
status_t reset();
status_t setAudioStreamType(int type);
status_t setLooping(int loop);
bool isLooping();
status_t setVolume(float leftVolume, float rightVolume);
void notify(int msg, int ext1, int ext2);
static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
private:
void clear_l();
status_t seekTo_l(int msec);
status_t prepareAsync_l();
status_t getDuration_l(int *msec);
status_t setDataSource(const sp<IMediaPlayer>& player);
static const sp<IMediaPlayerService>& getMediaPlayerService();
static void addObitRecipient(const wp<MediaPlayer>& recipient);
static void removeObitRecipient(const wp<MediaPlayer>& recipient);
class DeathNotifier: public IBinder::DeathRecipient
{
public:
DeathNotifier() {}
virtual ~DeathNotifier();
virtual void binderDied(const wp<IBinder>& who);
};
sp<IMediaPlayer> mPlayer;
thread_id_t mLockThreadId;
Mutex mLock;
Mutex mNotifyLock;
Condition mSignal;
sp<MediaPlayerListener> mListener;
void* mCookie;
media_player_states mCurrentState;
int mDuration;
int mCurrentPosition;
int mSeekPosition;
bool mPrepareSync;
status_t mPrepareStatus;
int mStreamType;
bool mLoop;
float mLeftVolume;
float mRightVolume;
int mVideoWidth;
int mVideoHeight;
friend class DeathNotifier;
static Mutex sServiceLock;
static sp<IMediaPlayerService> sMediaPlayerService;
static sp<DeathNotifier> sDeathNotifier;
static SortedVector< wp<MediaPlayer> > sObitRecipients;
};
}; // namespace android
#endif // ANDROID_MEDIAPLAYER_H