#define _CRT_SECURE_NO_WARNINGS #include #include #include "AnyCleaner.h" #include "RtpFilesCleaner.h" #include "CRtpFrame.h" #include "json.h" #include "RtpFast.h" #define _DEBUG1 0 //#include "CRtpFrame.h" void rtpcallback_timeinfo(char* frame_data, int frame_size, \ unsigned int frame_timesec, unsigned int frame_timeusec, bool is_iframe, \ void* user_data) { if (frame_size < 0) return; // ignore error information RTPFILEDESC* rtp_filedesc = static_cast(user_data); if (!frame_data && !frame_size) { // end of file int diff_sec = 0; int diff_usec = 0; CTimeHelper::TimeDiff(&diff_sec, &diff_usec, rtp_filedesc->start_timesec, rtp_filedesc->start_timeusec, rtp_filedesc->end_timesec, rtp_filedesc->end_timeusec); rtp_filedesc->duration_sec = diff_sec; return; } if (!rtp_filedesc->start_timesec) { rtp_filedesc->start_timesec = frame_timesec; rtp_filedesc->start_timeusec = frame_timeusec; } rtp_filedesc->end_timesec = frame_timesec; rtp_filedesc->end_timeusec = frame_timeusec; } int rtp_proc(RTPFILEDESC* rtp_filedesc, Buffer_t* mem_buffer, CRtpFrame* rtp_frame, FRAMEDATACALLBACK framedata_cb, void* user_data) { if (rtp_filedesc->start_timesec != 0) { return 0; } if (!rtp_filedesc->file_size) { BLOG_ERROR(fmt::format("[F] {} file size is 0", rtp_filedesc->file_name)); //CONSOLELOG(ERROR) << "[" << rtp_filedesc->file_name << "] file size is 0."; return -1; } if (mem_buffer->BufSize < rtp_filedesc->file_size) { BLOG_ERROR(fmt::format("[F] {} file size: {} is greater than allocated buffer size: {}", rtp_filedesc->file_name, rtp_filedesc->file_size, mem_buffer->BufSize)); //CONSOLELOG(ERROR) << "[" << rtp_filedesc->file_name << "] file size: " << rtp_filedesc->file_size << " is greater than allocated buffer size: " << mem_buffer->BufSize; return -1; } FILE* fp = NULL; fp = fopen(rtp_filedesc->file_name, "rb"); if (!fp) { BLOG_ERROR(fmt::format("[F] {} cannot open file.", rtp_filedesc->file_name)); //CONSOLELOG(ERROR) << "[" << rtp_filedesc->file_name << "] cannot open file."; return -1; } // read in data fread(mem_buffer->pData, 1, rtp_filedesc->file_size, fp); fclose(fp); fp = NULL; char* file_data = mem_buffer->pData; char* frame_cache = mem_buffer->pData + mem_buffer->BufSize; unsigned int frame_cachesize = 0; int fatal_error = 0; // -1: parse header error, -2: file not completed char RtpHeader[64]; const int HeaderSize = RTP_HEADER_SIZE + RTP_DATAINFO_EXT_SIZE; unsigned int M; unsigned int TimeStamp; unsigned int RtpDataSize; unsigned int RtpDataSec; unsigned int RtpDataUSec; unsigned int is_iframe; int data_size = 0; char* packet_databuffer = 0; while (data_size + HeaderSize < rtp_filedesc->file_size) { // assume at least one header is remain packet_databuffer = file_data; memcpy(RtpHeader, file_data, HeaderSize); file_data += HeaderSize; data_size += HeaderSize; M = 0; TimeStamp = 0; RtpDataSize = 0; is_iframe = 0; RtpDataSec = 0; RtpDataUSec = 0; if (RtpGetPacketSizeEx(&M, &TimeStamp, &RtpDataSize, &is_iframe, &RtpDataSec, &RtpDataUSec, NULL, NULL, RtpHeader) < 0) { fatal_error = -1; // corrupt rtp data break; } data_size += RtpDataSize; if (data_size > rtp_filedesc->file_size) { // the file is not completed fatal_error = -2; break; } // copy frame data if (frame_cachesize + RtpDataSize > FRAME_CACHESIZE) { BLOG_ERROR(fmt::format("[F] {} frame data size: {} is too large to be cached", rtp_filedesc->file_name, frame_cachesize + RtpDataSize)); //CONSOLELOG(ERROR) << "[" << rtp_filedesc->file_name << "] frame data size: " << frame_cachesize + RtpDataSize << " is too large to be cached"; break; } memcpy(frame_cache + frame_cachesize, file_data, RtpDataSize); frame_cachesize += RtpDataSize; file_data += RtpDataSize; if (!rtp_frame) { if (M) { // at the end of frame framedata_cb(frame_cache, frame_cachesize, RtpDataSec, RtpDataUSec, is_iframe ? true : false, user_data); frame_cachesize = 0; } } else { Buffer_t packet_buffer; memset(&packet_buffer, 0, sizeof(packet_buffer)); packet_buffer.pData = packet_databuffer; packet_buffer.DataSize = HeaderSize + RtpDataSize; rtp_frame->Proc(&packet_buffer); if (rtp_frame->IsFrameReady()) { framedata_cb(rtp_frame->GetVideoData(), rtp_frame->GetVideoDataLength(), RtpDataSec, RtpDataUSec, is_iframe ? true : false, user_data); frame_cachesize = 0; rtp_frame->CopyFrame(NULL, NULL, NULL, NULL, NULL); } } } if (fatal_error) { framedata_cb(NULL, -1, 0, 0, false, user_data); //CONSOLELOG(ERROR) << "[" << rtp_filedesc->file_name << "] process error: " << (fatal_error == -1 ? "corrupt header." : "partially flush content."); if (rtp_filedesc->start_timesec != 0 && rtp_filedesc->end_timesec != 0) { return 0; } else { BLOG_ERROR(fmt::format("[F] {} process error: {}", rtp_filedesc->file_name, (fatal_error == -1 ? "corrupt header." : "partially flush content."))); return -1; } } assert(!frame_cachesize); framedata_cb(NULL, frame_cachesize, 0, 0, false, user_data); return 0; } ClearRtpFiles::ClearRtpFiles() { //Start(); } ClearRtpFiles::~ClearRtpFiles() { Stop(); std::list::iterator iter; for (iter = list_src_rtpfiles.begin(); iter != list_src_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_src_rtpfiles.erase(iter); } list_src_rtpfiles.clear(); for (iter = list_backup_rtpfiles.begin(); iter != list_backup_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_backup_rtpfiles.erase(iter); } list_backup_rtpfiles.clear(); } bool ClearRtpFiles::LoadDeviceInfo() { char* text = NULL; FILE* pf = fopen("anycleaner.cfg", "rb+"); if (!pf) { BLOG_ERROR("open anycleaner.cfg failed"); //printf("open deveice.config failed\n"); return false; } fseek(pf, 0, SEEK_END); long lSize = ftell(pf); text = (char*)malloc(lSize); rewind(pf); fread(text, sizeof(char), lSize, pf); std::string filedata = std::string(text, lSize); free(text); fclose(pf); nlohmann::json j = nlohmann::json::parse(filedata); std::string src = j["duty_spool"]; src_path = src; std::string backup = j["standby_spool"]; backup_path = backup; checktime = j["check_interval"]; remaining_memory = j["storage_freespace"]; retension_day = j["retension_day"]; return true; } int ClearRtpFiles::Get_Folder_List(std::vector* pVecFolderName, char* folder_name) { char fileFound[256]; WIN32_FIND_DATAA info; HANDLE hp; char* folder_path = NULL; sprintf(fileFound, ("%s\\*.*"), folder_name); hp = FindFirstFileA(fileFound, &info); if (hp == INVALID_HANDLE_VALUE) return -1; do { if ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) continue; // "." if (info.cFileName[0] == '.' && info.cFileName[1] == '\0') continue; // ".." if (info.cFileName[0] == '.' && info.cFileName[1] == '.' && info.cFileName[2] == '\0') continue; // find one directory folder_path = new char[256]; if (!folder_path) break; sprintf(folder_path, "%s\\%s", folder_name, info.cFileName); pVecFolderName->push_back(folder_path); folder_path = NULL; } while (FindNextFileA(hp, &info)); FindClose(hp); return 0; } int ClearRtpFiles::Get_Date_List(std::vector* pVecFolderName, char* folder_name) { char fileFound[256]; WIN32_FIND_DATAA info; HANDLE hp; char* folder_path = NULL; sprintf(fileFound, ("%s\\*.*"), folder_name); hp = FindFirstFileA(fileFound, &info); if (hp == INVALID_HANDLE_VALUE) return -1; do { if ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) continue; // "." if (info.cFileName[0] == '.' && info.cFileName[1] == '\0') continue; // ".." if (info.cFileName[0] == '.' && info.cFileName[1] == '.' && info.cFileName[2] == '\0') continue; // find one directory folder_path = new char[256]; if (!folder_path) break; sprintf(folder_path, "%s\\%s", folder_name, info.cFileName); pVecFolderName->push_back(folder_path); folder_path = NULL; } while (FindNextFileA(hp, &info)); FindClose(hp); return 0; } void ClearRtpFiles::Get_DateFiles(std::vector* vec_foldernames, const char* src_folder) { Get_Date_List(vec_foldernames, (char*)src_folder); } void ClearRtpFiles::Get_Folder(std::vector* vec_foldernames,const char* src_folder) { Get_Folder_List(vec_foldernames, (char*)src_folder); } int ClearRtpFiles::Rtp_Listfile(std::list* list_rtpfiles, const char* src_folder) { std::vector vec_foldernames; char* curr_folder = new char[256]; if (!curr_folder) { //CONSOLELOG(ERROR) << "mem is not enough to process folder: " << src_folder; return -1; } sprintf(curr_folder, "%s", src_folder); vec_foldernames.push_back(curr_folder); CDiscHelper::GetFolderName(&vec_foldernames, (char*)src_folder, true); for (unsigned int f = 0; f < vec_foldernames.size(); f++) { std::vector vec_filenames; CDiscHelper::GetFileName(&vec_filenames, vec_foldernames.at(f)); if (vec_filenames.empty()) { //CONSOLELOG(INFO) << "there is no files under folder: " << vec_foldernames.at(f); continue; } // #process all the rtp files for (unsigned int v = 0; v < vec_filenames.size(); v++) { if (!CDiscHelper::IsMatchExt(vec_filenames.at(v), (char*)".rtp")) continue; // ignore non rtp files RTPFILEDESC* rtp_filedesc = new RTPFILEDESC; if (!rtp_filedesc) { //CONSOLELOG(ERROR) << "mem is limited to process more files."; break; } memset(rtp_filedesc, 0, sizeof(*rtp_filedesc)); sprintf(rtp_filedesc->file_name, "%s", vec_filenames.at(v)); rtp_filedesc->file_size = CDiscHelper::GetFileSize(rtp_filedesc->file_name); std::string srcdata = std::string(rtp_filedesc->file_name); std::string data = srcdata; while (true) { if (data.npos != data.find("\\")) { data = data.substr(data.find("\\") + 1); } else { break; } } memcpy(rtp_filedesc->name, data.c_str(), data.size()); //add file Serial number std::string tmpdata = Get_Filename_Time(rtp_filedesc->name); rtp_filedesc->file_number = std::stol(tmpdata); char fold[100] = ""; memcpy(fold, srcdata.c_str(), srcdata.find(data) - 1); data = std::string(fold); while (true) { if (data.npos != data.find("\\")) { data = data.substr(data.find("\\") + 1); } else { break; } } memcpy(rtp_filedesc->folder, data.c_str(),data.size()); list_rtpfiles->push_back(rtp_filedesc); } CDiscHelper::ClearFolderName(&vec_filenames); } CDiscHelper::ClearFolderName(&vec_foldernames); return 0; } std::wstring s2ws(const std::string& s) { int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } void ClearRtpFiles::Delete_file(std::string filename) { { std::string file = filename; std::wstring stemp = s2ws(file); LPCWSTR result = stemp.c_str(); BOOL del = DeleteFile(result); if (!del) { DWORD error_rus = GetLastError(); BLOG_DEBUG(fmt::format("[F] *** failed to DeleteFile {},code{} ***", file, error_rus)); } } { std::string file = filename; file += ".gop"; std::wstring stemp = s2ws(file); LPCWSTR result = stemp.c_str(); BOOL del = DeleteFile(result); if (!del) { DWORD error_rus = GetLastError(); BLOG_DEBUG(fmt::format("[F] *** failed to DeleteFile {},code{} ***", file, error_rus)); } } } void get_Item_ex(std::string src,std::string& head,std::string& end) { std::string data = src; std::string he; while (true) { if (data.npos != data.find("\\")) { he += data.substr(0, data.find("\\") + 1); data = data.substr(data.find("\\") + 1); } else { break; } } head = he; end = data; } std::string get_Item(std::string src) { std::string data = src; while (true) { if (data.npos != data.find("\\")) { data = data.substr(data.find("\\") + 1); } else { break; } } return data; } std::string ClearRtpFiles::Get_Filename_Time(std::string src) { std::string data = src; data = data.substr(data.find("-") + 1); if (data.npos != data.find("-")) { data = data.substr(0, data.find("-")); } else if (data.npos != data.find(".")) { data = data.substr(0, data.find(".")); } return data; } /*通过调用ShFileOperation来实现整个目录的删除*/ /*只删除单个目录*/ BOOL ClearRtpFiles::SHDeleteFolder(std::string pstrFolder, BOOL bAllowUndo) { std::string file = pstrFolder; std::wstring stemp = s2ws(file); LPCWSTR result = stemp.c_str(); int iPathLen = wcslen(result); if (iPathLen >= MAX_PATH) { return FALSE; } /*确保目录的路径以2个\0结尾*/ TCHAR tczFolder[MAX_PATH + 1]; ZeroMemory(tczFolder, (MAX_PATH + 1) * sizeof(TCHAR)); wcscpy(tczFolder, result); tczFolder[iPathLen] = _T('\0'); tczFolder[iPathLen + 1] = _T('\0'); SHFILEOPSTRUCT FileOp; ZeroMemory(&FileOp, sizeof(SHFILEOPSTRUCT)); FileOp.fFlags |= FOF_SILENT; /*不显示进度*/ FileOp.fFlags |= FOF_NOERRORUI; /*不报告错误信息*/ FileOp.fFlags |= FOF_NOCONFIRMATION;/*直接删除,不进行确认*/ FileOp.hNameMappings = NULL; FileOp.hwnd = NULL; FileOp.lpszProgressTitle = NULL; FileOp.wFunc = FO_DELETE; FileOp.pFrom = tczFolder; /*要删除的目录,必须以2个\0结尾*/ FileOp.pTo = NULL; /*根据传递的bAllowUndo参数确定是否删除到回收站*/ if (bAllowUndo) { FileOp.fFlags |= FOF_ALLOWUNDO; /*删除到回收站*/ } else { FileOp.fFlags &= ~FOF_ALLOWUNDO; /*直接删除,不放入回收站*/ } /*删除目录*/ if (0 == SHFileOperation(&FileOp)) { return TRUE; } else { return FALSE; } } void ClearRtpFiles::File_Sort(std::list* src_rtpfiles, std::list* dst_rtpfiles) { std::list::iterator it_1; int filesize = (*src_rtpfiles).size(); for (int i = 0; i < filesize; i++) { it_1 = (*src_rtpfiles).begin(); if ((*src_rtpfiles).size() == 0) break; RTPFILEDESC* data = new RTPFILEDESC; memset(data, 0, sizeof(*data)); data->file_number = 0; do { RTPFILEDESC* rtp_filedesc = *it_1++; if (data->file_number == 0) { data->file_number = rtp_filedesc->file_number; memcpy(data->file_name, rtp_filedesc->file_name, 256); memcpy(data->folder, rtp_filedesc->folder, 256); data->file_size = rtp_filedesc->file_size; memcpy(data->name, rtp_filedesc->name,256); } else { if ((data->file_number) > rtp_filedesc->file_number) { data->file_number = rtp_filedesc->file_number; memcpy(data->file_name, rtp_filedesc->file_name, 256); memcpy(data->folder, rtp_filedesc->folder, 256); data->file_size = rtp_filedesc->file_size; memcpy(data->name, rtp_filedesc->name, 256); } } } while (it_1 != (*src_rtpfiles).end()); it_1 = (*src_rtpfiles).begin(); for (it_1 = (*src_rtpfiles).begin(); it_1 != (*src_rtpfiles).end();) { if (!strcmp((*it_1)->name, data->name)){ delete (*it_1); *it_1 = NULL; it_1 = (*src_rtpfiles).erase(it_1); } else { it_1++; } } (*dst_rtpfiles).emplace_back(data); } for (it_1 = (*src_rtpfiles).begin(); it_1 != (*src_rtpfiles).end();) { delete (*it_1); *it_1 = NULL; it_1 = (*src_rtpfiles).erase(it_1); } (*src_rtpfiles).clear(); } void ClearRtpFiles::Folder_Sort(std::vector* src_folder, std::vector* dst_folder) { std::vector::iterator it_1; std::string data_; int filesize = (*src_folder).size(); for (int i = 0; i < filesize; i++) { it_1 = (*src_folder).begin(); if ((*src_folder).size() == 0) break; char* data = new char[256]; memset(data, 0, 256); int file_number = 0; do { char* rtp_filedesc = *it_1++; if (file_number == 0) { data_ = get_Item(std::string(rtp_filedesc)); file_number = std::stoi(data_); memcpy(data, rtp_filedesc, 256); } else { data_ = get_Item(std::string(rtp_filedesc)); if ((file_number) > std::stoi(data_)) { file_number = std::stoi(data_); memcpy(data, rtp_filedesc, 256); } } } while (it_1 != (*src_folder).end()); it_1 = (*src_folder).begin(); for (it_1 = (*src_folder).begin(); it_1 != (*src_folder).end();) { if (std::string(*it_1) == std::string(data)) { delete[] (*it_1); *it_1 = NULL; it_1 = (*src_folder).erase(it_1); } else { it_1++; } } (*dst_folder).emplace_back(data); } for (it_1 = (*src_folder).begin(); it_1 != (*src_folder).end();) { delete[] (*it_1); *it_1 = NULL; it_1 = (*src_folder).erase(it_1); } (*src_folder).clear(); } int ClearRtpFiles::Get_MaxSize_File(std::list* list_rtpfiles) { int max_filesize = 0; std::list::iterator it; it = (*list_rtpfiles).begin(); do { if ((*list_rtpfiles).size() == 0) break; RTPFILEDESC* rtp_filedesc = *it++; max_filesize = max_filesize > rtp_filedesc->file_size ? max_filesize : rtp_filedesc->file_size; } while (it != (*list_rtpfiles).end()); return max_filesize; } void ClearRtpFiles::Check_Channels(std::string src, std::string backup) { std::string last_day; std::string next_day; std::string src_day; std::string src_tmp; std::string head_; std::string last_src_tmp; std::vector src_daytmp_name; std::vector src_day_name; std::vector backup_day_name; Get_Folder(&src_daytmp_name, src.c_str()); Folder_Sort(&src_daytmp_name, &src_day_name); Get_Folder(&src_daytmp_name, backup.c_str()); Folder_Sort(&src_daytmp_name, &backup_day_name); std::vector::iterator it_char; bool ishave = false; for (it_char = backup_day_name.begin(); it_char != backup_day_name.end(); it_char++) { //Whether the same date exists std::string bak_day = get_Item(*it_char); if (std::stoi(std::string(bak_day)) >= 20231108) { BLOG_DEBUG(fmt::format("don't delete 11month")); break; } //查找是否存在主目录的同一天 for (auto s : src_day_name) { src_tmp = std::string(s); get_Item_ex(src_tmp, head_, src_day); if (std::stoi(src_day) == std::stoi(bak_day)) { int daytime = std::stoi(src_day); char buff_[100] = ""; sprintf(buff_, "%d", daytime - 1); last_day = head_ + std::string(buff_); memset(buff_, 0, 100); sprintf(buff_, "%d", daytime + 1); next_day = head_ + std::string(buff_); ishave = true; break; } } if (!ishave) continue; ishave = false; std::list list_tmp_rtpfiles; Rtp_Listfile(&list_tmp_rtpfiles, *it_char); File_Sort(&list_tmp_rtpfiles, &list_backup_rtpfiles); BLOG_DEBUG(fmt::format("list_backup_rtpfiles backup_folder{}, size {}", *it_char, list_backup_rtpfiles.size())); //获取当天内rtp最大的文件大小 int max_filesize = Get_MaxSize_File(&list_backup_rtpfiles); Buffer_t mem_buffer; memset(&mem_buffer, 0, sizeof(mem_buffer)); mem_buffer.BufSize = ((max_filesize + 64 - 1) / 64) * 64; mem_buffer.pData = new char[mem_buffer.BufSize + (1024 * 1024 * 30)]; memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); std::list::iterator it; it = list_backup_rtpfiles.begin(); std::list::iterator it_erase; do { if (list_backup_rtpfiles.size() == 0) break; it_erase = it; RTPFILEDESC* rtp_filedesc = *it++; // read in time informatiion if (rtp_proc(rtp_filedesc, &mem_buffer, NULL, rtpcallback_timeinfo, rtp_filedesc)) { if (rtp_filedesc != list_backup_rtpfiles.back()) BLOG_ERROR(fmt::format("Check_Channels[F] {} is corrupt. ... skip the file ...", rtp_filedesc->file_name)); delete (*it_erase); *it_erase = NULL; list_backup_rtpfiles.erase(it_erase); } else { //获取到rtp时间 //开始对比单个文件是否存在主目录内 if (rtp_filedesc->start_timesec == rtp_filedesc->end_timesec) { //测试出现过start_timesec和end_timesec相同的情况 BLOG_ERROR(fmt::format("Time is same,Delete fiel:{},time:{}~{}", rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(rtp_filedesc->folder)) < 20231108) Delete_file(rtp_filedesc->file_name); #endif } else { if (last_src_tmp != src_tmp) { std::list::iterator iter; for (iter = list_lastDay_rtpfiles.begin(); iter != list_lastDay_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_lastDay_rtpfiles.erase(iter); } list_lastDay_rtpfiles.clear(); for (iter = list_nextDay_rtpfiles.begin(); iter != list_nextDay_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_nextDay_rtpfiles.erase(iter); } list_nextDay_rtpfiles.clear(); for (iter = list_localDay_rtpfiles.begin(); iter != list_localDay_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_localDay_rtpfiles.erase(iter); } list_localDay_rtpfiles.clear(); Rtp_Listfile(&list_tmp_rtpfiles, last_day.c_str()); File_Sort(&list_tmp_rtpfiles, &list_lastDay_rtpfiles); Rtp_Listfile(&list_tmp_rtpfiles, next_day.c_str()); File_Sort(&list_tmp_rtpfiles, &list_nextDay_rtpfiles); Rtp_Listfile(&list_tmp_rtpfiles, src_tmp.c_str()); File_Sort(&list_tmp_rtpfiles, &list_localDay_rtpfiles); BLOG_DEBUG("new list_localDay_rtpfiles"); } last_src_tmp = src_tmp; bool check_last = false; bool check_next = false; //BLOG_DEBUG(fmt::format("bakcup:{},time:{}~{}", rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); Is_Same_Times(&list_localDay_rtpfiles, rtp_filedesc, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec, check_last, check_next); if (check_last) { BLOG_DEBUG("Is_LastSame_Times"); Is_LastSame_Times(&list_lastDay_rtpfiles, rtp_filedesc, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec); } else if (check_next) { BLOG_DEBUG("Is_NextSame_Times"); Is_NextSame_Times(&list_nextDay_rtpfiles, rtp_filedesc, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec); } } } memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); } while (it != list_backup_rtpfiles.end()); delete[] mem_buffer.pData; mem_buffer.pData = NULL; //删除备份的空目录 Clear_EmptyDirectory(it_char); Free_Rtpfiles(); } for (it_char = src_day_name.begin(); it_char != src_day_name.end();) { delete[](*it_char); *it_char = NULL; it_char = src_day_name.erase(it_char); } src_day_name.clear(); for (it_char = backup_day_name.begin(); it_char != backup_day_name.end();) { delete[](*it_char); *it_char = NULL; it_char = backup_day_name.erase(it_char); } backup_day_name.clear(); } void ClearRtpFiles::Free_Rtpfiles() { std::list::iterator it; it = list_backup_rtpfiles.begin(); for (it = list_backup_rtpfiles.begin(); it != list_backup_rtpfiles.end();) { delete (*it); *it = NULL; it = list_backup_rtpfiles.erase(it); } list_backup_rtpfiles.clear(); std::list::iterator iter; for (iter = list_lastDay_rtpfiles.begin(); iter != list_lastDay_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_lastDay_rtpfiles.erase(iter); } list_lastDay_rtpfiles.clear(); for (iter = list_nextDay_rtpfiles.begin(); iter != list_nextDay_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_nextDay_rtpfiles.erase(iter); } list_nextDay_rtpfiles.clear(); for (iter = list_localDay_rtpfiles.begin(); iter != list_localDay_rtpfiles.end();) { delete (*iter); *iter = NULL; iter = list_localDay_rtpfiles.erase(iter); } list_localDay_rtpfiles.clear(); } void ClearRtpFiles::Clear_EmptyDirectory(std::vector::iterator it_char) { std::wstring stemp = s2ws(*it_char); LPCWSTR result = stemp.c_str(); BOOL ret = PathIsDirectoryEmpty(result); if (ret) { BLOG_DEBUG(fmt::format("Delete BACKUP Folder {}", *it_char)); #ifdef _DEBUG1 SHDeleteFolder(*it_char, false); #endif } } void ClearRtpFiles::Get_Channels(const char* backup_folder, const char* src_folder) { Get_Folder(&vec_src_foldernames, src_folder); if (vec_src_foldernames.empty()) { BLOG_ERROR(fmt::format("[F] *** failed to load src_folder file vec_src_foldernames {}***", src_folder)); return; } Get_Folder(&vec_back_foldernames, backup_folder); if (vec_back_foldernames.empty()) { BLOG_ERROR(fmt::format("[F] *** failed to load src_folder file vec_back_foldernames {}***", backup_folder)); return; } std::vector src_daytmp_name; //磁盤空間小於某個值刪除主目录最舊的一天文件 std::string serial = std::string(vec_src_foldernames.front()); serial = serial.substr(0, serial.find("\\")); int gb_data = Get_Disk_Free(serial); BLOG_DEBUG(fmt::format("Get_Disk_Free {}", gb_data)); if (remaining_memory >= gb_data) { for (auto s : vec_src_foldernames) { Get_DateFiles(&src_daytmp_name, s); Folder_Sort(&src_daytmp_name, &vec_src_date_folder); for (auto d : vec_src_date_folder) { BLOG_DEBUG(fmt::format("remaining_memory Delete SRC Folder {}", d)); #ifdef _DEBUG1 //SHDeleteFolder(d, false); #endif std::vector::iterator iter; for (iter = vec_src_date_folder.begin(); iter != vec_src_date_folder.end();) { delete[](*iter); *iter = NULL; iter = vec_src_date_folder.erase(iter); } vec_src_date_folder.clear(); break; } } } //首先保证主目录存留retension_day设置的天数 int index = 0; int i = 0; for (auto s : vec_src_foldernames) { Get_DateFiles(&src_daytmp_name, s); Folder_Sort(&src_daytmp_name, &vec_src_date_folder); if (vec_src_date_folder.size() >= retension_day) { index = vec_src_date_folder.size() - retension_day; BLOG_DEBUG(fmt::format("index {},retension_day {}", index,retension_day)); for (auto d : vec_src_date_folder) { if (i >= index) break; BLOG_DEBUG(fmt::format("retension_day Delete SRC Folder {}", d)); #ifdef _DEBUG1 //SHDeleteFolder(d, false); #endif i++; } } std::vector::iterator iter; for (iter = vec_src_date_folder.begin(); iter != vec_src_date_folder.end();) { delete[](*iter); *iter = NULL; iter = vec_src_date_folder.erase(iter); } vec_src_date_folder.clear(); i = 0; index = 0; } for (auto src : vec_src_foldernames) { std::string src_ = std::string(src); std::string src_channel = get_Item(src_); for (auto back : vec_back_foldernames) { std::string bak = std::string(back); std::string back_channel = get_Item(bak); if (back_channel == src_channel) { Check_Channels(src_, bak); break; } } } std::vector::iterator iter; for (iter = vec_src_foldernames.begin(); iter != vec_src_foldernames.end();) { delete[] (*iter); *iter = NULL; iter = vec_src_foldernames.erase(iter); } vec_src_foldernames.clear(); for (iter = vec_back_foldernames.begin(); iter != vec_back_foldernames.end();) { delete (*iter); *iter = NULL; iter = vec_back_foldernames.erase(iter); } vec_back_foldernames.clear(); } void ClearRtpFiles::Is_NextSame_Times(std::list* list_rtpfiles, RTPFILEDESC* paramer, unsigned int starttime, unsigned int endtime) { std::list::iterator it = (*list_rtpfiles).begin(); int max_filesize = 0; do { RTPFILEDESC* rtp_filedesc = *it++; max_filesize = max_filesize > rtp_filedesc->file_size ? max_filesize : rtp_filedesc->file_size; } while (it != (*list_rtpfiles).end()); it = (*list_rtpfiles).begin(); Buffer_t mem_buffer; memset(&mem_buffer, 0, sizeof(mem_buffer)); mem_buffer.BufSize = ((max_filesize + 64 - 1) / 64) * 64; mem_buffer.pData = new char[mem_buffer.BufSize + (1024 * 1024 * 30)]; memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); std::list::iterator it_erase; int index = 0; bool isbreak = false; while (it != (*list_rtpfiles).end()) { it_erase = it; RTPFILEDESC* rtp_filedesc = *it++; if (rtp_filedesc->start_timesec != 0) continue; index++; //检查上一天,从最后面的rtp获取时间 if (index <= 20) { if (rtp_proc(rtp_filedesc, &mem_buffer, NULL, rtpcallback_timeinfo, rtp_filedesc)) { if (rtp_filedesc != (*list_rtpfiles).back()) BLOG_ERROR(fmt::format("Is_NextSame_Times[F] {} is corrupt. ... skip the file ...", rtp_filedesc->file_name)); delete (*it_erase); *it_erase = NULL; (*list_rtpfiles).erase(it_erase); //continue; } else { int day_ = std::stoi(std::string(paramer->folder)); if (starttime >= rtp_filedesc->start_timesec && endtime <= rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_Same_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } else if (starttime < rtp_filedesc->start_timesec && endtime > rtp_filedesc->start_timesec && endtime < rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_Same_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } else if (starttime >= rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_Same_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } if (isbreak) { delete (*it_erase); *it_erase = NULL; (*list_rtpfiles).erase(it_erase); break; } } memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); } } if (mem_buffer.pData) { delete[] mem_buffer.pData; mem_buffer.pData = NULL; } } void ClearRtpFiles::Is_LastSame_Times(std::list* list_rtpfiles, RTPFILEDESC* paramer, unsigned int starttime, unsigned int endtime) { std::list::iterator it = (*list_rtpfiles).begin(); int max_filesize = 0; do { RTPFILEDESC* rtp_filedesc = *it++; max_filesize = max_filesize > rtp_filedesc->file_size ? max_filesize : rtp_filedesc->file_size; } while (it != (*list_rtpfiles).end()); it = (*list_rtpfiles).begin(); //文件时间信息 Buffer_t mem_buffer; memset(&mem_buffer, 0, sizeof(mem_buffer)); mem_buffer.BufSize = ((max_filesize + 64 - 1) / 64) * 64; mem_buffer.pData = new char[mem_buffer.BufSize + (1024 * 1024 * 30)]; memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); std::list::iterator it_erase; int count = (*list_rtpfiles).size(); int index = 0; bool isbreak = false; while (it != (*list_rtpfiles).end()) { it_erase = it; RTPFILEDESC* rtp_filedesc = *it++; index++; //检查上一天,从最后面的rtp获取时间 if (count - index <= 20) { //mem_buffer.BufSize = ((rtp_filedesc->file_size + 64 - 1) / 64) * 64; //mem_buffer.pData = new char[mem_buffer.BufSize + (1024 * 1024 * 30)]; //memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); if (rtp_proc(rtp_filedesc, &mem_buffer, NULL, rtpcallback_timeinfo, rtp_filedesc)) { if (rtp_filedesc != (*list_rtpfiles).back()) BLOG_ERROR(fmt::format("Is_LastSame_Times[F] {} is corrupt. ... skip the file ...", rtp_filedesc->file_name)); delete (*it_erase); *it_erase = NULL; (*list_rtpfiles).erase(it_erase); //continue; } else { if (starttime <= rtp_filedesc->end_timesec && endtime >= rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_LastSame_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } else if (starttime >= rtp_filedesc->start_timesec && starttime <= rtp_filedesc->end_timesec && endtime > rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_LastSame_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } else if (endtime <= rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_LastSame_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } if (isbreak) { delete (*it_erase); *it_erase = NULL; (*list_rtpfiles).erase(it_erase); break; } } //delete[] mem_buffer.pData; //mem_buffer.pData = NULL; memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); } } if (mem_buffer.pData) { delete[] mem_buffer.pData; mem_buffer.pData = NULL; } } void ClearRtpFiles::Is_Same_Times(std::list* list_rtpfiles, RTPFILEDESC* paramer, unsigned int starttime, unsigned int endtime, bool& check_last, bool& check_next) { std::list::iterator it = (*list_rtpfiles).begin(); int max_filesize = 0; do { RTPFILEDESC* rtp_filedesc = *it++; max_filesize = max_filesize > rtp_filedesc->file_size ? max_filesize : rtp_filedesc->file_size; } while (it != (*list_rtpfiles).end()); it = (*list_rtpfiles).begin(); Buffer_t mem_buffer; memset(&mem_buffer, 0, sizeof(mem_buffer)); mem_buffer.BufSize = ((max_filesize + 64 - 1) / 64) * 64; mem_buffer.pData = new char[mem_buffer.BufSize + (1024 * 1024 * 30)]; memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); std::list::iterator it_erase; bool flag = false; bool last_flag = false; bool next_flag = false; bool isbreak = false; bool is_first_file = true; do { it_erase = it; RTPFILEDESC* rtp_filedesc = *it++; // read in time informatiion if (rtp_proc(rtp_filedesc, &mem_buffer, NULL, rtpcallback_timeinfo, rtp_filedesc)) { if (rtp_filedesc != (*list_rtpfiles).back()) BLOG_ERROR(fmt::format("Is_Same_Times[F] {} is corrupt. ... skip the file ...", rtp_filedesc->file_name)); delete (*it_erase); *it_erase = NULL; (*list_rtpfiles).erase(it_erase); } else { //BLOG_DEBUG(fmt::format("Is_Same_Times src:{},time:{}~{}", rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); int day_ = std::stoi(std::string(paramer->folder)); //Home directory contains all have if (!flag && starttime >= rtp_filedesc->start_timesec && endtime <= rtp_filedesc->end_timesec) { #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } //right intersect else if (!flag && starttime >= rtp_filedesc->start_timesec && starttime <= rtp_filedesc->end_timesec && endtime > rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_Same_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } //right,需要检查下一天前面几个的rtp文件时间 else if (!flag && starttime >= rtp_filedesc->end_timesec ) { if (rtp_filedesc == (*list_rtpfiles).back()) { flag = true; next_flag = true; } } //left intersect else if (!flag && starttime < rtp_filedesc->start_timesec && endtime >= rtp_filedesc->start_timesec && endtime < rtp_filedesc->end_timesec) { //BLOG_DEBUG(fmt::format("Is_Same_Times Delete_file {},time:{}~{},src:{},time:{}~{}", paramer->file_name, paramer->start_timesec, // paramer->end_timesec, rtp_filedesc->file_name, rtp_filedesc->start_timesec, rtp_filedesc->end_timesec)); #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } //left需要检查上一天末尾几个的rtp文件时间 else if (!flag && endtime < rtp_filedesc->start_timesec && is_first_file) { flag = true; last_flag = true; } else if (!flag && endtime < rtp_filedesc->start_timesec && !is_first_file) { #ifdef _DEBUG1 if (std::stoi(std::string(paramer->folder)) < 20231108) Delete_file(paramer->file_name); #endif isbreak = true; } if (isbreak) { delete (*it_erase); *it_erase = NULL; (*list_rtpfiles).erase(it_erase); break; } } is_first_file = false; memset(mem_buffer.pData, 0, mem_buffer.BufSize + (1024 * 1024 * 30)); if (last_flag) break; } while (it != (*list_rtpfiles).end()); if (mem_buffer.pData) { delete[] mem_buffer.pData; mem_buffer.pData = NULL; } check_last = last_flag; check_next = next_flag; } int ClearRtpFiles::Get_Disk_Free(std::string serial) { int pSize = MultiByteToWideChar(CP_OEMCP, 0, serial.c_str(), serial.size() + 1, NULL, 0); TCHAR* buf = new wchar_t[pSize]; MultiByteToWideChar(CP_OEMCP, 0, serial.c_str(), serial.size() + 1, buf, pSize); ULARGE_INTEGER available, total, free; //ULARGE_INTEGER 一个64位的无符号整型值 /*if (GetDiskFreeSpaceEx(TEXT("D:"), (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free)) {*/ if (GetDiskFreeSpaceEx(buf, (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free)) { //printf(" | 总容量 = %.2f GB,可用空间 = %.2f GB,空闲空间 = %.2f GB\n",GB(total), GB(available), GB(free)); } else { BLOG_ERROR(fmt::format("[F] *** failed to Get_Disk_Free ***")); //puts("获取容量信息失败"); } int available_ = GB(available); return available_; } void ClearRtpFiles::init() { life_worker = new CAppLifeThread(); life_worker->Start(); Start(); } void ClearRtpFiles::Action() { while (!IsAborted()) { Get_Channels(backup_path.c_str(), src_path.c_str()); std::this_thread::sleep_for(std::chrono::minutes(checktime)); } }