DvbTunerTechnicalInfo V4LHelper::GetTechnicalInfo() { DvbTunerTechnicalInfo result; memset(&result, 0, sizeof(result)); if (m_frontendHandle == -1) return result; fe_status_t status; if (ioctl(m_frontendHandle, FE_READ_STATUS, &status) >= 0) { result.fe_status = (unsigned int) status; } result.signal = GetSignal(); result.snr = GetSNR(); result.ber = GetBER(); result.ucb = GetUCB(); return result; }
int V4LHelper::Read(char * buf, int size) { CSingleLock lock(m_lock); static bool timeout = false; if (m_frontendHandle <= 0) return -1; // Check the signal once a second if (m_tuningState == DvbTuner::TUNING_STATE_TUNED && SDL_GetTicks() - m_lastSignalCheckTicks > 1000) { uint16_t signal = GetSignal(); uint16_t snr = GetSNR(); if ((signal > 140 || signal == 0) && (snr > 100 || snr == 0)) m_signalOk = true; else m_signalOk = false; // printf("signal=%d snr=%d signalok=%s\n", signal, snr, m_signalOk ? "true" : "false"); m_lastSignalCheckTicks = SDL_GetTicks(); } struct pollfd ufd[2]; int n; ufd[0].fd = m_frontendHandle; ufd[0].events = POLLIN; n = 1; if(m_dvr > 0) { ufd[1].fd = m_dvr; ufd[1].events = POLLIN; n = 2; } // we put one second timeout for video to come out. // if it doesn't then we reopen devices int rc = poll(ufd, n, 1000); if (rc == -1 && errno == EINTR) { return 0; } if (rc < 0) { CLog::Log(LOGERROR, "%s poll failed: %s", __func__, strerror(errno)); return -1; } // if dvr is open and we get a timeout, reopen devices if(m_dvr > 0 && rc == 0) { CLog::Log(LOGWARNING, "V4LHelper::Read DVR timeout. Reopening frontend"); CloseFrontEnd(); CloseDVR(); Sleep(100); OpenFrontEnd(); m_tuningState = DvbTuner::TUNING_STATE_TUNING; Tune(m_frontend_settings); } int bytesRead = 0; struct dvb_frontend_event ev; if (ufd[0].revents) { if (ioctl(m_frontendHandle, FE_GET_EVENT, &ev) < 0) { if (errno == EOVERFLOW) { CLog::Log(LOGWARNING, "Cannot dequeue events fast enough from frontend. Doing nothing"); return 0; } else CLog::Log(LOGERROR, "Cannot dequeue frontend event: %s", strerror(errno)); } else { CLog::Log(LOGINFO, "Got frontend event. status: 0x%02X", (unsigned) ev.status); if (ev.status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) { m_tuningState = DvbTuner::TUNING_STATE_TUNED; CloseDVR(); } else if (m_tuningState == DvbTuner::TUNING_STATE_TUNED) m_tuningState = DvbTuner::TUNING_STATE_TUNE_FAILED; } } if (m_dvr > 0 && n == 2 && ufd[1].revents) { ssize_t val = read(m_dvr, buf, size); if (val == -1 && (errno != EAGAIN && errno != EINTR)) { if (errno == EOVERFLOW) { CLog::Log(LOGWARNING, "Cannot read dvr data fast enough. Doing nothing"); return 0; } CLog::Log(LOGERROR, "Error reading from dvr: %d %s", m_dvr, strerror(errno) ); bytesRead = -1; } else if (val > 0) { bytesRead = val; } } if(m_tuningState == DvbTuner::TUNING_STATE_TUNED) { if(m_dvr < 0) { Sleep(100); OpenDVR(); } } return bytesRead; }
static int dvbfe_read_snr(struct dvb_frontend* fe, u16* snr) { DECLARE_DEV; DBG_fCDVBFE("calling GetSNR()\n"); return GetSNR(p->context, snr); }