std::string RecpathConfig::GetNextPathForStream() { logD(recpath, _func_); //m_mutex.lock(); if(m_configs.size() == 0) { //m_mutex.unlock(); logD(recpath, _func_, "Config is empty"); return std::string(""); } else logD(recpath, _func_, "Config size is ", m_configs.size()); std::string next_path; while(true) { for(ConfigMap::const_iterator it = m_configs.begin(); it != m_configs.end(); ++it) { Int64 freeSize = MemoryDispatcher::Instance().GetDiskFreeSizeFromDiskname(it->first); logD(recpath, _func_, "diskname is ", it->first.c_str()); logD(recpath, _func_, "freeSize is ", freeSize); if(freeSize > MINFREESIZE) { next_path = it->first; logD(recpath, _func_, "next_path is ", next_path.c_str()); break; } } if(next_path.size()) { break; } else { logD(recpath, _func_, "next_path is empty"); } // cleaning logD(recpath, _func_, "CLEANING"); ChannelChecker::ChannelFileDiskTimes channelFileDiskTimes; std::map<std::string, WeakRef<FFmpegStream> >::iterator itFFStream = m_pStreams->begin(); for(itFFStream; itFFStream != m_pStreams->end(); itFFStream++) { logD(recpath, _func_, "channel_name = ", itFFStream->first.c_str()); Ref<ChannelChecker> channelChecker = itFFStream->second.getRefPtr()->GetChannelChecker(); std::pair<std::string, ChChDiskTimes> oldestFileDiskTimes = channelChecker->GetOldestFileDiskTimes(); logD(recpath, _func_, "filename = ", oldestFileDiskTimes.first.c_str()); logD(recpath, _func_, "diskname = ", oldestFileDiskTimes.second.diskName.c_str()); logD(recpath, _func_, "beginTime = ", oldestFileDiskTimes.second.times.timeStart); logD(recpath, _func_, "endTime = ", oldestFileDiskTimes.second.times.timeEnd); if(oldestFileDiskTimes.first.size()) { channelFileDiskTimes.insert(oldestFileDiskTimes); } } // find most older file int minTime = std::numeric_limits<int>::max(); std::string fileName; std::string diskName; ChannelChecker::ChannelFileDiskTimes::iterator iter = channelFileDiskTimes.begin(); for(iter; iter != channelFileDiskTimes.end(); iter++) { if(minTime > iter->second.times.timeStart) { minTime = iter->second.times.timeStart; fileName = iter->first; diskName = iter->second.diskName; } } logD(recpath, _func_, "minTime = ", minTime); logD(recpath, _func_, "minfileName = ", fileName.c_str()); logD(recpath, _func_, "mindiskName = ", diskName.c_str()); // delete it (if filename is not recorded at current time) StRef<String> dir_name = st_makeString(diskName.c_str()); StRef<String> file_name = st_makeString(fileName.c_str()); StRef<String> full_file_name = st_makeString(dir_name, "/", file_name, ".flv"); if(!MemoryDispatcher::Instance().IsFilenameRecorded(full_file_name->cstr())) { Ref<Vfs> vfs = Vfs::createDefaultLocalVfs (dir_name->mem()); StRef<String> const filenameFull = st_makeString(fileName.c_str(), ".flv"); logD(recpath, _func_, "filenameFull to remove = ", filenameFull); vfs->removeFile (filenameFull->mem()); vfs->removeSubdirsForFilename (filenameFull->mem()); std::string channel_name = fileName.substr(0,fileName.find("/")); (*m_pStreams)[channel_name].getRefPtr()->GetChannelChecker()->DeleteFromCache(diskName, fileName); } else { break; } } //m_mutex.unlock(); return next_path; }
StRef<String> DefaultNamingScheme::getPath (ConstMemory const channel_name, const timeval & tv, Time * const ret_next_unixtime_sec) { const Time unixtime_sec = tv.tv_sec; struct tm tm; if (!unixtimeToStructTm (unixtime_sec, &tm)) { logE_ (_func, "unixtimeToStructTm() failed"); return NULL; } // logD_ (_func, "unixtimeToStructTm() cur_unixtime_sec: ", cur_unixtime_sec); // logD_ (_func, "unixtimeToStructTm() unixtime_sec: ", unixtime_sec); // logD_ (_func, "unixtimeToStructTm() tv.tv_sec: ", tv.tv_sec, ", tv.tv_usec: ", tv.tv_usec); //double time_in_mill = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond unsigned const day_duration = 3600 * 24; unsigned const hour_duration = 3600; unsigned const minute_duration = 60; Time file_duration_sec_local = file_duration_sec; Format fmt; fmt.min_digits = 2; StRef<String> res_str; // previous file gmtime next file boundary // boundary | | // | v | // ______|____________________________|_____________________ // \____________/^ // | | // | unixtime // | // offset if (file_duration_sec_local >= day_duration) { // The offset is approximate but close. // There may a few seconds of difference, and we don't account for that here, // rounding to the neares day instead. // unsigned const offset = tm.tm_hour * 3600 + tm.tm_min * 60 + tm.tm_sec; // *ret_next_unixtime_sec = unixtime_sec + (day_duration - offset); // res_str = st_makeString (tm.tm_year + 1900, "/", fmt, tm.tm_mon + 1, "/", tm.tm_mday); // } else file_duration_sec_local = day_duration - 1; } if (file_duration_sec_local < minute_duration) { file_duration_sec_local = minute_duration; } if (file_duration_sec_local >= hour_duration) { unsigned hours = file_duration_sec_local / hour_duration; unsigned const offset = (tm.tm_hour % hours) * 3600 + tm.tm_min * 60 + tm.tm_sec; *ret_next_unixtime_sec = unixtime_sec + (hours * 3600 - offset); //logD_ (_func, "tm.tm_mday: ", tm.tm_mday, ", tm.tm_hour: ", tm.tm_hour, ", hour: ", tm.tm_hour - tm.tm_hour % hours); res_str = st_makeString (tm.tm_year + 1900, "/", fmt, tm.tm_mon + 1, "/", tm.tm_mday, "/", tm.tm_hour/* - tm.tm_hour % hours*/, tm.tm_min, tm.tm_sec); } else // (file_duration_sec_local >= minute_duration) { unsigned minutes = file_duration_sec_local / minute_duration; unsigned const offset = (tm.tm_min % minutes) * 60 + tm.tm_sec; *ret_next_unixtime_sec = unixtime_sec + (minutes * 60 - offset); res_str = st_makeString (tm.tm_year + 1900, "/", fmt, tm.tm_mon + 1, "/", tm.tm_mday, "/", tm.tm_hour, tm.tm_min/* - tm.tm_min % minutes*/, tm.tm_sec); } // else { // unsigned const offset = tm.tm_sec % file_duration_sec_local; // *ret_next_unixtime_sec = unixtime_sec + (file_duration_sec_local - offset); // res_str = st_makeString (tm.tm_year + 1900, "/", fmt, tm.tm_mon + 1, "/", tm.tm_mday, "/", tm.tm_hour, tm.tm_min, tm.tm_sec - offset); // } if (*ret_next_unixtime_sec == unixtime_sec) *ret_next_unixtime_sec = unixtime_sec + 1; Time unixtimeprefix = (Time)tv.tv_sec * 1000000000LL + (Time)tv.tv_usec * 1000; res_str = st_makeString (channel_name, "/", res_str, "_", unixtimeprefix); // logD_ (_func, "res_str: ", res_str); return res_str; }