void FirewireSignalMonitor::AddData(const unsigned char *data, uint len) { if (!dtvMonitorRunning) return; if (GetStreamData()) GetStreamData()->ProcessData((unsigned char *)data, len); }
/** \fn ExternalSignalMonitor::UpdateValues(void) * \brief Fills in frontend stats and emits status Qt signals. * * This is automatically called by run(), after Start() * has been used to start the signal monitoring thread. */ void ExternalSignalMonitor::UpdateValues(void) { if (!running || exit) return; if (m_stream_handler_started) { if (!m_stream_handler->IsRunning()) { error = QObject::tr("Error: stream handler died"); LOG(VB_CHANNEL, LOG_ERR, LOC + error); update_done = true; return; } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); update_done = true; return; } AddFlags(kSigMon_WaitForSig); int strength = GetSignalStrengthPercent(); bool is_locked = HasLock(); // Set SignalMonitorValues { QMutexLocker locker(&statusLock); signalStrength.SetValue(strength); signalLock.SetValue(is_locked); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (is_locked && GetStreamData() && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { if (!m_stream_handler_started) { m_stream_handler->AddListener(GetStreamData()); m_stream_handler->StartStreaming(false); m_stream_handler_started = true; } } update_done = true; }
/** \fn DVBSignalMonitor::Stop(void) * \brief Stop signal monitoring and table monitoring threads. */ void DVBSignalMonitor::Stop(void) { VERBOSE(VB_CHANNEL, LOC + "Stop() -- begin"); SignalMonitor::Stop(); if (GetStreamData()) streamHandler->RemoveListener(GetStreamData()); streamHandlerStarted = false; streamHandler->SetRetuneAllowed(false, NULL, NULL); VERBOSE(VB_CHANNEL, LOC + "Stop() -- end"); }
/** \fn ASISignalMonitor::Stop(void) * \brief Stop signal monitoring and table monitoring threads. */ void ASISignalMonitor::Stop(void) { LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin"); SignalMonitor::Stop(); if (GetStreamData()) streamHandler->RemoveListener(GetStreamData()); streamHandlerStarted = false; LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end"); }
/** \fn ExternalSignalMonitor::Stop(void) * \brief Stop signal monitoring and table monitoring threads. */ void ExternalSignalMonitor::Stop(void) { QString result; LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin"); m_stream_handler->StopStreaming(); SignalMonitor::Stop(); if (GetStreamData()) m_stream_handler->RemoveListener(GetStreamData()); m_stream_handler_started = false; LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end"); }
void FirewireSignalMonitor::HandlePAT(const ProgramAssociationTable *pat) { AddFlags(kDTVSigMon_PATSeen); FirewireChannel *fwchan = dynamic_cast<FirewireChannel*>(channel); if (!fwchan) return; bool crc_bogus = !fwchan->GetFirewireDevice()->IsSTBBufferCleared(); if (crc_bogus && stb_needs_to_wait_for_pat && (stb_wait_for_pat_timer.elapsed() < (int)kBufferTimeout)) { LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePAT() ignoring PAT"); uint tsid = pat->TransportStreamID(); GetStreamData()->SetVersionPAT(tsid, -1,0); return; } if (crc_bogus && stb_needs_to_wait_for_pat) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Wait for valid PAT timed out"); stb_needs_to_wait_for_pat = false; } DTVSignalMonitor::HandlePAT(pat); }
void DVBSignalMonitor::HandleSTT(const SystemTimeTable *stt) { DTVSignalMonitor::HandleSTT(stt); DVBChannel *dvbchannel = GetDVBChannel(); if (dvbchannel) dvbchannel->SetTimeOffset(GetStreamData()->TimeOffset()); }
void DVBSignalMonitor::HandleTDT(const TimeDateTable *tdt) { DTVSignalMonitor::HandleTDT(tdt); DVBChannel *dvbchannel = GetDVBChannel(); if (dvbchannel) dvbchannel->SetTimeOffset(GetStreamData()->TimeOffset()); }
bool DTVRecorder::FindAudioKeyframes(const TSPacket*) { bool hasKeyFrame = false; if (!ringBuffer || (GetStreamData()->VideoPIDSingleProgram() <= 0x1fff)) return hasKeyFrame; static const uint64_t msec_per_day = 24 * 60 * 60 * 1000ULL; const double frame_interval = (1000.0 / video_frame_rate); uint64_t elapsed = (uint64_t) max(_audio_timer.elapsed(), 0); uint64_t expected_frame = (uint64_t) ((double)elapsed / frame_interval); while (_frames_seen_count > expected_frame + 10000) expected_frame += (uint64_t) ((double)msec_per_day / frame_interval); if (!_frames_seen_count || (_frames_seen_count < expected_frame)) { if (!_frames_seen_count) _audio_timer.start(); _frames_seen_count++; if (1 == (_frames_seen_count & 0x7)) { _last_keyframe_seen = _frames_seen_count; HandleKeyframe(); hasKeyFrame = true; } if (!_wait_for_keyframe_option || _first_keyframe>=0) _frames_written_count++; } return hasKeyFrame; }
/** \fn CetonSignalMonitor::UpdateValues(void) * \brief Fills in frontend stats and emits status Qt signals. * * This is automatically called by MonitorLoop(), after Start() * has been used to start the signal monitoring thread. */ void CetonSignalMonitor::UpdateValues(void) { if (!running || exit) return; if (streamHandlerStarted) { EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // TODO dtv signals... update_done = true; return; } uint sig = 100; // TODO find some way to actually monitor signal level // Set SignalMonitorValues from info from card. bool isLocked = false; { QMutexLocker locker(&statusLock); signalStrength.SetValue(sig); signalLock.SetValue(true); // TODO add some way to indicate if there is actually a lock isLocked = signalLock.IsGood(); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (isLocked && GetStreamData() && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { streamHandler->AddListener(GetStreamData()); streamHandlerStarted = true; } update_done = true; }
/** \fn IPTVSignalMonitor::UpdateValues(void) * \brief Fills in frontend stats and emits status Qt signals. * * This is automatically called by run(), after Start() * has been used to start the signal monitoring thread. */ void IPTVSignalMonitor::UpdateValues(void) { if (lock_timer.elapsed() > m_lock_timeout) error = "Timed out."; if (!running || exit) return; if (m_streamHandlerStarted) { EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // TODO dtv signals... update_done = true; return; } bool isLocked = false; { QMutexLocker locker(&statusLock); isLocked = signalLock.IsGood(); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (isLocked && GetStreamData() && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { GetChannel()->SetStreamData(GetStreamData()); m_streamHandlerStarted = true; } update_done = true; }
/** \fn ASISignalMonitor::UpdateValues(void) * \brief Fills in frontend stats and emits status Qt signals. * * This is automatically called by MonitorLoop(), after Start() * has been used to start the signal monitoring thread. */ void ASISignalMonitor::UpdateValues(void) { if (!running || exit) return; if (streamHandlerStarted) { EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // TODO dtv signals... update_done = true; return; } // Set SignalMonitorValues from info from card. bool isLocked = true; { QMutexLocker locker(&statusLock); signalStrength.SetValue(100); signalLock.SetValue(1); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (isLocked && GetStreamData() && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { streamHandler->AddListener(GetStreamData()); streamHandlerStarted = true; } update_done = true; }
bool FirewireRecorder::ProcessTSPacket(const TSPacket &tspacket) { if (tspacket.TransportError()) return true; if (tspacket.Scrambled()) return true; if (tspacket.HasAdaptationField()) GetStreamData()->HandleAdaptationFieldControl(&tspacket); if (tspacket.HasPayload()) { const unsigned int lpid = tspacket.PID(); // Pass or reject packets based on PID, and parse info from them if (lpid == GetStreamData()->VideoPIDSingleProgram()) { _buffer_packets = !FindMPEG2Keyframes(&tspacket); BufferedWrite(tspacket); } else if (GetStreamData()->IsAudioPID(lpid)) { _buffer_packets = !FindAudioKeyframes(&tspacket); BufferedWrite(tspacket); } else if (GetStreamData()->IsListeningPID(lpid)) GetStreamData()->HandleTSTables(&tspacket); else if (GetStreamData()->IsWritingPID(lpid)) BufferedWrite(tspacket); } return true; }
bool FirewireRecorder::ProcessTSPacket(const TSPacket &tspacket) { const uint pid = tspacket.PID(); if (pid == 0x1fff) // Stuffing return true; if (tspacket.TransportError()) return true; if (tspacket.Scrambled()) return true; if (tspacket.HasAdaptationField()) GetStreamData()->HandleAdaptationFieldControl(&tspacket); if (GetStreamData()->IsVideoPID(tspacket.PID())) return ProcessVideoTSPacket(tspacket); if (GetStreamData()->IsAudioPID(tspacket.PID())) return ProcessAudioTSPacket(tspacket); if (GetStreamData()->IsWritingPID(tspacket.PID())) BufferedWrite(tspacket); if (GetStreamData()->IsListeningPID(tspacket.PID()) && tspacket.HasPayload()) GetStreamData()->HandleTSTables(&tspacket); return true; }
void FirewireSignalMonitor::HandlePMT(uint pnum, const ProgramMapTable *pmt) { LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT()"); AddFlags(kDTVSigMon_PMTSeen); if (!HasFlags(kDTVSigMon_PATMatch)) { GetStreamData()->SetVersionPMT(pnum, -1,0); LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT() ignoring PMT"); return; } DTVSignalMonitor::HandlePMT(pnum, pmt); }
/** \fn IPTVSignalMonitor::RunTableMonitor(void) */ void IPTVSignalMonitor::RunTableMonitor(void) { DBG_SM("Run", "begin"); dtvMonitorRunning = true; GetStreamData()->AddListeningPID(0); GetChannel()->GetFeeder()->AddListener(this); GetChannel()->GetFeeder()->Run(); GetChannel()->GetFeeder()->RemoveListener(this); while (dtvMonitorRunning) usleep(10000); DBG_SM("Run", "end"); }
/** \fn IPTVSignalMonitor::UpdateValues(void) * \brief Fills in frontend stats and emits status Qt signals. * * This is automatically called by run(), after Start() * has been used to start the signal monitoring thread. */ void IPTVSignalMonitor::UpdateValues(void) { if (!running || exit) return; if (dtvMonitorRunning) { EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // TODO dtv signals... update_done = true; return; } bool isLocked = false; { QMutexLocker locker(&statusLock); isLocked = signalLock.IsGood(); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (isLocked && GetStreamData() && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { tableMonitorThread = new IPTVTableMonitorThread(this); DBG_SM("UpdateValues", "Waiting for table monitor to start"); while (!dtvMonitorRunning) usleep(5000); DBG_SM("UpdateValues", "Table monitor started"); } update_done = true; }
/// Non-Audio/Video data. For streams which contain no audio/video, /// write just 1 key-frame at the start. bool DTVRecorder::FindOtherKeyframes(const TSPacket *tspacket) { if (!ringBuffer || (GetStreamData()->VideoPIDSingleProgram() <= 0x1fff)) return true; if (_has_written_other_keyframe) return true; VERBOSE(VB_RECORD, LOC + "DSMCC - FindOtherKeyframes() - " "generating initial key-frame"); _frames_seen_count++; _frames_written_count++; _last_keyframe_seen = _frames_seen_count; HandleKeyframe(); _has_written_other_keyframe = true; return true; }
void FirewireSignalMonitor::RunTableMonitor(void) { stb_needs_to_wait_for_pat = true; stb_wait_for_pat_timer.start(); dtvMonitorRunning = true; LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- begin"); FirewireChannel *lchan = dynamic_cast<FirewireChannel*>(channel); if (!lchan) { LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err"); while (dtvMonitorRunning) usleep(10000); LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err end"); return; } FirewireDevice *dev = lchan->GetFirewireDevice(); dev->OpenPort(); dev->AddListener(this); while (dtvMonitorRunning && GetStreamData()) usleep(10000); LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- shutdown "); dev->RemoveListener(this); dev->ClosePort(); while (dtvMonitorRunning) usleep(10000); LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- end"); }
void DVBRecorder::UpdateCAMTimeOffset(void) { _channel->SetTimeOffset(GetStreamData()->TimeOffset()); }
DWORD COpenALSoundUtility::OnAddSound(DWORD size, void *params) { VERIFY_MESSAGE_SIZE(sizeof(ADDSOUNDOBJECTPARAMS), size); ADDSOUNDOBJECTPARAMS *asparams = (ADDSOUNDOBJECTPARAMS *) params; IHashString *fileName = asparams->FileName; IHashString *ext = asparams->fileType; IEEStream *fileStream = asparams->fileStream; static CHashString hsWav(_T("wav")); static CHashString hsOgg(_T("ogg")); if ((fileName) && (ext) && (fileStream)) { if (ext->GetUniqueID() == hsWav.GetUniqueID()) { // can't stream wav files with alut function, so we have to load the whole thing // and add to buffer list AUDIOBUFFERMAPBYFILE::iterator iter = m_AudioBufferMap.find(fileName->GetUniqueID()); if ( iter == m_AudioBufferMap.end() ) { ALenum err; // now we have to load this raw buffer into OpenAL ALuint soundBuffer; void *data; UINT buffSize; data = GetStreamData(fileStream, &buffSize); if (data == NULL) { m_ToolBox->Log(LOGWARNING, _T("Sound manager: could not buffer data from stream for file %s\n"), fileName->GetString()); return MSG_NOT_HANDLED; } soundBuffer = alutCreateBufferFromFileImage(data, buffSize); free(data); err = alutGetError(); if (err != ALUT_ERROR_NO_ERROR) { m_ToolBox->SetErrorValue(ERR_NULL_POINTER); m_ToolBox->Log( LOGWARNING, _T("Sound manager: alut couldn't buffer the data for file %s: %s\n"), fileName->GetString(), alutGetErrorString(err)); return MSG_ERROR; } int size = 0; if (GetALBufferI(soundBuffer, AL_SIZE, &size, __FILE__, __LINE__)) { AddALMemUsageBytes((UINT)size); } m_AudioBufferMap[fileName->GetUniqueID()] = soundBuffer; } } else if (ext->GetUniqueID() == hsOgg.GetUniqueID()) { // ogg files sorta have to be streamed, not really, but it'll probably help, // so we have to copy the file data and make buffers at play time AUDIOBUFFERMAPBYFILE::iterator bufferIter = m_AudioBufferMap.find(fileName->GetUniqueID()); BUFFERSTREAMDATABYFILE::iterator streamIter = m_BufferStreamMap.find(fileName->GetUniqueID()); if ((streamIter == m_BufferStreamMap.end()) && (bufferIter == m_AudioBufferMap.end())) { // at some point, we may need to stream from disk, but for now, go ahead and load everything into // a mem stream -- the beauty of this system is that the IEEStream can be a file stream or a mem // stream and the buffers will still function void *data; UINT buffSize; data = GetStreamData(fileStream, &buffSize); // NOTE: do not free this data here; it will be freed in the mem stream when it deinits CREATESTREAM cs; cs.mode = STREAM_MODE_READ; cs.streamData = data; cs.streamSize = buffSize; static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID(); DWORD retval = m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs); if ((retval != MSG_HANDLED) || (cs.openStream == NULL)) { m_ToolBox->Log(LOGWARNING, _T("Sound manager: could not create mem stream to store file data!\n")); free(data); return MSG_NOT_HANDLED; } else { // now check to see if this file is in the map, and if so, if we're caching buffers bool bKeepMemStream = true; FILETOKEYMAP::iterator fileMapIter = m_FileToKeyMap.find(fileName->GetUniqueID()); if (fileMapIter != m_FileToKeyMap.end()) { SOUNDKEYMAP::iterator mapIter = m_SoundMap.find(fileMapIter->second); if (mapIter != m_SoundMap.end()) { if (mapIter->second.bCachedUncompressed) { bKeepMemStream = false; COGGSoundBufferStream tempBufferStream(fileName, cs.openStream); ALuint tempBuffer; tempBuffer = tempBufferStream.BufferFullSound(); m_AudioBufferMap[fileName->GetUniqueID()] = tempBuffer; } } } if (bKeepMemStream) { m_BufferStreamMap[fileName->GetUniqueID()].pStream = cs.openStream; m_BufferStreamMap[fileName->GetUniqueID()].pData = data; } else { cs.openStream->Close(); free(data); } } } } // close and delete stream fileStream->Close(); delete fileStream; } return MSG_HANDLED_STOP; }
void IPTVSignalMonitor::SetStreamData(MPEGStreamData *data) { DTVSignalMonitor::SetStreamData(data); GetChannel()->SetStreamData(GetStreamData()); }
void iUniStream::SafeCast(T& c) { USBits mask(0, US_MASK_BIT_SIZE); *this >> mask; switch (mask.bits) { case US_MASK_UINT_8: { unsigned char cC = 0; Receive8(cC); c = (T)cC; } break; case US_MASK_SINT_8: { unsigned char cC = 0; Receive8(cC); signed char cSigned = reinterpret_cast<signed char&>(cC); c = (T)cSigned; } break; case US_MASK_UINT_16: { unsigned short cC = 0; Receive16(cC); c = (T)cC; } break; case US_MASK_SINT_16: { unsigned short cC = 0; Receive16(cC); signed short cSigned = reinterpret_cast<signed short&>(cC); c = (T)cSigned; } break; case US_MASK_UINT_32: { unsigned long cC = 0; Receive32(cC); c = (T)cC; } break; case US_MASK_SINT_32: { unsigned long cC = 0; Receive32(cC); signed long cSigned = reinterpret_cast<signed long&>(cC); c = (T)cSigned; } break; case US_MASK_UINT_64: { unsigned long long cC = 0; Receive64(cC); c = (T)cC; } break; case US_MASK_SINT_64: { unsigned long long cC = 0; Receive64(cC); signed long long cSigned = reinterpret_cast<signed long long&>(cC); c = (T)cSigned; } break; case US_MASK_CHAR_16: { unsigned short cC = 0; Receive16(cC); if (sizeof(char16_t) == 2) { usUint16_t tmp = (usUint16_t)(cC); char16_t ch = reinterpret_cast<char16_t&>(tmp); c = (T)ch; } else if(sizeof(char16_t) == 4) { usUint32_t tmp = (usUint32_t)(cC); char32_t ch = reinterpret_cast<char32_t&>(tmp); c = (T)ch; } else { UNHANDLED_CASE(); } } break; case US_MASK_CHAR_32: { unsigned long cC = 0; Receive32(cC); if(sizeof(char32_t) == 4) { usUint32_t tmp = (usUint32_t)(cC); char32_t ch = reinterpret_cast<char32_t&>(tmp); c = (T)ch; } else if (sizeof(char32_t) == 8) { usUint64_t tmp = (usUint64_t)(cC); char32_t ch = reinterpret_cast<char32_t&>(tmp); c = (T)ch; } else { UNHANDLED_CASE(); } } break; case US_MASK_FLOAT_32: { unsigned long cC = 0; CopyNum32(cC); if (sizeof(float) == 4) { usUint32_t tmp = (usUint32_t)(cC); float ch = reinterpret_cast<float&>(tmp); c = (T)ch; } else { UNHANDLED_CASE(); } } break; case US_MASK_DOUBLE_64: { unsigned long long cC = 0; CopyNum64(cC); if (sizeof(long long) == 8) { usUint64_t tmp = (usUint64_t)(cC); double ch = reinterpret_cast<double&>(tmp); c = (T)ch; } else { UNHANDLED_CASE(); } } break; case US_MASK_BOOL_1: { USBits boolMask(1, 1); GetStreamData(boolMask); bool val = (boolMask.bits == 1); c = (T)val; } break; default: UNHANDLED_CASE(); break; } }
void IPTVSignalMonitor::AddData( const unsigned char *data, unsigned int dataSize) { GetStreamData()->ProcessData((unsigned char*)data, dataSize); }
/** \fn DVBSignalMonitor::UpdateValues() * \brief Fills in frontend stats and emits status Qt signals. * * This is automatically called by MonitorLoop(), after Start() * has been used to start the signal monitoring thread. */ void DVBSignalMonitor::UpdateValues(void) { if (!running || exit) return; if (streamHandlerStarted) { if (!streamHandler->IsRunning()) { error = QObject::tr("Error: stream handler died"); update_done = true; return; } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // TODO dtv signals... update_done = true; return; } AddFlags(kSigMon_WaitForSig); DVBChannel *dvbchannel = GetDVBChannel(); if (!dvbchannel) return; // Handle retuning after rotor has turned if (HasFlags(SignalMonitor::kDVBSigMon_WaitForPos)) { if (dvbchannel->GetRotor()) { if (!streamHandler->IsRetuneAllowed()) streamHandler->SetRetuneAllowed(true, this, dvbchannel); streamHandler->RetuneMonitor(); } else RemoveFlags(SignalMonitor::kDVBSigMon_WaitForPos); } bool wasLocked = false, isLocked = false; uint sig = 0, snr = 0, ber = 0, ublocks = 0; // Get info from card bool has_lock = dvbchannel->HasLock(); if (HasFlags(kSigMon_WaitForSig)) sig = (uint) (dvbchannel->GetSignalStrength() * 65535); if (HasFlags(kDVBSigMon_WaitForSNR)) snr = (uint) (dvbchannel->GetSNR() * 65535); if (HasFlags(kDVBSigMon_WaitForBER)) ber = (uint) dvbchannel->GetBitErrorRate(); if (HasFlags(kDVBSigMon_WaitForUB)) ublocks = (uint) dvbchannel->GetUncorrectedBlockCount(); has_lock |= streamHandler->IsRunning(); // Set SignalMonitorValues from info from card. { QMutexLocker locker(&statusLock); // BER and UB are actually uint32 values, but we // clamp them at 64K. This is because these values // are acutally cumulative, but we don't try to // normalize these to a time period. wasLocked = signalLock.IsGood(); signalLock.SetValue((has_lock) ? 1 : 0); isLocked = signalLock.IsGood(); if (HasFlags(kSigMon_WaitForSig)) signalStrength.SetValue(sig); if (HasFlags(kDVBSigMon_WaitForSNR)) signalToNoise.SetValue(snr); if (HasFlags(kDVBSigMon_WaitForBER)) bitErrorRate.SetValue(ber); if (HasFlags(kDVBSigMon_WaitForUB)) uncorrectedBlocks.SetValue(ublocks); } // Debug output if (wasLocked != isLocked) { VERBOSE(VB_CHANNEL, LOC + "UpdateValues -- Signal " <<(isLocked ? "Locked" : "Lost")); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (isLocked && GetStreamData() && (!HasFlags(kDVBSigMon_WaitForPos) || rotorPosition.IsGood()) && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { GetStreamData()->AddListeningPID(MPEG_PAT_PID); streamHandler->AddListener(GetStreamData(), true, false); streamHandlerStarted = true; } update_done = true; }
/** \fn FirewireSignalMonitor::UpdateValues(void) * \brief Fills in frontend stats and emits status Qt signals. * * This function uses five ioctl's FE_READ_SNR, FE_READ_SIGNAL_STRENGTH * FE_READ_BER, FE_READ_UNCORRECTED_BLOCKS, and FE_READ_STATUS to obtain * statistics from the frontend. * * This is automatically called by MonitorLoop(), after Start() * has been used to start the signal monitoring thread. */ void FirewireSignalMonitor::UpdateValues(void) { if (!running || exit) return; if (dtvMonitorRunning) { EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // TODO dtv signals... update_done = true; return; } if (stb_needs_to_wait_for_power && (stb_wait_for_power_timer.elapsed() < (int)kPowerTimeout)) { return; } stb_needs_to_wait_for_power = false; FirewireChannel *fwchan = dynamic_cast<FirewireChannel*>(channel); if (!fwchan) return; if (HasFlags(kFWSigMon_WaitForPower) && !HasFlags(kFWSigMon_PowerMatch)) { bool retried = false; while (true) { FirewireDevice::PowerState power = fwchan->GetPowerState(); if (FirewireDevice::kAVCPowerOn == power) { AddFlags(kFWSigMon_PowerSeen | kFWSigMon_PowerMatch); } else if (FirewireDevice::kAVCPowerOff == power) { AddFlags(kFWSigMon_PowerSeen); fwchan->SetPowerState(true); stb_wait_for_power_timer.start(); stb_needs_to_wait_for_power = true; } else { bool qfailed = (FirewireDevice::kAVCPowerQueryFailed == power); if (qfailed && !retried) { retried = true; continue; } LOG(VB_RECORD, LOG_WARNING, "Can't determine if STB is power on, assuming it is..."); AddFlags(kFWSigMon_PowerSeen | kFWSigMon_PowerMatch); } break; } } bool isLocked = !HasFlags(kFWSigMon_WaitForPower) || HasFlags(kFWSigMon_WaitForPower | kFWSigMon_PowerMatch); if (isLocked && stb_needs_retune) { fwchan->Retune(); isLocked = stb_needs_retune = false; } SignalMonitor::UpdateValues(); { QMutexLocker locker(&statusLock); if (!scriptStatus.IsGood()) return; } // Set SignalMonitorValues from info from card. { QMutexLocker locker(&statusLock); signalStrength.SetValue(isLocked ? 100 : 0); signalLock.SetValue(isLocked ? 1 : 0); } EmitStatus(); if (IsAllGood()) SendMessageAllGood(); // Start table monitoring if we are waiting on any table // and we have a lock. if (isLocked && GetStreamData() && HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT | kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT | kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT)) { tableMonitorThread = new FirewireTableMonitorThread(this); LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- " "Waiting for table monitor to start"); while (!dtvMonitorRunning) usleep(5000); LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- " "Table monitor started"); } update_done = true; }