PVR_ERROR CHTSPData::AddTimer(const PVR_TIMER &timer) { XBMC->Log(LOG_DEBUG, "%s - channelUid=%d title=%s epgid=%d", __FUNCTION__, timer.iClientChannelUid, timer.strTitle, timer.iEpgUid); time_t startTime = timer.startTime; if (startTime <= 0) { int iGmtOffset; GetBackendTime(&startTime, &iGmtOffset); } htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "addDvrEntry"); htsmsg_add_u32(msg, "eventId", -1); // XXX tvheadend doesn't correct epg tags with wrong start and end times, so we'll use xbmc's values htsmsg_add_str(msg, "title", timer.strTitle); htsmsg_add_u32(msg, "start", startTime); htsmsg_add_u32(msg, "stop", timer.endTime); htsmsg_add_u32(msg, "channelId", timer.iClientChannelUid); htsmsg_add_u32(msg, "priority", timer.iPriority); htsmsg_add_str(msg, "description", timer.strSummary); htsmsg_add_str(msg, "creator", "XBMC"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get addDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } const char *strError = NULL; if ((strError = htsmsg_get_str(msg, "error"))) { XBMC->Log(LOG_DEBUG, "%s - Error adding timer: '%s'", __FUNCTION__, strError); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
bool cXVDRData::SetUpdateChannels(uint8_t method) { cRequestPacket vrp; if (!vrp.init(XVDR_UPDATECHANNELS)) return false; if (!vrp.add_U8(method)) return false; cResponsePacket* vresp = ReadResult(&vrp); if (!vresp) { XBMC->Log(LOG_INFO, "Setting channel update method not supported by server. Consider updating the XVDR server."); return false; } XBMC->Log(LOG_INFO, "Channel update method set to %i", method); uint32_t ret = vresp->extract_U32(); delete vresp; return ret == XVDR_RET_OK ? true : false; }
bool cVNSIChannelScan::ReadCountries() { m_spinCountries = GUI->Control_getSpin(m_window, CONTROL_SPIN_COUNTRIES); m_spinCountries->Clear(); CStdString dvdlang = XBMC->GetDVDMenuLanguage(); dvdlang = dvdlang.ToUpper(); cRequestPacket vrp; if (!vrp.init(VDR_SCAN_GETCOUNTRIES)) return false; cResponsePacket* vresp = ReadResult(&vrp); if (!vresp) return false; int startIndex = -1; uint32_t retCode = vresp->extract_U32(); if (retCode == VDR_RET_OK) { while (!vresp->end()) { uint32_t index = vresp->extract_U32(); const char *isoName = vresp->extract_String(); const char *longName = vresp->extract_String(); m_spinCountries->AddLabel(longName, index); if (dvdlang == isoName) startIndex = index; delete[] longName; delete[] isoName; } if (startIndex >= 0) m_spinCountries->SetValue(startIndex); } else { XBMC->Log(LOG_ERROR, "cVNSIChannelScan::ReadCountries() - Return error after reading countries (%i)", retCode); } delete vresp; return retCode == VDR_RET_OK; }
virtual ReadResult readObject(const std::string& uri, const Options* options) const { if ( "osgearth_engine_mp" == osgDB::getFileExtension( uri ) ) { if ( "earth" == osgDB::getNameLessExtension( osgDB::getFileExtension( uri ) ) ) { return readNode( uri, options ); } else { MPTerrainEngineOptions terrainOpts; OE_INFO << LC << "Activated!" << std::endl; return ReadResult( new MPTerrainEngineNode() ); } } else { return readNode( uri, options ); } }
bool cXVDRData::SupportChannelScan() { cRequestPacket vrp; if (!vrp.init(XVDR_SCAN_SUPPORTED)) { XBMC->Log(LOG_ERROR, "%s - Can't init cRequestPacket", __FUNCTION__); return false; } cResponsePacket* vresp = ReadResult(&vrp); if (!vresp) { XBMC->Log(LOG_ERROR, "%s - Can't get response packet", __FUNCTION__); return false; } uint32_t ret = vresp->extract_U32(); delete vresp; return ret == XVDR_RET_OK ? true : false; }
int cXVDRData::GetRecordingsCount() { cRequestPacket vrp; if (!vrp.init(XVDR_RECORDINGS_GETCOUNT)) { XBMC->Log(LOG_ERROR, "%s - Can't init cRequestPacket", __FUNCTION__); return -1; } cResponsePacket* vresp = ReadResult(&vrp); if (!vresp) { XBMC->Log(LOG_ERROR, "%s - Can't get response packet", __FUNCTION__); return -1; } uint32_t count = vresp->extract_U32(); delete vresp; return count; }
void cVNSIChannelScan::StopScan() { cRequestPacket vrp; if (!vrp.init(VDR_SCAN_STOP)) return; cResponsePacket* vresp = ReadResult(&vrp); if (!vresp) return; uint32_t retCode = vresp->extract_U32(); if (retCode != VDR_RET_OK) { XBMC->Log(LOG_ERROR, "cVNSIChannelScan::StopScan() - Return error after stop (%i)", retCode); m_window->SetControlLabel(LABEL_STATUS, XBMC->GetLocalizedString(24071)); m_window->SetControlLabel(BUTTON_START, XBMC->GetLocalizedString(30024)); m_window->SetControlLabel(HEADER_LABEL, XBMC->GetLocalizedString(30043)); m_stopped = true; } return; }
PVR_ERROR cHTSPData::DeleteTimer(const PVR_TIMERINFO &timerinfo, bool force) { XBMC->Log(LOG_DEBUG, "%s", __FUNCTION__); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "deleteDvrEntry"); htsmsg_add_u32(msg, "id", timerinfo.index); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get deleteDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
PVR_ERROR CHTSPData::DeleteRecording(const PVR_RECORDING &recording) { XBMC->Log(LOG_DEBUG, "%s", __FUNCTION__); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "deleteDvrEntry"); htsmsg_add_u32(msg, "id", atoi(recording.strRecordingId)); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get deleteDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
bool CHTSPData::GetDriveSpace(long long *total, long long *used) { htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "getDiskSpace"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - failed to get getDiskSpace", __FUNCTION__); return false; } int64_t freespace; if (htsmsg_get_s64(msg, "freediskspace", &freespace) != 0) return false; int64_t totalspace; if (htsmsg_get_s64(msg, "totaldiskspace", &totalspace) != 0) return false; *total = totalspace / 1024; *used = (totalspace - freespace) / 1024; return true; }
PVR_ERROR cXVDRData::DeleteRecording(const PVR_RECORDING& recinfo) { cRequestPacket vrp; if (!vrp.init(XVDR_RECORDINGS_DELETE)) { XBMC->Log(LOG_ERROR, "%s - Can't init cRequestPacket", __FUNCTION__); return PVR_ERROR_UNKNOWN; } if (!vrp.add_String(recinfo.strRecordingId)) return PVR_ERROR_UNKNOWN; cResponsePacket* vresp = ReadResult(&vrp); if (vresp == NULL || vresp->noResponse()) { delete vresp; return PVR_ERROR_UNKNOWN; } uint32_t returnCode = vresp->extract_U32(); delete vresp; switch(returnCode) { case XVDR_RET_DATALOCKED: return PVR_ERROR_NOT_DELETED; case XVDR_RET_RECRUNNING: return PVR_ERROR_RECORDING_RUNNING; case XVDR_RET_DATAINVALID: return PVR_ERROR_NOT_POSSIBLE; case XVDR_RET_ERROR: return PVR_ERROR_SERVER_ERROR; } return PVR_ERROR_NO_ERROR; }
PVR_ERROR cHTSPData::AddTimer(const PVR_TIMERINFO &timerinfo) { XBMC->Log(LOG_DEBUG, "%s - channelNumber=%d channelUid=%d title=%s epgid=%d", __FUNCTION__, timerinfo.channelUid, timerinfo.channelUid, timerinfo.title, timerinfo.epgid); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "addDvrEntry"); htsmsg_add_u32(msg, "eventId", timerinfo.epgid); htsmsg_add_str(msg, "title", timerinfo.title); htsmsg_add_u32(msg, "start", timerinfo.starttime); htsmsg_add_u32(msg, "stop", timerinfo.endtime); htsmsg_add_u32(msg, "channelId", timerinfo.channelUid); htsmsg_add_u32(msg, "priority", timerinfo.priority); htsmsg_add_str(msg, "description", timerinfo.description); htsmsg_add_str(msg, "creator", "XBMC"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get addDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } const char *strError = NULL; if ((strError = htsmsg_get_str(msg, "error"))) { XBMC->Log(LOG_DEBUG, "%s - Error adding timer: '%s'", __FUNCTION__, strError); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
PVR_ERROR cXVDRData::UpdateTimer(const PVR_TIMER &timerinfo) { // use timer margin to calculate start/end times uint32_t starttime = timerinfo.startTime - timerinfo.iMarginStart*60; uint32_t endtime = timerinfo.endTime + timerinfo.iMarginEnd*60; cRequestPacket vrp; if (!vrp.init(XVDR_TIMER_UPDATE)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iClientIndex)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.state == PVR_TIMER_STATE_SCHEDULED)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iPriority)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iLifetime)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iClientChannelUid)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(starttime)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(endtime)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.bIsRepeating ? timerinfo.firstDay : 0)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iWeekdays))return PVR_ERROR_UNKNOWN; if (!vrp.add_String(timerinfo.strTitle)) return PVR_ERROR_UNKNOWN; if (!vrp.add_String("")) return PVR_ERROR_UNKNOWN; cResponsePacket* vresp = ReadResult(&vrp); if (vresp == NULL || vresp->noResponse()) { delete vresp; return PVR_ERROR_UNKNOWN; } uint32_t returnCode = vresp->extract_U32(); delete vresp; if (returnCode == XVDR_RET_DATAUNKNOWN) return PVR_ERROR_NOT_POSSIBLE; else if (returnCode == XVDR_RET_DATAINVALID) return PVR_ERROR_NOT_SAVED; else if (returnCode == XVDR_RET_ERROR) return PVR_ERROR_SERVER_ERROR; return PVR_ERROR_NO_ERROR; }
PVR_ERROR CHTSPData::RenameRecording(const PVR_RECORDING &recording, const char *strNewName) { XBMC->Log(LOG_DEBUG, "%s - id=%s", __FUNCTION__, recording.strRecordingId); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "updateDvrEntry"); htsmsg_add_u32(msg, "id", atoi(recording.strRecordingId)); htsmsg_add_str(msg, "title", recording.strTitle); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get updateDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_SAVED; }
virtual ReadResult openArchive(const std::string &file, ArchiveStatus status, unsigned int indexBlockSize = 4096, const Options *options = NULL) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile(file, options); if (fileName.empty()) { if (status == READ) return ReadResult::FILE_NOT_FOUND; fileName = file; } osg::ref_ptr<OSGA_Archive> archive = new OSGA_Archive; if (!archive->open(fileName, status, indexBlockSize)) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } return archive.get(); }
virtual ReadResult readObject(std::istream& fin, const osgDB::ReaderWriter::Options* options) const { osgDB::Input fr; fr.attach(&fin); fr.setOptions(options); typedef std::vector< osg::ref_ptr<osgViewer::View> > ViewList; ViewList viewList; // load all nodes in file, placing them in a group. while(!fr.eof()) { osg::ref_ptr<osg::Object> object = fr.readObject(); osgViewer::View* view = dynamic_cast<osgViewer::View*>(object.get()); if (view) { viewList.push_back(view); } else fr.advanceOverCurrentFieldOrBlock(); } if (viewList.empty()) { return ReadResult("No data loaded"); } else if (viewList.size()==1) { return viewList.front().get(); } else { OSG_NOTICE<<"Found multiple view's, just taking first"<<std::endl; return viewList.front().get(); } }
void cVNSIChannelScan::StartScan() { m_header = XBMC->GetLocalizedString(30025); m_Signal = XBMC->GetLocalizedString(30029); SetProgress(0); SetSignal(0, false); int source = m_spinSourceType->GetValue(); switch (source) { case DVB_TERR: m_window->SetControlLabel(LABEL_TYPE, "DVB-T"); break; case DVB_CABLE: m_window->SetControlLabel(LABEL_TYPE, "DVB-C"); break; case DVB_SAT: m_window->SetControlLabel(LABEL_TYPE, "DVB-S/S2"); break; case PVRINPUT: m_window->SetControlLabel(LABEL_TYPE, XBMC->GetLocalizedString(30032)); break; case PVRINPUT_FM: m_window->SetControlLabel(LABEL_TYPE, XBMC->GetLocalizedString(30033)); break; case DVB_ATSC: m_window->SetControlLabel(LABEL_TYPE, "ATSC"); break; } cRequestPacket vrp; cResponsePacket* vresp = NULL; uint32_t retCode = VDR_RET_ERROR; if (!vrp.init(VDR_SCAN_START)) goto SCANError; if (!vrp.add_U32(source)) goto SCANError; if (!vrp.add_U8(m_radioButtonTV->IsSelected())) goto SCANError; if (!vrp.add_U8(m_radioButtonRadio->IsSelected())) goto SCANError; if (!vrp.add_U8(m_radioButtonFTA->IsSelected())) goto SCANError; if (!vrp.add_U8(m_radioButtonScrambled->IsSelected())) goto SCANError; if (!vrp.add_U8(m_radioButtonHD->IsSelected())) goto SCANError; if (!vrp.add_U32(m_spinCountries->GetValue())) goto SCANError; if (!vrp.add_U32(m_spinDVBCInversion->GetValue())) goto SCANError; if (!vrp.add_U32(m_spinDVBCSymbolrates->GetValue())) goto SCANError; if (!vrp.add_U32(m_spinDVBCqam->GetValue())) goto SCANError; if (!vrp.add_U32(m_spinDVBTInversion->GetValue())) goto SCANError; if (!vrp.add_U32(m_spinSatellites->GetValue())) goto SCANError; if (!vrp.add_U32(m_spinATSCType->GetValue())) goto SCANError; vresp = ReadResult(&vrp); if (!vresp) goto SCANError; retCode = vresp->extract_U32(); if (retCode != VDR_RET_OK) goto SCANError; return; SCANError: XBMC->Log(LOG_ERROR, "cVNSIChannelScan::StartScan() - Return error after start (%i)", retCode); m_window->SetControlLabel(LABEL_STATUS, XBMC->GetLocalizedString(24071)); m_window->SetControlLabel(BUTTON_START, XBMC->GetLocalizedString(30024)); m_window->SetControlLabel(HEADER_LABEL, XBMC->GetLocalizedString(30043)); m_stopped = true; }
PVR_ERROR cXVDRData::AddTimer(const PVR_TIMER &timerinfo) { cRequestPacket vrp; if (!vrp.init(XVDR_TIMER_ADD)) { XBMC->Log(LOG_ERROR, "%s - Can't init cRequestPacket", __FUNCTION__); return PVR_ERROR_UNKNOWN; } // add directory in front of the title std::string path; if(timerinfo.strDirectory != NULL && strlen(timerinfo.strDirectory) > 0) { path += timerinfo.strDirectory; if(path == "/") { path.clear(); } else if(path.size() > 1) { if(path[0] == '/') { path = path.substr(1); } } if(path.size() > 0 && path[path.size()-1] != '/') { path += "/"; } } if(timerinfo.strTitle != NULL) { path += timerinfo.strTitle; } // replace directory separators for(std::size_t i=0; i<path.size(); i++) { if(path[i] == '/' || path[i] == '\\') { path[i] = '~'; } } if(path.empty()) { XBMC->Log(LOG_ERROR, "%s - Empty filename !", __FUNCTION__); return PVR_ERROR_UNKNOWN; } // use timer margin to calculate start/end times uint32_t starttime = timerinfo.startTime - timerinfo.iMarginStart*60; uint32_t endtime = timerinfo.endTime + timerinfo.iMarginEnd*60; if (!vrp.add_U32(timerinfo.state == PVR_TIMER_STATE_SCHEDULED)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iPriority)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iLifetime)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iClientChannelUid)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(starttime)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(endtime)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.bIsRepeating ? timerinfo.firstDay : 0)) return PVR_ERROR_UNKNOWN; if (!vrp.add_U32(timerinfo.iWeekdays))return PVR_ERROR_UNKNOWN; if (!vrp.add_String(path.c_str())) return PVR_ERROR_UNKNOWN; if (!vrp.add_String("")) return PVR_ERROR_UNKNOWN; cResponsePacket* vresp = ReadResult(&vrp); if (vresp == NULL || vresp->noResponse()) { delete vresp; XBMC->Log(LOG_ERROR, "%s - Can't get response packet", __FUNCTION__); return PVR_ERROR_UNKNOWN; } uint32_t returnCode = vresp->extract_U32(); delete vresp; if (returnCode == XVDR_RET_DATALOCKED) return PVR_ERROR_ALREADY_PRESENT; else if (returnCode == XVDR_RET_DATAINVALID) return PVR_ERROR_NOT_SAVED; else if (returnCode == XVDR_RET_ERROR) return PVR_ERROR_SERVER_ERROR; return PVR_ERROR_NO_ERROR; }
virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const { if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED); else return readFile(ARCHIVE,fileName,options); }
virtual ReadResult readNode(const std::string& uri, const Options* options) const { std::string ext = osgDB::getFileExtension(uri); if ( acceptsExtension(ext) ) { // See if the filename starts with server: and strip it off. This will trick OSG // into passing in the filename to our plugin instead of using the CURL plugin if // the filename contains a URL. So, if you want to read a URL, you can use the // following format: osgDB::readNodeFile("server:http://myserver/myearth.earth"). // This should only be necessary for the first level as the other files will have // a tilekey prepended to them. if ((uri.length() > 7) && (uri.substr(0, 7) == "server:")) return readNode(uri.substr(7), options); // parse the tile key and engine ID: std::string tileDef = osgDB::getNameLessExtension(uri); unsigned int lod, x, y, engineID; sscanf(tileDef.c_str(), "%d/%d/%d.%d", &lod, &x, &y, &engineID); // find the appropriate engine: osg::ref_ptr<MPTerrainEngineNode> engineNode; MPTerrainEngineNode::getEngineByUID( (UID)engineID, engineNode ); if ( engineNode.valid() ) { OE_START_TIMER(tileLoadTime); // see if we have a progress tracker ProgressCallback* progress = options ? const_cast<ProgressCallback*>( dynamic_cast<const ProgressCallback*>(options->getUserData())) : 0L; // must have a ProgressCallback if we're profiling. bool ownProgress = (progress == 0L); if ( !progress && _profiling ) progress = new ProgressCallback(); // assemble the key and create the node: const Profile* profile = engineNode->getMap()->getProfile(); TileKey key( lod, x, y, profile ); osg::ref_ptr<osg::Node> node; if ( "osgearth_engine_mp_tile" == ext ) { node = engineNode->createNode(key, progress); } else if ( "osgearth_engine_mp_standalone_tile" == ext ) { node = engineNode->createStandaloneNode(key, progress); } double tileLoadTime = OE_STOP_TIMER(tileLoadTime); if ( progress ) progress->stats()["tile_load_time"] = tileLoadTime; if ( _profiling ) { OE_NOTICE << "tile: " << tileDef << std::endl; for(std::map<std::string,double>::iterator i = progress->stats().begin(); i != progress->stats().end(); ++i) { OE_NOTICE << " " << i->first << " = " << std::setprecision(4) << i->second << " (" << (int)((i->second/tileLoadTime)*100) << "%)" << std::endl; } if ( ownProgress ) { delete progress; progress = 0L; } } // Deal with failed loads. if ( !node.valid() ) { if ( key.getLOD() == 0 || (progress && progress->isCanceled()) ) { // the tile will ask again next time. return ReadResult::FILE_NOT_FOUND; } else { // the parent tile will never ask again as long as it remains in memory. node = new InvalidTileNode( key ); } } else { // notify the Terrain interface of a new tile osg::Timer_t start = osg::Timer::instance()->tick(); engineNode->getTerrain()->notifyTileAdded(key, node.get()); osg::Timer_t end = osg::Timer::instance()->tick(); } return ReadResult( node.get(), ReadResult::FILE_LOADED ); } else { return ReadResult::FILE_NOT_FOUND; } } else { return ReadResult::FILE_NOT_HANDLED; } }
virtual ReadResult readNode(const std::string& uri, const Options* options) const { std::string ext = osgDB::getFileExtension(uri); if ( acceptsExtension(ext) ) { // See if the filename starts with server: and strip it off. This will trick OSG // into passing in the filename to our plugin instead of using the CURL plugin if // the filename contains a URL. So, if you want to read a URL, you can use the // following format: osgDB::readNodeFile("server:http://myserver/myearth.earth"). // This should only be necessary for the first level as the other files will have // a tilekey prepended to them. if ((uri.length() > 7) && (uri.substr(0, 7) == "server:")) return readNode(uri.substr(7), options); // parse the tile key and engine ID: std::string tileDef = osgDB::getNameLessExtension(uri); unsigned int lod, x, y, engineID; sscanf(tileDef.c_str(), "%d/%d/%d.%d", &lod, &x, &y, &engineID); // find the appropriate engine: osg::ref_ptr<MPTerrainEngineNode> engineNode; MPTerrainEngineNode::getEngineByUID( (UID)engineID, engineNode ); if ( engineNode.valid() ) { Registry::instance()->startActivity(uri); OE_START_TIMER(tileLoadTime); // see if we have a progress tracker ProgressCallback* progress = options ? const_cast<ProgressCallback*>( dynamic_cast<const ProgressCallback*>(options->getUserData())) : 0L; // must have a ProgressCallback if we're profiling. bool ownProgress = (progress == 0L); if ( !progress && _profiling ) progress = new ProgressCallback(); // assemble the key and create the node: const Profile* profile = engineNode->getMap()->getProfile(); TileKey key( lod, x, y, profile ); osg::ref_ptr<osg::Node> node; if ( "osgearth_engine_mp_tile" == ext ) { node = engineNode->createNode(key, progress); } else if ( "osgearth_engine_mp_standalone_tile" == ext ) { node = engineNode->createStandaloneNode(key, progress); } double tileLoadTime = OE_STOP_TIMER(tileLoadTime); if ( progress ) progress->stats()["tile_load_time"] = tileLoadTime; // profiling level 1 = detailed stats about individual loads. if ( _profiling == 1 ) { progress->stats()["http_get_time_avg"] = progress->stats()["http_get_time"] / progress->stats()["http_get_count"]; OE_NOTICE << "tile: " << tileDef << std::endl; for(ProgressCallback::Stats::iterator i = progress->stats().begin(); i != progress->stats().end(); ++i) { std::stringstream buf; if ( osgEarth::endsWith(i->first, "_time") ) { buf << i->first << " = " << std::setprecision(4) << (i->second*1000.0) << "ms (" << (int)((i->second/tileLoadTime)*100) << "%)"; } else { buf << i->first << " = " << std::setprecision(4) << i->second; } OE_NOTICE << " " << buf.str() << std::endl; } if ( ownProgress ) { delete progress; progress = 0L; } } // profiling level 2 = running 60-sample averages else if ( _profiling == 2 ) { static std::deque<double> tileLoadTimes[3]; static int samples[3] = { 64, 256, 1024 }; static double runningTotals[3] = { 0.0, 0.0, 0.0 }; static Threading::Mutex averageMutex; averageMutex.lock(); for(int i=0; i<3; ++i) { runningTotals[i] += tileLoadTime; tileLoadTimes[i].push_back( tileLoadTime ); if ( tileLoadTimes[i].size() > samples[i] ) { runningTotals[i] -= tileLoadTimes[i].front(); tileLoadTimes[i].pop_front(); } } OE_NOTICE << "(samples)time : " << "(" << samples[0] << "): " << (tileLoadTimes[0].size() == samples[0] ? (runningTotals[0]/(double)samples[0])*1000.0 : -1.0) << "ms; " << "(" << samples[1] << "): " << (tileLoadTimes[1].size() == samples[1] ? (runningTotals[1]/(double)samples[1])*1000.0 : -1.0) << "ms; " << "(" << samples[2] << "): " << (tileLoadTimes[2].size() == samples[2] ? (runningTotals[2]/(double)samples[2])*1000.0 : -1.0) << "ms; " << std::endl; averageMutex.unlock(); } Registry::instance()->endActivity(uri); // Deal with failed loads. if ( !node.valid() ) { if ( key.getLOD() == 0 ) { // the tile will ask again next time. return ReadResult::FILE_NOT_FOUND; } else if (progress && progress->isCanceled()) { if ( _profiling ) { OE_NOTICE << LC << "Tile " << key.str() << " -- canceled!" << std::endl; } return ReadResult::FILE_NOT_FOUND; } else { // the parent tile will never ask again as long as it remains in memory. node = new InvalidTileNode( key ); } } else { // notify the Terrain interface of a new tile // moved this to TileNodeRegistry::add //osg::Timer_t start = osg::Timer::instance()->tick(); //engineNode->getTerrain()->notifyTileAdded(key, node.get()); //osg::Timer_t end = osg::Timer::instance()->tick(); } return ReadResult( node.get(), ReadResult::FILE_LOADED ); } else { return ReadResult::FILE_NOT_FOUND; } } else { return ReadResult::FILE_NOT_HANDLED; } }