2012-10-08, 13:49
(2012-10-08, 09:03)dteirney Wrote:(2012-10-03, 21:11)Aubrien Wrote: OK, I have had live tv playing for hours now without it stopping so I think its time to post the solution. There are two delays needed as well as an object lock. I based this on cfetzer's code not janbar's since that is where we are moving to anyway. The changes are below...
addons/pvr.mythtv.cmyth/src/pvrclient-mythtv.cpp
Add the delay for changing channels.Code:bool PVRClientMythTV::OpenLiveStream(const PVR_CHANNEL &channel)
{
if (g_bExtraDebug)
XBMC->Log(LOG_DEBUG,"%s - chanID: %i, channumber: %i", __FUNCTION__, channel.iUniqueId, channel.iChannelNumber);
SingleLock<PLATFORM::CMutex> lock(&m_lock);
if (m_rec.IsNull())
{
MythChannel chan = m_channels.at(channel.iUniqueId);
for (std::vector<int>::iterator it = m_sources.at(chan.SourceID()).begin(); it != m_sources.at(chan.SourceID()).end(); it++)
{
m_rec = m_con.GetRecorder(*it);
if (!m_rec.IsRecording() && m_rec.IsTunable(chan))
{
if (g_bExtraDebug)
XBMC->Log(LOG_DEBUG,"%s: Opening new recorder %i", __FUNCTION__, m_rec.ID());
if (m_pEventHandler)
m_pEventHandler->SetRecorder(m_rec);
if (m_rec.SpawnLiveTV(chan))
{
usleep(10000000); //Channel change delay of 10s
return true;
}
}
m_rec = MythRecorder();
if (m_pEventHandler)
{
m_pEventHandler->SetRecorder(m_rec); // Redundant
}
}
if (g_bExtraDebug)
XBMC->Log(LOG_DEBUG,"%s - Done", __FUNCTION__);
return false;
}
else
{
if (g_bExtraDebug)
XBMC->Log(LOG_DEBUG,"%s - Done", __FUNCTION__);
return true;
}
}
addons/pvr.mythtv.cmyth/src/cppmyth/MythRecorder.cpp
Uncomment the lock/unlock. Add the delay for between shows.Code:bool MythRecorder::LiveTVChainUpdate(CStdString chainID)
{
char* buffer=strdup(chainID.c_str());
m_recorder_t->Lock();
int retval = 0;
usleep(5000000); // Program switch delay of 5s
CMYTH_REC_CALL( retval, retval < 0, cmyth_livetv_chain_update( *m_recorder_t, buffer, 16*1024 ) );
if(retval != 0)
XBMC->Log(LOG_ERROR,"LiveTVChainUpdate failed on chainID: %s",buffer);
*livechainupdated=1;
m_recorder_t->Unlock();
free(buffer);
return retval==0;
}
addons/pvr.mythtv.cmyth/src/cppmyth/MythRecorder.cpp
Uncomment the lock/unlockCode:int MythRecorder::ReadLiveTV(void* buffer,unsigned long length)
{
m_recorder_t->Lock();
int bytesRead=0;
CMYTH_REC_CALL( bytesRead, bytesRead < 0, cmyth_livetv_read( *m_recorder_t, static_cast<char*>( buffer ), length ) );
m_recorder_t->Unlock();
return bytesRead;
}
The end result of this makes the channels change properly either from nothing being played or from already watching tv. The delay is especially useful for those of us with IR blasters and analog tuners. Additionally, when the chain is updated (program transition) it locks the recorder for 5s. During this time read operations delay and the user is prevented from underrunning the buffer on the backend. Both the channel change delay and the program switch delay should be made into addon settings to be user configured. Mine works with the static values I inserted for developing the fix. Between program transitions you will see a "Buffering %" dialog for a second or so. This buffering is essential as each program transition causes no data for a small period and eventually the buffer is depleted and this makes it refill.
Rather than a hard-coded 5 second delay could you look at doing something more like was done in one of my branches. Unfortunately still not cleaned up and ready for PR to upstream libcmyth. https://github.com/dteirney/xbmc/commit/...96ecac88b2
That commit also has the fix for the LiveTV locking problem as well.
@dteirney: I read your commit. It is a way. But i think we must to find a solution without use backend's database at least for liveTV. Would not be better to use only Mythtv protocol ?