Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
  }
}
Exemplo n.º 7
0
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;
}