#define LOG_TAG "playerDemo"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <CedarMediaPlayer.h>
#include <CedarDisplay.h>
#include <ProcessState.h>
#include <IPCThreadState.h>
using namespace android;
#define gsmLoge(fmt, arg...) ALOGE("\033[40;31m" "<F:%s, L:%u> " fmt "\033[0m", __FUNCTION__, __LINE__, ##arg)
#define gsmLogw(fmt, arg...) ALOGW("\033[40;33m" "<F:%s, L:%u> " fmt "\033[0m", __FUNCTION__, __LINE__, ##arg)
#define gsmLogi(fmt, arg...) ALOGI("\033[40;36m" "<F:%s, L:%u> " fmt "\033[0m", __FUNCTION__, __LINE__, ##arg)
#define gsmLogd(fmt, arg...) ALOGD("\033[40;36m" "<F:%s, L:%u> " fmt "\033[0m", __FUNCTION__, __LINE__, ##arg)
#define gsmLogv(fmt, arg...) ALOGV("\033[40;36m" "<F:%s, L:%u> " fmt "\033[0m", __FUNCTION__, __LINE__, ##arg)
enum PlayerDemoStates {
PLAYER_DEMO_STATE_ERROR = 0,
PLAYER_DEMO_IDLE,
PLAYER_DEMO_INITIALIZED,
PLAYER_DEMO_PREPARING,
PLAYER_DEMO_PREPARED,
PLAYER_DEMO_STARTED,
PLAYER_DEMO_PAUSED,
PLAYER_DEMO_STOPPED,
PLAYER_DEMO_PLAYBACK_COMPLETE,
};
class PlayerDemo {
public:
PlayerDemo();
~PlayerDemo();
status_t initialize();
status_t destroy();
status_t setDisplay();
status_t prepareToPlay(String8 path);
status_t start();
status_t stop();
status_t pause();
status_t seek(int msec);
status_t release();
status_t reset();
int getDurationMs();
int getCurrentPosMs();
PlayerDemoStates getCurrentStates(){return mCurrentStates;}
void setCurrentStates(PlayerDemoStates state){mCurrentStates = state;}
class PlayerListener
: public CedarMediaPlayer::OnPreparedListener
, public CedarMediaPlayer::OnCompletionListener
, public CedarMediaPlayer::OnErrorListener
, public CedarMediaPlayer::OnVideoSizeChangedListener
, public CedarMediaPlayer::OnInfoListener
, public CedarMediaPlayer::OnSeekCompleteListener
, public CedarMediaPlayer::OnBufferingUpdateListener
{
public:
PlayerListener(PlayerDemo *player){mpPlayerDemo = player;}
~PlayerListener(){}
void onPrepared(CedarMediaPlayer *pMp);
void onCompletion(CedarMediaPlayer *pMp);
bool onError(CedarMediaPlayer *pMp, int what, int extra);
void onVideoSizeChanged(CedarMediaPlayer *pMp, int width, int height);
bool onInfo(CedarMediaPlayer *pMp, int what, int extra);
void onSeekComplete(CedarMediaPlayer *pMp);
void onBufferingUpdate(CedarMediaPlayer *pMp, int percent);
private:
PlayerDemo *mpPlayerDemo;
};
private:
CedarMediaPlayer *mpPlayer;
PlayerListener *mpListener;
CedarDisplay *mpCedarDisp;
int mHlay;
PlayerDemoStates mCurrentStates;
};
PlayerDemo::PlayerDemo()
: mpPlayer(NULL)
, mpListener(NULL)
, mpCedarDisp(NULL)
, mCurrentStates(PLAYER_DEMO_IDLE)
{
}
PlayerDemo::~PlayerDemo()
{
}
status_t PlayerDemo::initialize()
{
struct view_info sur = {0, 0, 480, 272};
int ret;
mpPlayer = new CedarMediaPlayer();
if (mpPlayer == NULL) {
gsmLoge("Failed to new CedarMediaPlayer!!");
return NO_MEMORY;
}
mpListener = new PlayerListener(this);
if (mpListener == NULL) {
gsmLoge("Failed to new PlayerListener!!");
goto ALLOC_LISTENER_ERR;
}
mpPlayer->setOnPreparedListener(mpListener);
mpPlayer->setOnCompletionListener(mpListener);
mpPlayer->setOnErrorListener(mpListener);
mpPlayer->setOnVideoSizeChangedListener(mpListener);
mpPlayer->setOnInfoListener(mpListener);
mpPlayer->setOnSeekCompleteListener(mpListener);
mpPlayer->setOnBufferingUpdateListener(mpListener);
mpCedarDisp = new CedarDisplay(0);
if (mpCedarDisp == NULL) {
gsmLoge("Failed to new CedarDisplay!!");
goto ALLOC_DISP_ERR;
}
mHlay = mpCedarDisp->requestSurface(&sur);
mpCedarDisp->setPreviewRect(&sur);
ret=mpCedarDisp->open(mHlay, 1);
if (ret != NO_ERROR) {
gsmLoge("Failed to open CedarDisplay[%d]", ret);
goto OPEN_DISP_ERR;
}
return NO_ERROR;
OPEN_DISP_ERR:
mpCedarDisp->releaseSurface(mHlay);
delete mpCedarDisp;
mpCedarDisp = NULL;
ALLOC_DISP_ERR:
delete mpListener;
mpListener = NULL;
ALLOC_LISTENER_ERR:
delete mpPlayer;
mpPlayer = NULL;
return NO_MEMORY;
}
status_t PlayerDemo::destroy()
{
if (mpCedarDisp != NULL) {
mpCedarDisp->releaseSurface(mHlay);
delete mpCedarDisp;
mpCedarDisp = NULL;
}
if (mpListener != NULL) {
delete mpListener;
mpListener = NULL;
}
if (mpPlayer != NULL) {
delete mpPlayer;
mpPlayer = NULL;
}
return NO_ERROR;
}
status_t PlayerDemo::setDisplay()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
mpPlayer->setDisplay(mHlay);
return NO_ERROR;
}
status_t PlayerDemo::prepareToPlay(String8 path)
{
status_t ret;
if (mpPlayer == NULL) {
return NO_INIT;
}
ret = mpPlayer->setDataSource(path);
if (ret != NO_ERROR) {
gsmLoge("setDataSource error[%d]", ret);
return ret;
}
ret = mpPlayer->setAudioStreamType(AUDIO_STREAM_MUSIC);
if (ret != NO_ERROR) {
gsmLoge("setAudioStreamType error[%d]", ret);
return ret;
}
mpPlayer->setScreenOnWhilePlaying(true);
mCurrentStates = PLAYER_DEMO_INITIALIZED;
ret = mpPlayer->prepareAsync();
if (ret != NO_ERROR) {
gsmLoge("prepareAsync error[%d]", ret);
return ret;
}
mCurrentStates = PLAYER_DEMO_PREPARING;
return NO_ERROR;
}
status_t PlayerDemo::start()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
if (mCurrentStates == PLAYER_DEMO_PREPARED ||
mCurrentStates == PLAYER_DEMO_PLAYBACK_COMPLETE ||
mCurrentStates == PLAYER_DEMO_PAUSED) {
status_t ret = mpPlayer->start();
if (ret != NO_ERROR) {
gsmLoge("start error[%d]", ret);
mCurrentStates = PLAYER_DEMO_STATE_ERROR;
} else {
mCurrentStates = PLAYER_DEMO_STARTED;
}
return ret;
} else {
return INVALID_OPERATION;
}
return NO_ERROR;
}
status_t PlayerDemo::stop()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
if (mCurrentStates == PLAYER_DEMO_STOPPED) {
return NO_ERROR;
}
if (mCurrentStates == PLAYER_DEMO_STARTED ||
mCurrentStates == PLAYER_DEMO_PREPARED ||
mCurrentStates == PLAYER_DEMO_PAUSED ||
mCurrentStates == PLAYER_DEMO_PLAYBACK_COMPLETE) {
status_t ret = mpPlayer->stop();
if (ret != NO_ERROR) {
mCurrentStates = PLAYER_DEMO_STATE_ERROR;
} else {
mCurrentStates = PLAYER_DEMO_STOPPED;
}
return ret;
}
return INVALID_OPERATION;
}
status_t PlayerDemo::pause()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
if (mCurrentStates == PLAYER_DEMO_PAUSED || mCurrentStates == PLAYER_DEMO_PLAYBACK_COMPLETE) {
return NO_ERROR;
}
if (mCurrentStates == PLAYER_DEMO_STARTED) {
status_t ret = mpPlayer->pause();
if (ret != NO_ERROR) {
mCurrentStates = PLAYER_DEMO_STATE_ERROR;
} else {
mCurrentStates = PLAYER_DEMO_PAUSED;
}
return ret;
}
return INVALID_OPERATION;
}
status_t PlayerDemo::seek(int msec)
{
int total, current;
if (mpPlayer == NULL) {
return NO_INIT;
}
if (mCurrentStates == PLAYER_DEMO_STARTED ||
mCurrentStates == PLAYER_DEMO_PREPARED ||
mCurrentStates == PLAYER_DEMO_PAUSED ||
mCurrentStates == PLAYER_DEMO_PLAYBACK_COMPLETE) {
if(msec == 0) {
return BAD_VALUE;
}
total = getDurationMs();
current = getCurrentPosMs();
if(total == -1 || current == -1) {
return UNKNOWN_ERROR;
}
current += msec;
if(current > total || current < 0) {
return BAD_VALUE;
}
return mpPlayer->seekTo(current);
}
return INVALID_OPERATION;
}
status_t PlayerDemo::release()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
mpPlayer->release();
return NO_ERROR;
}
status_t PlayerDemo::reset()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
if (mCurrentStates == PLAYER_DEMO_IDLE) {
return NO_ERROR;
}
status_t ret = mpPlayer->reset();
if (ret != NO_ERROR) {
mCurrentStates = PLAYER_DEMO_STATE_ERROR;
} else {
mCurrentStates = PLAYER_DEMO_IDLE;
}
return ret;
}
int PlayerDemo::getDurationMs()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
return mpPlayer->getDuration();
}
int PlayerDemo::getCurrentPosMs()
{
if (mpPlayer == NULL) {
return NO_INIT;
}
return mpPlayer->getCurrentPosition();
}
void PlayerDemo::PlayerListener::onPrepared(CedarMediaPlayer *pMp)
{
gsmLogd("onPrepared");
mpPlayerDemo->setCurrentStates(PLAYER_DEMO_PREPARED);
}
void PlayerDemo::PlayerListener::onCompletion(CedarMediaPlayer *pMp)
{
gsmLogd("onCompletion");
mpPlayerDemo->setCurrentStates(PLAYER_DEMO_PLAYBACK_COMPLETE);
}
bool PlayerDemo::PlayerListener::onError(CedarMediaPlayer *pMp, int what, int extra)
{
gsmLogd("onError: what=%d, extra=%d", what, extra);
return true;
}
void PlayerDemo::PlayerListener::onVideoSizeChanged(CedarMediaPlayer *pMp, int width, int height)
{
gsmLogd("onVideoSizeChanged: width=%d, height=%d", width, height);
}
bool PlayerDemo::PlayerListener::onInfo(CedarMediaPlayer *pMp, int what, int extra)
{
gsmLogd("onInfo: what=%d, extra=%d", what, extra);
return true;
}
void PlayerDemo::PlayerListener::onSeekComplete(CedarMediaPlayer *pMp)
{
gsmLogd("onSeekComplete");
}
void PlayerDemo::PlayerListener::onBufferingUpdate(CedarMediaPlayer *pMp, int percent)
{
gsmLogd("onBufferingUpdate: percent=%d", percent);
}
static void usage()
{
fprintf(stderr, "Usage: playDemo file\n");
}
int main(int argc, char *argv[])
{
if (argc < 2) {
usage();
return -1;
}
fprintf(stderr, "hello, playDemo\n");
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
status_t ret = NO_ERROR;
int i = 0;
int totalTimeMs, curTimeMs;
system("dd if=/dev/zero of=/dev/graphics/fb0");
PlayerDemo *player = new PlayerDemo();
if (player == NULL) {
gsmLoge("Failed to new PlayerDemo!!");
return -1;
}
ret = player->initialize();
if (ret != NO_ERROR) {
gsmLoge("Failed to initialize PlayerDemo[%d]!!", ret);
return -1;
}
player->setDisplay();
ret = player->prepareToPlay(String8(argv[1]));
if (ret != NO_ERROR) {
gsmLoge("Failed to prepareToPlay[%d]!!", ret);
return -1;
}
for (i = 0; i < 50; ++i) {
if (player->getCurrentStates() == PLAYER_DEMO_PREPARED) {
gsmLogd("Ready to start play");
break;
}
gsmLogd("Waiting %dms for player changing to ready states", i*100*1000);
usleep(100*1000);
}
if (i >= 50) {
gsmLoge("wait player ready too long!");
return -1;
}
totalTimeMs = player->getDurationMs();
curTimeMs = 0;
ret = player->start();
if (ret != NO_ERROR) {
return -1;
}
fprintf(stderr, "player time:\n");
while (player->getCurrentStates() != PLAYER_DEMO_PLAYBACK_COMPLETE) {
curTimeMs = player->getCurrentPosMs();
fprintf(stderr, "\t\t%05d / %05d\r", curTimeMs/1000, totalTimeMs/1000);
usleep(1*1000*1000);
}
fprintf(stderr, "\n");
player->stop();
player->reset();
player->destroy();
delete player;
fprintf(stderr, "playDemo done\n");
IPCThreadState::self()->joinThreadPool();
}