void OMXPlayerAudio::Process() { m_audioStats.Start(); while(!m_bStop) { CDVDMsg* pMsg; int priority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0; int timeout = 1000; MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, timeout, priority); if (ret == MSGQ_TIMEOUT) { Sleep(10); continue; } if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT) { Sleep(10); continue; } if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { DemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket(); bool bPacketDrop = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop(); #ifdef _DEBUG CLog::Log(LOGINFO, "Audio: dts:%.0f pts:%.0f size:%d (s:%d f:%d d:%d l:%d) s:%d %d/%d late:%d,%d", pPacket->dts, pPacket->pts, (int)pPacket->iSize, m_started, m_flush, bPacketDrop, m_stalled, m_speed, 0, 0, (int)m_omxAudio.GetAudioRenderingLatency(), (int)m_hints_current.samplerate); #endif if(Decode(pPacket, m_speed > DVD_PLAYSPEED_NORMAL || m_speed < 0 || bPacketDrop)) { // we are not running until something is cached in output device if(m_stalled && m_omxAudio.GetCacheTime() > 0.0) { CLog::Log(LOGINFO, "COMXPlayerAudio - Switching to normal playback"); m_stalled = false; } } } else if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) { if(((CDVDMsgGeneralSynchronize*)pMsg)->Wait( 100, SYNCSOURCE_AUDIO )) CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_SYNCHRONIZE"); else m_messageQueue.Put(pMsg->Acquire(), 1); /* push back as prio message, to process other prio messages */ } else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC)) { //player asked us to set internal clock CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg; CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, %d)", m_audioClock, pMsgGeneralResync->m_clock); m_flush = false; m_audioClock = DVD_NOPTS_VALUE; } else if (pMsg->IsType(CDVDMsg::GENERAL_RESET)) { CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESET"); if (m_pAudioCodec) m_pAudioCodec->Reset(); m_omxAudio.Flush(); m_started = false; m_audioClock = DVD_NOPTS_VALUE; } else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) { CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_FLUSH"); m_omxAudio.Flush(); m_stalled = true; m_started = false; if (m_pAudioCodec) m_pAudioCodec->Reset(); m_audioClock = DVD_NOPTS_VALUE; } else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) { CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_STARTED %d", m_started); if(m_started) m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_AUDIO)); } else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME)) { COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value; if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK) state.time = DVD_TIME_TO_MSEC(m_av_clock->OMXMediaTime()); //state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset); else state.timestamp = m_av_clock->GetAbsoluteClock(); state.player = DVDPLAYER_AUDIO; m_messageParent.Put(pMsg->Acquire()); } else if (pMsg->IsType(CDVDMsg::GENERAL_EOF)) { CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_EOF"); SubmitEOS(); } else if (pMsg->IsType(CDVDMsg::GENERAL_DELAY)) { double timeout = static_cast<CDVDMsgDouble*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_DELAY(%f)", timeout); } else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED)) { if (m_speed != static_cast<CDVDMsgInt*>(pMsg)->m_value) { m_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_SETSPEED %d", m_speed); } } else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE)) { m_silence = static_cast<CDVDMsgBool*>(pMsg)->m_value; if (m_silence) CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, 1)", m_audioClock); else CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, 0)", m_audioClock); } else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE)) { COMXMsgAudioCodecChange* msg(static_cast<COMXMsgAudioCodecChange*>(pMsg)); OpenStream(msg->m_hints, msg->m_codec); msg->m_codec = NULL; } pMsg->Release(); } }
void OMXPlayerAudio::Process() { m_audioStats.Start(); while(!m_bStop) { CDVDMsg* pMsg; int timeout = 1000; // read next packet and return -1 on error int priority = 1; //Do we want a new audio frame? if (m_syncState == IDVDStreamPlayer::SYNC_STARTING || /* when not started */ m_speed == DVD_PLAYSPEED_NORMAL || /* when playing normally */ m_speed < DVD_PLAYSPEED_PAUSE || /* when rewinding */ (m_speed > DVD_PLAYSPEED_NORMAL && m_audioClock < m_av_clock->GetClock())) /* when behind clock in ff */ priority = 0; if (m_syncState == IDVDStreamPlayer::SYNC_WAITSYNC) priority = 1; // consider stream stalled if queue is empty // we can't sync audio to clock with an empty queue if (m_speed == DVD_PLAYSPEED_NORMAL) { timeout = 0; } MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, timeout, priority); if (ret == MSGQ_TIMEOUT) { Sleep(10); continue; } if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT) { Sleep(10); continue; } if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { DemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket(); bool bPacketDrop = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop(); #ifdef _DEBUG CLog::Log(LOGINFO, "Audio: dts:%.0f pts:%.0f size:%d (s:%d f:%d d:%d l:%d) s:%d %d/%d late:%d,%d", pPacket->dts, pPacket->pts, (int)pPacket->iSize, m_syncState, m_flush, bPacketDrop, m_stalled, m_speed, 0, 0, (int)m_omxAudio.GetAudioRenderingLatency(), (int)m_hints_current.samplerate); #endif if(Decode(pPacket, bPacketDrop, m_speed > DVD_PLAYSPEED_NORMAL || m_speed < 0)) { // we are not running until something is cached in output device if(m_stalled && m_omxAudio.GetCacheTime() > 0.0) { CLog::Log(LOGINFO, "COMXPlayerAudio - Switching to normal playback"); m_stalled = false; } } } else if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) { if(((CDVDMsgGeneralSynchronize*)pMsg)->Wait( 100, SYNCSOURCE_AUDIO )) CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_SYNCHRONIZE"); else m_messageQueue.Put(pMsg->Acquire(), 1); /* push back as prio message, to process other prio messages */ } else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC)) { //player asked us to set internal clock double pts = static_cast<CDVDMsgDouble*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f)", pts); m_audioClock = pts; m_syncState = IDVDStreamPlayer::SYNC_INSYNC; } else if (pMsg->IsType(CDVDMsg::GENERAL_RESET)) { CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESET"); if (m_pAudioCodec) m_pAudioCodec->Reset(); m_syncState = IDVDStreamPlayer::SYNC_STARTING; m_audioClock = DVD_NOPTS_VALUE; } else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) { bool sync = static_cast<CDVDMsgBool*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_FLUSH(%d)", sync); m_omxAudio.Flush(); m_stalled = true; m_syncState = IDVDStreamPlayer::SYNC_STARTING; if (m_pAudioCodec) m_pAudioCodec->Reset(); m_audioClock = DVD_NOPTS_VALUE; m_flush = false; } else if (pMsg->IsType(CDVDMsg::GENERAL_EOF)) { CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_EOF"); SubmitEOS(); } else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED)) { if (m_speed != static_cast<CDVDMsgInt*>(pMsg)->m_value) { m_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_SETSPEED %d", m_speed); } } else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE)) { COMXMsgAudioCodecChange* msg(static_cast<COMXMsgAudioCodecChange*>(pMsg)); CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_STREAMCHANGE"); OpenStream(msg->m_hints, msg->m_codec); msg->m_codec = NULL; } pMsg->Release(); } }
void OMXPlayerVideo::Process() { double frametime = (double)DVD_TIME_BASE / m_fFrameRate; bool bRequestDrop = false; m_videoStats.Start(); while(!m_bStop) { CDVDMsg* pMsg; int iQueueTimeOut = (int)(m_stalled ? frametime / 4 : frametime * 10) / 1000; int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0; MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, iQueueTimeOut, iPriority); if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT) { CLog::Log(LOGERROR, "OMXPlayerVideo: Got MSGQ_IS_ERROR(%d) Aborting", (int)ret); break; } else if (ret == MSGQ_TIMEOUT) { continue; } if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) { if(((CDVDMsgGeneralSynchronize*)pMsg)->Wait(100, SYNCSOURCE_VIDEO)) { CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_SYNCHRONIZE"); } else m_messageQueue.Put(pMsg->Acquire(), 1); /* push back as prio message, to process other prio messages */ pMsg->Release(); continue; } else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC)) { CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg; CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, %d)", pMsgGeneralResync->m_timestamp, pMsgGeneralResync->m_clock); m_nextOverlay = DVD_NOPTS_VALUE; m_iCurrentPts = DVD_NOPTS_VALUE; pMsgGeneralResync->Release(); continue; } else if (pMsg->IsType(CDVDMsg::GENERAL_DELAY)) { double timeout = static_cast<CDVDMsgDouble*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_DELAY(%f)", timeout); } else if (pMsg->IsType(CDVDMsg::VIDEO_SET_ASPECT)) { m_fForcedAspectRatio = *((CDVDMsgDouble*)pMsg); CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::VIDEO_SET_ASPECT %.2f", m_fForcedAspectRatio); } else if (pMsg->IsType(CDVDMsg::GENERAL_RESET)) { CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_RESET"); m_omxVideo.Reset(); m_started = false; m_nextOverlay = DVD_NOPTS_VALUE; m_iCurrentPts = DVD_NOPTS_VALUE; } else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (COMXPlayerVideo::Flush()) { CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_FLUSH"); m_stalled = true; m_started = false; m_nextOverlay = DVD_NOPTS_VALUE; m_iCurrentPts = DVD_NOPTS_VALUE; m_omxVideo.Reset(); m_flush = false; } else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED)) { if (m_speed != static_cast<CDVDMsgInt*>(pMsg)->m_value) { m_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value; CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::PLAYER_SETSPEED %d", m_speed); } } else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED)) { CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::PLAYER_STARTED %d", m_started); if(m_started) m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO)); } else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME)) { COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value; if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK) state.time = DVD_TIME_TO_MSEC(m_av_clock->OMXMediaTime()); //state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset); else state.timestamp = m_av_clock->GetAbsoluteClock(); state.player = DVDPLAYER_VIDEO; m_messageParent.Put(pMsg->Acquire()); } else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE)) { COMXMsgVideoCodecChange* msg(static_cast<COMXMsgVideoCodecChange*>(pMsg)); OpenStream(msg->m_hints, msg->m_codec); msg->m_codec = NULL; } else if (pMsg->IsType(CDVDMsg::GENERAL_EOF)) { CLog::Log(LOGDEBUG, "COMXPlayerVideo - CDVDMsg::GENERAL_EOF"); SubmitEOS(); } else if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { DemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket(); bool bPacketDrop = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop(); #ifdef _DEBUG CLog::Log(LOGINFO, "Video: dts:%.0f pts:%.0f size:%d (s:%d f:%d d:%d l:%d) s:%d %d/%d late:%d\n", pPacket->dts, pPacket->pts, (int)pPacket->iSize, m_started, m_flush, bPacketDrop, m_stalled, m_speed, 0, 0, 0); #endif if (m_messageQueue.GetDataSize() == 0 || m_speed < 0) { bRequestDrop = false; } // if player want's us to drop this packet, do so nomatter what if(bPacketDrop) bRequestDrop = true; m_omxVideo.SetDropState(bRequestDrop); while (!m_bStop) { // discard if flushing as clocks may be stopped and we'll never submit it if (m_flush) break; if((int)m_omxVideo.GetFreeSpace() < pPacket->iSize) { Sleep(10); continue; } if (m_stalled) { CLog::Log(LOGINFO, "COMXPlayerVideo - Stillframe left, switching to normal playback"); m_stalled = false; } // some packed bitstream AVI files set almost all pts values to DVD_NOPTS_VALUE, but have a scattering of real pts values. // the valid pts values match the dts values. // if a stream has had more than 4 valid pts values in the last 16, the use UNKNOWN, otherwise use dts m_history_valid_pts = (m_history_valid_pts << 1) | (pPacket->pts != DVD_NOPTS_VALUE); double pts = pPacket->pts; if(pPacket->pts == DVD_NOPTS_VALUE && count_bits(m_history_valid_pts & 0xffff) < 4) pts = pPacket->dts; if (pts != DVD_NOPTS_VALUE) pts += m_iVideoDelay; m_omxVideo.Decode(pPacket->pData, pPacket->iSize, pts); Output(pts, bRequestDrop); m_iCurrentPts = pts; if(m_started == false) { m_codecname = m_omxVideo.GetDecoderName(); m_started = true; m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO)); } break; } bRequestDrop = false; m_videoStats.AddSampleBytes(pPacket->iSize); } pMsg->Release(); } }