DTC::EncoderList* Dvr::GetEncoderList() { DTC::EncoderList* pList = new DTC::EncoderList(); QMap<int, EncoderLink *>::Iterator iter = tvList.begin(); for (; iter != tvList.end(); ++iter) { EncoderLink *elink = *iter; if (elink != NULL) { DTC::Encoder *pEncoder = pList->AddNewEncoder(); pEncoder->setId ( elink->GetCardID() ); pEncoder->setState ( elink->GetState() ); pEncoder->setLocal ( elink->IsLocal() ); pEncoder->setConnected ( elink->IsConnected() ); pEncoder->setSleepStatus ( elink->GetSleepStatus() ); // pEncoder->setLowOnFreeSpace( elink->isLowOnFreeSpace()); if (pEncoder->Local()) pEncoder->setHostName( gCoreContext->GetHostName() ); else pEncoder->setHostName( elink->GetHostName() ); switch ( pEncoder->State() ) { case kState_WatchingLiveTV: case kState_RecordingOnly: case kState_WatchingRecording: { ProgramInfo *pInfo = elink->GetRecording(); if (pInfo) { DTC::Program *pProgram = pEncoder->Recording(); FillProgramInfo( pProgram, pInfo, true, true ); delete pInfo; } break; } default: break; } } } return pList; }
/** \fn AutoExpire::CalcParams() * Calculates how much space needs to be cleared, and how often. */ void AutoExpire::CalcParams() { LOG(VB_FILE, LOG_INFO, LOC + "CalcParams()"); QList<FileSystemInfo> fsInfos; instance_lock.lock(); if (main_server) main_server->GetFilesystemInfos(fsInfos); instance_lock.unlock(); if (fsInfos.empty()) { LOG(VB_GENERAL, LOG_ERR, LOC + "Filesystem Info cache is empty, unable " "to calculate necessary parameters."); return; } uint64_t maxKBperMin = 0; uint64_t extraKB = static_cast<uint64_t> (gCoreContext->GetNumSetting("AutoExpireExtraSpace", 0)) << 20; QMap<int, uint64_t> fsMap; QMap<int, vector<int> > fsEncoderMap; // we use this copying on purpose. The used_encoders map ensures // that every encoder writes only to one fs. // Copying the data minimizes the time the lock is held instance_lock.lock(); QMap<int, int>::const_iterator ueit = used_encoders.begin(); while (ueit != used_encoders.end()) { fsEncoderMap[*ueit].push_back(ueit.key()); ++ueit; } instance_lock.unlock(); QList<FileSystemInfo>::iterator fsit; for (fsit = fsInfos.begin(); fsit != fsInfos.end(); ++fsit) { if (fsMap.contains(fsit->getFSysID())) continue; fsMap[fsit->getFSysID()] = 0; uint64_t thisKBperMin = 0; // append unknown recordings to all fsIDs vector<int>::iterator unknownfs_it = fsEncoderMap[-1].begin(); for (; unknownfs_it != fsEncoderMap[-1].end(); ++unknownfs_it) fsEncoderMap[fsit->getFSysID()].push_back(*unknownfs_it); if (fsEncoderMap.contains(fsit->getFSysID())) { LOG(VB_FILE, LOG_INFO, QString("fsID #%1: Total: %2 GB Used: %3 GB Free: %4 GB") .arg(fsit->getFSysID()) .arg(fsit->getTotalSpace() / 1024.0 / 1024.0, 7, 'f', 1) .arg(fsit->getUsedSpace() / 1024.0 / 1024.0, 7, 'f', 1) .arg(fsit->getFreeSpace() / 1024.0 / 1024.0, 7, 'f', 1)); vector<int>::iterator encit = fsEncoderMap[fsit->getFSysID()].begin(); for (; encit != fsEncoderMap[fsit->getFSysID()].end(); ++encit) { EncoderLink *enc = *(encoderList->find(*encit)); if (!enc->IsConnected() || !enc->IsBusy()) { // remove encoder since it can't write to any file system LOG(VB_FILE, LOG_INFO, LOC + QString("Cardid %1: is not recoding, removing it " "from used list.").arg(*encit)); instance_lock.lock(); used_encoders.remove(*encit); instance_lock.unlock(); continue; } uint64_t maxBitrate = enc->GetMaxBitrate(); if (maxBitrate<=0) maxBitrate = 19500000LL; thisKBperMin += (((uint64_t)maxBitrate)*((uint64_t)15))>>11; LOG(VB_FILE, LOG_INFO, QString(" Cardid %1: max bitrate " "%2 Kb/sec, fsID %3 max is now %4 KB/min") .arg(enc->GetCardID()) .arg(enc->GetMaxBitrate() >> 10) .arg(fsit->getFSysID()) .arg(thisKBperMin)); } } fsMap[fsit->getFSysID()] = thisKBperMin; if (thisKBperMin > maxKBperMin) { LOG(VB_FILE, LOG_INFO, QString(" Max of %1 KB/min for fsID %2 is higher " "than the existing Max of %3 so we'll use this Max instead") .arg(thisKBperMin).arg(fsit->getFSysID()).arg(maxKBperMin)); maxKBperMin = thisKBperMin; } }