player.cpp
来自「这是一个mp3的源代码」· C++ 代码 · 共 1,991 行 · 第 1/4 页
CPP
1,991 行
Registry*
Player::
GetUIRegistry() const
{
return m_uiRegistry;
}
void
Player::
GetUIManipLock()
{
m_uiManipLock->Acquire(WAIT_FOREVER);
}
void
Player::
ReleaseUIManipLock()
{
m_uiManipLock->Release();
}
int32
Player::
AcceptEvent(Event * e)
{
m_eventQueue->Write(e);
m_eventSem->Signal();
return 0;
}
bool
Player::
SetState(PlayerState ps)
{
#if 0
printf("Player state: ");
switch(ps)
{
case PlayerState_Stopped:
printf("Stopped.\n");
break;
case PlayerState_Paused:
printf("Paused.\n");
break;
case PlayerState_Playing:
printf("Playing.\n");
break;
default:
printf("Unknown.\n");
break;
}
#endif
if (ps == m_playerState)
return false;
m_playerState = ps;
return true;
}
char *
Player::
GetExtension(const char *title)
{
char *temp_ext;
char *ext_return = NULL;
temp_ext = strrchr(title, '.');
if (temp_ext)
{
temp_ext = temp_ext + 1;
ext_return = new char [strlen(temp_ext) + 1];
strcpy(ext_return, temp_ext);
char *p = ext_return;
while (*p) {
*p = toupper(*p);
p++;
}
}
return ext_return;
}
bool
Player::
IsSupportedExtension(const char *ext)
{
RegistryItem *lmc_item = m_lmcExtensions->Value(ext);
if (lmc_item)
return true;
return false;
}
RegistryItem *
Player::
ChooseLMC(const char *szUrl, char *szTitle)
{
RegistryItem *lmc_item = NULL;
char *iExt;
iExt = GetExtension(szUrl);
if (!iExt)
return lmc_item;
lmc_item = m_lmcExtensions->Value(iExt);
delete iExt;
return lmc_item;
}
RegistryItem *
Player::
ChoosePMI(const char *szUrl, char *szTitle)
{
PhysicalMediaInput *pmi;
RegistryItem *pmi_item, *ret = NULL;
int iLoop;
char *szNewUrl = NULL;
if (strstr(szUrl, "://") == NULL)
{
szNewUrl = new char[strlen(szUrl) + strlen("file:// ") + 1];
sprintf(szNewUrl, "file://%s", szUrl);
szUrl = szNewUrl;
}
for (iLoop = 0; iLoop < m_pmiRegistry->CountItems(); iLoop++)
{
pmi_item = m_pmiRegistry->GetItem(iLoop);
pmi = (PhysicalMediaInput *) pmi_item->InitFunction()(m_context);
if (pmi->CanHandle(szUrl, szTitle))
{
ret = pmi_item;
delete pmi;
break;
}
delete pmi;
}
if (szNewUrl)
delete szNewUrl;
return ret;
}
void
Player::
CreatePMO(const PlaylistItem * pc, Event * pC)
{
Error error = kError_NoErr;
Event *e;
PhysicalMediaOutput *pmo = NULL;
PhysicalMediaInput *pmi = NULL;
LogicalMediaConverter *lmc = NULL;
RegistryItem *pmi_item = NULL;
RegistryItem *lmc_item = NULL;
RegistryItem *item = NULL;
if (!pc)
{
m_plm->SetCurrentIndex(0);
if (m_pmo)
{
m_pmo->Pause();
delete m_pmo;
m_pmo = NULL;
}
if (SetState(PlayerState_Stopped))
{
SEND_NORMAL_EVENT(INFO_Stopped);
}
GetUIManipLock();
e = new Event(INFO_PlaylistDonePlay);
SendToUI(e);
ReleaseUIManipLock();
delete e;
}
if (m_pmo)
{
m_pmo->Pause();
delete m_pmo;
m_pmo = NULL;
}
pmi_item = ChoosePMI(pc->URL().c_str());
if (!pmi_item)
{
char szErr[1024];
sprintf(szErr, "Cannot determine what pmi to use for %s\n", pc->URL().c_str());
m_context->log->Error(szErr);
AcceptEvent(new ErrorMessageEvent(szErr));
return;
}
lmc_item = ChooseLMC(pc->URL().c_str());
if (!lmc_item)
// FIXME: Should probably have a user definable default LMC
lmc_item = m_lmcRegistry->GetItem(0);
if (pmi_item)
{
pmi = (PhysicalMediaInput *) pmi_item->InitFunction()(m_context);
pmi->SetPropManager((Properties *) this);
}
char *extension = GetExtension(pc->URL().c_str());
if (extension) {
if (!strncasecmp("CDA", extension, 3)) {
int32 i = 0;
while (NULL != (item = m_pmoRegistry->GetItem(i++)))
{
if (!strcmp("cd.pmo", item->Name()))
{
break;
}
}
}
}
if (!item) {
char defaultPMO[256];
uint32 size = sizeof(defaultPMO);
m_context->prefs->GetDefaultPMO(defaultPMO, &size);
int32 i = 0;
while (NULL != (item = m_pmoRegistry->GetItem(i++)))
{
if(!strcmp(defaultPMO, item->Name()))
{
break;
}
}
}
// if the default isn't around then just use first one
// is there a better way?
if(!item)
item = m_pmoRegistry->GetItem(0);
if (item)
{
pmo = (PhysicalMediaOutput *) item->InitFunction()(m_context);
pmo->SetPropManager((Properties *) this);
}
error = kError_NoErr;
if (lmc_item)
{
lmc = (LogicalMediaConverter *) lmc_item->InitFunction()(m_context);
lmc->SetPropManager((Properties *) this);
}
lmc->SetPMI(pmi);
lmc->SetPMO(pmo);
pmo->SetPMI(pmi);
pmo->SetLMC(lmc);
pmi = NULL;
m_lmc = lmc;
lmc = NULL;
error = pmo->SetTo(pc->URL().c_str());
if (IsError(error))
{
char szErr[1024];
sprintf(szErr, "Cannot setup the audio decode process: %d\n", error);
m_context->log->Error(szErr);
goto epilogue;
}
m_pmo = pmo;
pmo = NULL;
epilogue:
if (pmo)
{
delete pmo;
}
if (pmi)
{
delete pmi;
}
if (lmc)
{
delete lmc;
}
}
void
Player::
DoneOutputting(Event *pEvent)
{
// LMC or PMO sends this when its done
// outputting whatever. Now, go on to next
// piece in playlist
if (m_pmo)
{
delete m_pmo;
m_pmo = NULL;
}
if (SetState(PlayerState_Stopped))
{
SEND_NORMAL_EVENT(INFO_Stopped);
}
SEND_NORMAL_EVENT(INFO_DoneOutputting);
if (pEvent->Type() == INFO_DoneOutputtingDueToError &&
(m_plm->GetRepeatMode() == kPlaylistMode_RepeatOne ||
(m_plm->GetRepeatMode() == kPlaylistMode_RepeatAll &&
m_plm->CountItems() == 1)))
{
m_plm->SetCurrentIndex(0);
SEND_NORMAL_EVENT(INFO_PlaylistDonePlay);
delete pEvent;
return;
}
if (m_plm->HasAnotherItem())
{
//AcceptEvent(new Event(CMD_NextMediaPiece));
m_plm->GotoNextItem(false);
if (m_playerState == PlayerState_Paused)
{
AcceptEvent(new Event(CMD_PlayPaused));
}
else
{
AcceptEvent(new Event(CMD_Play));
}
}
else
{
m_plm->SetCurrentIndex(0);
SEND_NORMAL_EVENT(INFO_PlaylistDonePlay);
}
delete pEvent;
}
void
Player::
Stop(Event *pEvent)
{
if (m_pmo)
{
m_pmo->Pause();
delete m_pmo;
m_pmo = NULL;
}
if (SetState(PlayerState_Stopped))
{
SEND_NORMAL_EVENT(INFO_Stopped);
}
delete pEvent;
}
void
Player::
GetVolume(Event *pEvent)
{
int iVolume = -1;
delete pEvent;
if (m_pmo)
{
iVolume = m_pmo->GetVolume();
SendToUI(new VolumeEvent(INFO_VolumeInfo,iVolume));
}
}
void
Player::
SetVolume(Event *pEvent)
{
int32 v=((VolumeEvent *) pEvent)->GetVolume();
if (m_pmo)
m_pmo->SetVolume(v);
delete pEvent;
}
void
Player::
ChangePosition(Event *pEvent)
{
if (m_pmo)
m_pmo->ChangePosition(((ChangePositionEvent *) pEvent)->GetPosition());
delete pEvent;
}
void
Player::
HandleQueryState()
{
if (m_playerState == PlayerState_Playing)
{
SEND_NORMAL_EVENT(INFO_Playing);
}
else if (m_playerState == PlayerState_Stopped)
{
SEND_NORMAL_EVENT(INFO_Stopped);
}
else if (m_playerState == PlayerState_Paused)
{
SEND_NORMAL_EVENT(INFO_Paused);
}
}
void
Player::
Play(Event *pEvent)
{
const PlaylistItem *pItem;
if (m_playerState == PlayerState_Playing)
{
delete m_pmo;
m_pmo = NULL;
if (SetState(PlayerState_Stopped))
{
SEND_NORMAL_EVENT(INFO_Stopped);
}
}
if (!m_pmo)
{
pItem = m_plm->GetCurrentItem();
if (pItem)
{
CreatePMO(pItem, pEvent);
}
if (!m_pmo)
return;
}
if (pEvent->Type() == CMD_PlayPaused)
{
if (SetState(PlayerState_Paused))
{
SEND_NORMAL_EVENT(INFO_Playing);
SEND_NORMAL_EVENT(INFO_Paused);
}
}
else
{
m_pmo->Resume();
if (SetState(PlayerState_Playing))
{
SEND_NORMAL_EVENT(INFO_Playing);
}
}
delete pEvent;
}
void
Player::
Next(Event *pEvent)
{
if (m_playerState != PlayerState_Stopped)
{
AcceptEvent(new Event(CMD_Stop));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?