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 + -
显示快捷键?