📄 cpi_player_engine.c
字号:
break;
}
}
if(bTerminateThread)
break;
// 等待下一个消息或者缓冲区满 (假如有播放器)
if(playercontext.m_bOutputActive)
{
dwWaitResult = 0L;
if(bForceRefill == FALSE)
{
if(playercontext.m_pCurrentOutputModule->m_evtBlockFree)
dwWaitResult = MsgWaitForMultipleObjects(1, &playercontext.m_pCurrentOutputModule->m_evtBlockFree, FALSE, 1000, QS_POSTMESSAGE);
else
dwWaitResult = WAIT_OBJECT_0;
}
// 如果缓冲区消息被发送,那么请求重新填充
if(bForceRefill == TRUE || dwWaitResult == WAIT_OBJECT_0)
{
if(playercontext.m_pCurrentOutputModule->m_pCoDec)
{
playercontext.m_pCurrentOutputModule->RefillBuffers(playercontext.m_pCurrentOutputModule);
if(playercontext.m_pCurrentOutputModule->m_pCoDec == NULL)
{
// 通知 UI 需要另一个播放文件
PostMessage(playercontext.m_pBaseEngineParams->m_hWndNotify, CPNM_PLAYERSTATE, (WPARAM)cppsEndOfStream, 0);
}
else
UpdateProgress(&playercontext);
}
// 如果输出结束了应作的每件事,关闭引擎
else if(playercontext.m_pCurrentOutputModule->IsOutputComplete(playercontext.m_pCurrentOutputModule) == TRUE)
{
playercontext.m_bOutputActive = FALSE;
playercontext.m_pCurrentOutputModule->Uninitialise(playercontext.m_pCurrentOutputModule);
PostMessage(playercontext.m_pBaseEngineParams->m_hWndNotify, CPNM_PLAYERSTATE, (WPARAM)cppsStopped, 0);
}
}
}
else
{
WaitMessage();
}
}
while(bTerminateThread == FALSE);
// 清空输出(如果仍然是活跃的)
if(playercontext.m_pCurrentOutputModule->m_pCoDec)
{
playercontext.m_pCurrentOutputModule->m_pCoDec->CloseFile(playercontext.m_pCurrentOutputModule->m_pCoDec);
playercontext.m_pCurrentOutputModule->m_pCoDec = NULL;
}
if(playercontext.m_bOutputActive == TRUE)
playercontext.m_pCurrentOutputModule->Uninitialise(playercontext.m_pCurrentOutputModule);
// 清空模板
playercontext.m_Equaliser.Uninitialise(&playercontext.m_Equaliser);
CleanupCoDecs(&playercontext);
if(hr_ComState == S_OK)
CoUninitialize();
CP_TRACE0("Cooler Engine terminating");
return 0;
}
//
//
//
void UpdateProgress(CPs_PlayerContext* pContext)
{
int iCurrentTime_Secs;
// 如果文件偏移改变,重新发送通知
if(pContext->m_bOutputActive == TRUE)
iCurrentTime_Secs = pContext->m_pCurrentOutputModule->m_pCoDec->GetCurrentPos_secs(pContext->m_pCurrentOutputModule->m_pCoDec);
else
iCurrentTime_Secs = 0;
if(iCurrentTime_Secs != pContext->m_iLastSentTime_Secs)
{
CPs_FileInfo* pFileInfo;
int iFileLength_Secs;
pContext->m_iLastSentTime_Secs = iCurrentTime_Secs;
// (重)发文件信息
pFileInfo = (CPs_FileInfo*)malloc(sizeof(*pFileInfo));
pContext->m_pCurrentOutputModule->m_pCoDec->GetFileInfo(pContext->m_pCurrentOutputModule->m_pCoDec, pFileInfo);
iFileLength_Secs = pFileInfo->m_iFileLength_Secs;
PostMessage(pContext->m_pBaseEngineParams->m_hWndNotify, CPNM_FILEINFO, (WPARAM)pFileInfo, 0);
// 发送当前进程
PostMessage(pContext->m_pBaseEngineParams->m_hWndNotify, CPNM_FILEOFFSET_SECS, (WPARAM)iCurrentTime_Secs, 0);
// Send the proportion along the track (if it has changed)
if(pContext->m_iProportion_TrackLength != 0 && iFileLength_Secs != 0)
{
int iProportionAlongTrack = (int)( ( (float)iCurrentTime_Secs / (float)iFileLength_Secs)
* (float)pContext->m_iProportion_TrackLength );
if(iProportionAlongTrack != pContext->m_iLastSentTime_Proportion)
{
pContext->m_iLastSentTime_Proportion = iProportionAlongTrack;
PostMessage(pContext->m_pBaseEngineParams->m_hWndNotify, CPNM_FILEOFFSET_PROP, (WPARAM)iProportionAlongTrack, 0);
}
}
}
}
//
//
//
void EmptyOutputStream(CPs_PlayerContext* pContext)
{
if(pContext->m_bOutputActive == FALSE)
return;
while(pContext->m_pCurrentOutputModule->IsOutputComplete(pContext->m_pCurrentOutputModule) == FALSE)
{
WaitForSingleObject(pContext->m_pCurrentOutputModule->m_evtBlockFree, 1000);
if(pContext->m_pCurrentOutputModule->m_pCoDec)
UpdateProgress(pContext);
}
pContext->m_bOutputActive = FALSE;
pContext->m_pCurrentOutputModule->Uninitialise(pContext->m_pCurrentOutputModule);
PostMessage(pContext->m_pBaseEngineParams->m_hWndNotify, CPNM_PLAYERSTATE, (WPARAM)cppsStopped, 0);
}
//
//
//
void EnumOutputDevices(CPs_PlayerContext* pContext)
{
int iOutputModuleIDX;
// 列举输出模板
for(iOutputModuleIDX = 0; iOutputModuleIDX <= CP_OUTPUT_last; iOutputModuleIDX++)
{
const CPs_OutputModule* pOutputModule = pContext->m_OutputModules + iOutputModuleIDX;
char* pcDeviceName;
// 缓冲释放
STR_AllocSetString(&pcDeviceName, pOutputModule->m_pcModuleName, FALSE);
PostMessage(pContext->m_pBaseEngineParams->m_hWndNotify, CPNM_FOUNDOUTPUTDEVICE, (WPARAM)pcDeviceName, (LPARAM)iOutputModuleIDX);
}
}
//
//
//
void StartPlay(CPs_CoDecModule* pCoDec, CPs_PlayerContext* pContext)
{
CPs_FileInfo FileInfo;
pCoDec->GetFileInfo(pCoDec, &FileInfo);
pContext->m_bOutputActive = TRUE;
pContext->m_iOpenDevice_Freq_Hz = FileInfo.m_iFreq_Hz;
pContext->m_bOpenDevice_Stereo = FileInfo.m_bStereo;
pContext->m_bOpenDevice_16bit = FileInfo.m_b16bit;
// 获得模板并初始化
pContext->m_Equaliser.Initialise(&pContext->m_Equaliser, FileInfo.m_iFreq_Hz, FileInfo.m_b16bit);
pContext->m_pCurrentOutputModule->Initialise(pContext->m_pCurrentOutputModule, &FileInfo, &pContext->m_Equaliser);
// 如果音量不是100% 那么设置音量级
// if(!pContext->m_iInternalVolume)
pContext->m_pCurrentOutputModule->SetInternalVolume(pContext->m_pCurrentOutputModule, pContext->m_iInternalVolume);
}
//
//
//
CPs_CoDecModule* OpenCoDec(CPs_PlayerContext* pContext, const char* pcFilename)
{
const char* pcLastDot = NULL;
int iCoDecIDX = 0;
BOOL bOpenSucceeded;
DWORD dwCookie=0;
// 查找扩展名
char *extension=NULL;
char *dot=strrchr(pcFilename,'.');
if(dot) extension=dot+1;
/* if(dot)
{
if(CPFA_IsAssociated(&pContext->m_CoDecs[CP_CODEC_WINAMPPLUGIN], extension, &dwCookie) == TRUE)
{
bOpenSucceeded = pContext->m_CoDecs[CP_CODEC_WINAMPPLUGIN].OpenFile(
&pContext->m_CoDecs[CP_CODEC_WINAMPPLUGIN],
pcFilename,
dwCookie,
pContext->m_pBaseEngineParams->m_hWndNotify);
if(bOpenSucceeded == TRUE)
return &pContext->m_CoDecs[CP_CODEC_WINAMPPLUGIN];
}
}
*/
// Find a CoDec that wants this association
for(iCoDecIDX =CP_CODEC_WAV; iCoDecIDX <= CP_CODEC_last; iCoDecIDX++)
{
bOpenSucceeded = pContext->m_CoDecs[iCoDecIDX].OpenFile( &pContext->m_CoDecs[iCoDecIDX],
pcFilename,
dwCookie,
pContext->m_pBaseEngineParams->m_hWndNotify);
if(bOpenSucceeded == TRUE)
return &pContext->m_CoDecs[iCoDecIDX];
}
return NULL;
}
//
//
//
void CleanupCoDecs(CPs_PlayerContext* pContext)
{
int iCoDecIDX = 0;
for(iCoDecIDX =CP_CODEC_WAV; iCoDecIDX <= CP_CODEC_last; iCoDecIDX++)
pContext->m_CoDecs[iCoDecIDX].Uninitialise(&pContext->m_CoDecs[iCoDecIDX]);
}
//
//
//
void SetCurrentOutputModule(CPs_PlayerContext* pContext, CPs_OutputModule* pNewOuputModule, BOOL* pbForceRefill)
{
if(!pNewOuputModule)
pNewOuputModule = &pContext->m_OutputModules[pContext->m_dwCurrentOutputModule];
// 如果输出模板改变,那么关闭老的,使用新的
if(pContext->m_pCurrentOutputModule == pNewOuputModule)
return;
// 关闭当前存在的
if(pContext->m_bOutputActive)
{
pContext->m_pCurrentOutputModule->Uninitialise(pContext->m_pCurrentOutputModule);
pContext->m_bOutputActive = FALSE;
}
// 转换解码器到新的输出模板
pNewOuputModule->m_pCoDec = pContext->m_pCurrentOutputModule->m_pCoDec;
// 设置新模板为当前使用
pContext->m_pCurrentOutputModule = pNewOuputModule;
if(pContext->m_bOutputActive == FALSE && pContext->m_pCurrentOutputModule->m_pCoDec)
{
StartPlay(pContext->m_pCurrentOutputModule->m_pCoDec, pContext);
*pbForceRefill = TRUE;
}
}
//
//
//
void AssociateFileExtensions(CPs_PlayerContext* pContext)
{
int iCoDecIDX;
for(iCoDecIDX =0; iCoDecIDX <= CP_CODEC_last; iCoDecIDX++)
CPFA_AssociateWithEXE(&pContext->m_CoDecs[iCoDecIDX]);
}
//
//
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -