bool MythRecorder::IsTunable(MythChannel &channel) { Lock(); XBMC->Log(LOG_DEBUG, "%s: called for recorder %i, channel %i", __FUNCTION__, ID(), channel.ID()); cmyth_inputlist_t inputlist = cmyth_get_free_inputlist(*m_recorder_t); bool ret = false; for (int i = 0; i < inputlist->input_count; ++i) { cmyth_input_t input = inputlist->input_list[i]; if (input->sourceid != channel.SourceID()) { XBMC->Log(LOG_DEBUG, "%s: skip input, source id differs (channel: %i, input: %i)", __FUNCTION__, channel.SourceID(), input->sourceid); continue; } if (input->multiplexid && input->multiplexid != channel.MultiplexID()) { XBMC->Log(LOG_DEBUG, "%s: skip input, multiplex id id differs (channel: %i, input: %i)", __FUNCTION__, channel.MultiplexID(), input->multiplexid); continue; } XBMC->Log(LOG_DEBUG,"%s: using recorder, input is tunable: source id: %i, multiplex id: channel: %i, input: %i)", __FUNCTION__, channel.SourceID(), channel.MultiplexID(), input->multiplexid); ret = true; break; } ref_release(inputlist); Unlock(); if (!ret) { XBMC->Log(LOG_DEBUG,"%s: recorder is not tunable", __FUNCTION__); } return ret; }
bool MythRecorder::SpawnLiveTV(MythChannel &channel) { char* pErr=NULL; CStdString channelNum; channelNum.Format("%i",channel.Number()); m_recorder_t->Lock(); //check channel *livechainupdated=0; *m_recorder_t=(CMYTH->SpawnLiveTv(*m_recorder_t,64*1024, 16*1024,MythRecorder::prog_update_callback,&pErr,channelNum.GetBuffer())); int i=20; while(*livechainupdated==0&&i--!=0) { m_recorder_t->Unlock(); cSleep(100); m_recorder_t->Lock(); } m_recorder_t->Unlock(); ASSERT(*m_recorder_t); if(pErr) XBMC->Log(LOG_ERROR,"%s - %s",__FUNCTION__,pErr); return pErr==NULL; }
bool MythRecorder::SetChannel(MythChannel &channel) { // m_recorder_t->Lock(); m_conn.Lock(); if (!IsRecording()) { XBMC->Log(LOG_ERROR, "%s: Recorder %i is not recording", __FUNCTION__, ID(), const_cast<char*>(channel.Name().c_str())); // m_recorder_t->Unlock(); m_conn.Unlock(); return false; } CStdString channelNum = channel.Number(); if (cmyth_recorder_pause(*m_recorder_t) != 0) { XBMC->Log(LOG_ERROR, "%s: Failed to pause recorder %i", __FUNCTION__, ID()); // m_recorder_t->Unlock(); m_conn.Unlock(); return false; } if (!CheckChannel(channel)) { XBMC->Log(LOG_ERROR, "%s: Recorder %i doesn't provide channel %s", __FUNCTION__, ID(), channel.Name().c_str()); // m_recorder_t->Unlock(); m_conn.Unlock(); return false; } if (cmyth_recorder_set_channel(*m_recorder_t,channelNum.GetBuffer())!=0) { XBMC->Log(LOG_ERROR, "%s: Failed to change recorder %i to channel %s", __FUNCTION__, ID(), channel.Name().c_str()); // m_recorder_t->Unlock(); m_conn.Unlock(); return false; } if (cmyth_livetv_chain_switch_last(*m_recorder_t) != 1) { XBMC->Log(LOG_ERROR,"%s: Failed to switch chain for recorder %i", __FUNCTION__, ID(), channel.Name().c_str()); // m_recorder_t->Unlock(); m_conn.Unlock(); return false; } *m_liveChainUpdated = 0; int i = 20; while (*m_liveChainUpdated == 0 && i-- != 0) { //m_recorder_t->Unlock(); m_conn.Unlock(); usleep(100000); //m_recorder_t->Lock(); m_conn.Lock(); } //m_recorder_t->Unlock(); m_conn.Unlock(); for (int i = 0; i < 20; i++) { if (!IsRecording()) usleep(1000); else break; } return true; }
bool MythRecorder::SpawnLiveTV(MythChannel &channel) { char* pErr = NULL; m_conn.Lock(); // m_recorder_t->Lock(); // Check channel *m_liveChainUpdated = 0; cmyth_recorder_t recorder = NULL; CMYTH_REC_CALL(recorder, recorder == NULL, cmyth_spawn_live_tv(*m_recorder_t, 64*1024, 16*1024, MythRecorder::prog_update_callback, &pErr, const_cast<char*>(channel.Number().c_str()))); *m_recorder_t = recorder; /* JLB * wait chain update for 5000ms before continue */ int i = 0; while (*m_liveChainUpdated == 0 && i < 5000) { m_conn.Unlock(); usleep(100000); m_conn.Lock(); i += 100; XBMC->Log(LOG_DEBUG, "%s: Delay channel switch: %d", __FUNCTION__, i); } // m_recorder_t->Unlock(); m_conn.Unlock(); ASSERT(*m_recorder_t); if (pErr) XBMC->Log(LOG_ERROR,"%s - %s", __FUNCTION__, pErr); return pErr == NULL; }
bool MythRecorder::CheckChannel(MythChannel &channel) { int retval = 0; CMYTH_REC_CALL(retval, retval < 0, cmyth_recorder_check_channel(*m_recorder_t, const_cast<char*>(channel.Number().c_str()))); return retval == 1; }
bool PVRClientMythTV::OpenLiveStream(const PVR_CHANNEL &channel) { if (g_bExtraDebug) XBMC->Log(LOG_DEBUG,"%s - chanID: %i, channumber: %i", __FUNCTION__, channel.iUniqueId, channel.iChannelNumber); CLockObject lock(m_lock); if (m_rec.IsNull()) { // Suspend fileOps to avoid connection hang if (m_fileOps->IsRunning()) m_fileOps->Suspend(); // Enable playback mode: Keep quiet on connection if (m_pEventHandler) { m_pEventHandler->EnablePlayback(); } 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.ID() > 0 && !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)) return true; } m_rec = MythRecorder(); if (m_pEventHandler) { m_pEventHandler->SetRecorder(m_rec); // Redundant } } // Disable playback mode: Allow all if (m_pEventHandler) { m_pEventHandler->DisablePlayback(); } // Resume fileOps m_fileOps->Resume(); 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; } }
bool MythRecorder::SpawnLiveTV(MythChannel &channel) { bool ret = false; char* pErr = NULL; Lock(); // Check channel *m_liveChainUpdated = 0; cmyth_recorder_t recorder = NULL; recorder = cmyth_spawn_live_tv(*m_recorder_t, 64*1024, 64*1024, MythRecorder::prog_update_callback, &pErr, const_cast<char*>(channel.Number().c_str())); if (recorder && pErr == NULL) { *m_recorder_t = recorder; // Wait for chain update for 30s before break int i = 0; while (*m_liveChainUpdated == 0 && i < 30000) { // Release the latch to allow chain update Unlock(); usleep(100000); // Gets the latch before read chain status Lock(); i += 100; XBMC->Log(LOG_DEBUG, "%s: Delay channel switch: %d", __FUNCTION__, i); } if (*m_liveChainUpdated == 0) { XBMC->Log(LOG_ERROR,"%s - Chain update failed", __FUNCTION__); XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(30304)); // No response from MythTV backend } else ret = true; } else { // Dereference recorder to cancel callback *m_recorder_t = NULL; // Chain setup fails. Stop existing recorder ref_release(recorder); if (pErr) XBMC->Log(LOG_ERROR,"%s - %s", __FUNCTION__, pErr); XBMC->QueueNotification(QUEUE_ERROR, XBMC->GetLocalizedString(30306)); // Recorder unavailable } Unlock(); return ret; }