ThreadManager.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. #include "ThreadManager.h"
  2. #include "CreateWAVThread.h"
  3. #include "CreateDBThread.h"
  4. #include "ConsistencyCompareThread.h"
  5. #include "GlobalVariable.h"
  6. #include "NoiseDetectThread.h"
  7. #include "RtpOneRoadThread.h"
  8. #include "CreateRecordFileThread.h"
  9. #include "RecordThread.h"
  10. #include "AssignSrcDataThread.h"
  11. #include "SoundCards.h"
  12. #include "ThreadPool.h"
  13. #include <mutex>
  14. #include <string>
  15. ThreadManager::ThreadManager()
  16. {
  17. m_logger = spdlog::get("ACAServer");
  18. if(m_logger == nullptr)
  19. {
  20. fmt::print("ThreadManager: ACAServer Logger not found.\n");
  21. return;
  22. }
  23. m_logBase = "ThreadManager";
  24. }
  25. /* 启动所有线程 */
  26. // void ThreadManager::startAllThreads()
  27. // {
  28. // }
  29. /* 停止所有线程 */
  30. void ThreadManager::stopAllThreads()
  31. {
  32. }
  33. /* 线程函数,销毁录音线程 */
  34. void ThreadManager::thread_destroyeRecordThread()
  35. {
  36. while(true)
  37. {
  38. // SPDLOG_LOGGER_WARN(m_logger, "销毁录音线程函数开始运行");
  39. /* 设置超时2秒 */
  40. std::unique_lock<std::mutex> m_lock(m_mutexRecordThreadRefCount);
  41. m_condVarDestroyRecord.wait_for(m_lock, std::chrono::seconds(2), [this]() {
  42. return m_isDestroyeRecordThread.load();
  43. });
  44. // SPDLOG_LOGGER_WARN(m_logger, "销毁录音线程函数被唤醒, 销毁标志: {}", m_isDestroyeRecordThread.load());
  45. if(m_isDestroyeRecordThread.load() == false)
  46. {
  47. continue;
  48. }
  49. /* 销毁标志位置为false */
  50. m_isDestroyeRecordThread.store(false);
  51. /* 获取所有引用计数为0的录音线程 */
  52. QList<std::string> removePCMList; // 需要移除的录音通道列表
  53. for(auto it = m_mapRecordThreadRefCount.begin(); it != m_mapRecordThreadRefCount.end(); it++)
  54. {
  55. if(it->second.empty())
  56. {
  57. removePCMList.push_back(it->first);
  58. }
  59. }
  60. /* 停止线程 */
  61. for(const auto& pcmName : removePCMList)
  62. {
  63. OneSoundCardPCMInfo_t pcmInfo;
  64. pcmInfo.pcmInfo.strPCMName = pcmName;
  65. stopRecordAllThreads(pcmInfo);
  66. }
  67. /* 销毁线程 */
  68. destroyRecordThread();
  69. }
  70. }
  71. /* 创建一个录音通道及其附属的线程
  72. 注意:这个函数在对比项线程中运行
  73. */
  74. bool ThreadManager::createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID)
  75. {
  76. /* 先查找队列中有没有该录音通道 */
  77. std::unique_lock<std::mutex> lock(m_mutexRecordThreadRefCount);
  78. for(const auto& pair : m_mapRecordThreadRefCount)
  79. {
  80. if( pair.first == pcmInfo.pcmInfo.strPCMName)
  81. {
  82. SPDLOG_LOGGER_TRACE(m_logger, "{}:{} 录音线程已存在", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  83. /* 录音线程已存在,增加引用计数
  84. 先判断对比项ID是否已经在列表中了 */
  85. bool idFound = false;
  86. for(const auto& it : pair.second)
  87. {
  88. if(it == compareItemID)
  89. {
  90. idFound = true;
  91. break;
  92. }
  93. }
  94. if(!idFound)
  95. {
  96. /* 如果对比项ID不存在,则添加到引用计数中 */
  97. m_mapRecordThreadRefCount[pair.first].push_back(compareItemID);
  98. }
  99. SPDLOG_LOGGER_INFO(m_logger, "{}:{} 录音线程引用计数增加,当前计数: {}",
  100. pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName, m_mapRecordThreadRefCount[pair.first].size());
  101. /* 返回成功 */
  102. return true;
  103. }
  104. }
  105. /* 录音线程不存在,挨个创建线程 */
  106. /* 先创建生成wav小文件数据的线程 */
  107. RecordThreadInfo_t threadInfo;
  108. threadInfo.cardRoadInfo = pcmInfo;
  109. threadInfo.threadState.store(EThreadState::State_Inited);
  110. threadInfo.threadType = EThreadType::Type_CreateWAV;
  111. CreateWAVThread* pCreateWAVThread = new CreateWAVThread(threadInfo);
  112. if(pCreateWAVThread == nullptr)
  113. {
  114. SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建生成wav小文件线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  115. // return false; // 创建失败
  116. }else
  117. {
  118. CPPTP.add_task(&CreateWAVThread::thread_task, pCreateWAVThread);
  119. std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
  120. m_createWAVThreads.push_back(pCreateWAVThread);
  121. }
  122. /* 创建计算音量的线程 */
  123. threadInfo.threadType = EThreadType::Type_CreateDB;
  124. CreateDBThread* pCreateDBThread = new CreateDBThread(threadInfo);
  125. if(pCreateDBThread == nullptr)
  126. {
  127. SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建计算音量线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  128. // return false; // 创建失败
  129. }else
  130. {
  131. CPPTP.add_task(&CreateDBThread::thread_task, pCreateDBThread);
  132. std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
  133. m_createDBThreads.push_back(pCreateDBThread);
  134. }
  135. /* 创建生成长文件的线程 */
  136. threadInfo.threadType = EThreadType::Type_CreateLongWAV;
  137. CreateRecordFileThread* pCreateLongWAVThread = new CreateRecordFileThread(threadInfo);
  138. if(pCreateLongWAVThread == nullptr)
  139. {
  140. SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建生成长文件线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  141. // return false; // 创建失败
  142. }else
  143. {
  144. CPPTP.add_task(&CreateRecordFileThread::thread_task, pCreateLongWAVThread);
  145. std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
  146. m_createLongWAVThreads.push_back(pCreateLongWAVThread);
  147. }
  148. /* 创建发送RTP数据的线程 */
  149. threadInfo.threadType = EThreadType::Type_RtpSend;
  150. CPPTP.add_task(&ThreadManager::thread_RTPSend, threadInfo);
  151. /* 创建分派数据线程 */
  152. threadInfo.threadType = EThreadType::Type_AssignSrcData;
  153. AssignSrcDataThread* pAssignSrcDataThread = new AssignSrcDataThread(threadInfo);
  154. if(pAssignSrcDataThread == nullptr)
  155. {
  156. SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建分派数据线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  157. // return false; // 创建失败
  158. }else
  159. {
  160. CPPTP.add_task(&AssignSrcDataThread::thread_task, pAssignSrcDataThread);
  161. std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
  162. m_assignSrcDataThreads.push_back(pAssignSrcDataThread);
  163. }
  164. /* 创建录音线程 */
  165. threadInfo.threadType = EThreadType::Type_RecordSrc;
  166. RecordThread* pRecordThread = new RecordThread(threadInfo);
  167. if(pRecordThread == nullptr)
  168. {
  169. SPDLOG_LOGGER_ERROR(m_logger, "{}:{} 创建录音线程失败", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  170. // return false; // 创建失败
  171. }else
  172. {
  173. CPPTP.add_task(&RecordThread::thread_task, pRecordThread);
  174. std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
  175. m_recordThreads.push_back(pRecordThread);
  176. }
  177. /* 录音线程创建成功,增加引用计数 */
  178. m_mapRecordThreadRefCount[pcmInfo.pcmInfo.strPCMName].push_back(compareItemID);
  179. // SPDLOG_LOGGER_INFO(m_logger, "{}:{} 录音线程创建成功,map Size: {}, 当前引用计数: {}",
  180. // pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName, m_mapRecordThreadRefCount.size(), m_mapRecordThreadRefCount[pcmInfo.pcmInfo.strPCMName].size());
  181. return true;
  182. }
  183. /**
  184. 销毁一个录音通道及其附属的线程,如果引用计数为0, 这里只停止该录音通道的所有线程,不会删除实例
  185. 线程实例会由其他管理线程定期去删除
  186. 注意:这个函数其实是在对比项线程中运行的
  187. */
  188. bool ThreadManager::removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID)
  189. {
  190. // SPDLOG_LOGGER_WARN(m_logger, "{}:{} 准备减少录音线程计数...", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  191. std::unique_lock<std::mutex> lock(m_mutexRecordThreadRefCount);
  192. // SPDLOG_LOGGER_WARN(m_logger, "{}:{} 准备销毁录音线程, map Size: {}", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName, m_mapRecordThreadRefCount.size());
  193. /* 先查找这个引用计数是否存在 */
  194. int refCount = -1;
  195. for(auto& pair : m_mapRecordThreadRefCount)
  196. {
  197. if(pair.first == pcmInfo.pcmInfo.strPCMName)
  198. {
  199. /* 找到该引用计数,减少引用计数 */
  200. for(auto& it : pair.second)
  201. {
  202. if(it == compareItemID)
  203. {
  204. m_mapRecordThreadRefCount[pair.first].remove(it);
  205. break;
  206. }
  207. }
  208. refCount = m_mapRecordThreadRefCount[pair.first].size();
  209. break;
  210. }
  211. }
  212. std::string logBase = fmt::format("{}:{}", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  213. if(refCount > 0)
  214. {
  215. SPDLOG_LOGGER_INFO(m_logger, "{} 录音线程引用计数减少,当前计数: {}", logBase, refCount);
  216. return true;
  217. }
  218. else if(refCount < 0)
  219. {
  220. SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程未找到,可能已经释放", logBase);
  221. return true;
  222. }
  223. SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程引用计数为0,需要释放该录音通道的所有线程", logBase);
  224. /* 设置销毁录音线程标志 */
  225. m_isDestroyeRecordThread.store(true);
  226. m_condVarDestroyRecord.notify_one();
  227. return true;
  228. }
  229. /* 查找录音线程 */
  230. BaseRecordThread* ThreadManager::findRecordThread(EThreadType type, std::string pcmName)
  231. {
  232. switch(type)
  233. {
  234. case EThreadType::Type_RecordSrc: /* 录音线程 */
  235. {
  236. std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
  237. for (auto& pThread : m_recordThreads)
  238. {
  239. if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
  240. {
  241. return pThread;
  242. }
  243. }
  244. }
  245. break;
  246. case EThreadType::Type_CreateWAV: /* 创建wav小文件和分离左右声道的线程 */
  247. {
  248. std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
  249. for (auto& pThread : m_createWAVThreads)
  250. {
  251. if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
  252. {
  253. return pThread;
  254. }
  255. }
  256. }
  257. break;
  258. case EThreadType::Type_CreateDB: /* 计算音量和反相的线程 */
  259. {
  260. std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
  261. for (auto& pThread : m_createDBThreads)
  262. {
  263. if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
  264. {
  265. return pThread;
  266. }
  267. }
  268. }
  269. break;
  270. case EThreadType::Type_CreateLongWAV: /* 创建长文件的线程 */
  271. {
  272. std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
  273. for (auto& pThread : m_createLongWAVThreads)
  274. {
  275. if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
  276. {
  277. return pThread;
  278. }
  279. }
  280. }
  281. break;
  282. case EThreadType::Type_AssignSrcData: /* 分派数据线程 */
  283. {
  284. std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
  285. for (auto& pThread : m_assignSrcDataThreads)
  286. {
  287. if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
  288. {
  289. return pThread;
  290. }
  291. }
  292. }
  293. break;
  294. case EThreadType::Type_RtpSend: /* RTP发送线程 */
  295. {
  296. std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
  297. for (auto& pThread : m_rtpSendThreads)
  298. {
  299. if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
  300. {
  301. return pThread;
  302. }
  303. }
  304. }
  305. break;
  306. default:
  307. SPDLOG_LOGGER_ERROR(m_logger, "{} 查找录音线程失败,未知线程类型: {}", m_logBase, static_cast<int>(type));
  308. return nullptr; // 未知线程类型
  309. }
  310. return nullptr;
  311. }
  312. /* 获取创建WAV线程指针 */
  313. CreateWAVThread* ThreadManager::getCreateWAVThread(std::string pcmName)
  314. {
  315. std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
  316. for(auto& pThread : m_createWAVThreads)
  317. {
  318. if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
  319. {
  320. return dynamic_cast<CreateWAVThread*>(pThread);
  321. }
  322. }
  323. return nullptr;
  324. }
  325. /* 获取创建音量值的线程 */
  326. CreateDBThread* ThreadManager::getCreateDBThread(std::string pcmName)
  327. {
  328. std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
  329. for(auto& pThread : m_createDBThreads)
  330. {
  331. if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
  332. {
  333. return dynamic_cast<CreateDBThread*>(pThread);
  334. }
  335. }
  336. return nullptr;
  337. }
  338. /* 获取发送Rtp数据的线程 */
  339. RTPOneRoadThread* ThreadManager::getRtpSendThread(std::string pcmName)
  340. {
  341. std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
  342. for(auto& pThread : m_rtpSendThreads)
  343. {
  344. const auto& threadInfo = pThread->getThreadInfo();
  345. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmName)
  346. {
  347. return dynamic_cast<RTPOneRoadThread*>(pThread);
  348. }
  349. }
  350. return nullptr;
  351. }
  352. /* 获取录制报警文件的线程 */
  353. CreateRecordFileThread* ThreadManager::getCreateRecordFileThread(std::string pcmName)
  354. {
  355. std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
  356. for(auto& pThread : m_createLongWAVThreads)
  357. {
  358. if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
  359. {
  360. return dynamic_cast<CreateRecordFileThread*>(pThread);
  361. }
  362. }
  363. return nullptr;
  364. }
  365. /* RTP线程函数,套一层壳 */
  366. void ThreadManager::thread_RTPSend(RecordThreadInfo_t& threadInfo)
  367. {
  368. RTPOneRoadThread* pRtpSendThread = new RTPOneRoadThread(threadInfo);
  369. if(pRtpSendThread == nullptr)
  370. {
  371. SPDLOG_ERROR("{}:{} 创建RTP发送线程失败", threadInfo.cardRoadInfo.strSoundCardName, threadInfo.cardRoadInfo.pcmInfo.strPCMName);
  372. return;
  373. }
  374. /* 先加入队列,再开启线程 */
  375. ThreadMan.m_mutexRtpSendThreads.lock();
  376. ThreadMan.m_rtpSendThreads.push_back(pRtpSendThread);
  377. ThreadMan.m_mutexRtpSendThreads.unlock();
  378. pRtpSendThread->thread_task();
  379. }
  380. /* 停止某个录音通道的所有的线程 */
  381. void ThreadManager::stopRecordAllThreads(const OneSoundCardPCMInfo_t& pcmInfo)
  382. {
  383. std::string logBase = fmt::format("{}:{}", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
  384. /* 引用计数为0,停止该录音通道的所有线程 */
  385. /* 停止录音线程 */
  386. {
  387. std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
  388. SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程列表Size: {}", logBase, m_recordThreads.size());
  389. for(auto it : m_recordThreads)
  390. {
  391. const auto& threadInfo = it->getThreadInfo();
  392. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
  393. {
  394. SPDLOG_LOGGER_TRACE(m_logger, "{} 准备停止录音线程: {}", logBase, threadInfo.cardRoadInfo.pcmInfo.strPCMName);
  395. it->thread_stop_block();
  396. SPDLOG_LOGGER_TRACE(m_logger, "{} 录音线程已停止", logBase);
  397. break;
  398. }
  399. }
  400. }
  401. /* 停止分派任务线程 */
  402. {
  403. std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
  404. for(auto it : m_assignSrcDataThreads)
  405. {
  406. const auto& threadInfo = it->getThreadInfo();
  407. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
  408. {
  409. it->thread_stop_block();
  410. SPDLOG_LOGGER_TRACE(m_logger, "{} 分派数据线程已停止", logBase);
  411. break;
  412. }
  413. }
  414. }
  415. /* 停止生成wav小文件线程 */
  416. {
  417. std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
  418. for(auto it : m_createWAVThreads)
  419. {
  420. const auto& threadInfo = it->getThreadInfo();
  421. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
  422. {
  423. it->thread_stop_block();
  424. SPDLOG_LOGGER_TRACE(m_logger, "{} 生成wav小文件线程已停止", logBase);
  425. break;
  426. }
  427. }
  428. }
  429. /* 停止计算音量线程 */
  430. {
  431. std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
  432. for(auto it : m_createDBThreads)
  433. {
  434. const auto& threadInfo = it->getThreadInfo();
  435. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
  436. {
  437. it->thread_stop_block();
  438. SPDLOG_LOGGER_TRACE(m_logger, "{} 计算音量线程已停止", logBase);
  439. break;
  440. }
  441. }
  442. }
  443. /* 停止生成长文件线程 */
  444. {
  445. std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
  446. for(auto it : m_createLongWAVThreads)
  447. {
  448. const auto& threadInfo = it->getThreadInfo();
  449. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
  450. {
  451. it->thread_stop_block();
  452. SPDLOG_LOGGER_TRACE(m_logger, "{} 生成长文件线程已停止", logBase);
  453. break;
  454. }
  455. }
  456. }
  457. /* 停止发送RTP数据线程 */
  458. {
  459. std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
  460. for(auto it : m_rtpSendThreads)
  461. {
  462. const auto& threadInfo = it->getThreadInfo();
  463. if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
  464. {
  465. it->thread_stop_block();
  466. SPDLOG_LOGGER_TRACE(m_logger, "{} 发送RTP数据线程已停止", logBase);
  467. break;
  468. }
  469. }
  470. }
  471. /* 从引用计数中移除该录音通道 */
  472. auto it = m_mapRecordThreadRefCount.find(pcmInfo.pcmInfo.strPCMName);
  473. if(it != m_mapRecordThreadRefCount.end())
  474. {
  475. m_mapRecordThreadRefCount.erase(it);
  476. SPDLOG_LOGGER_WARN(m_logger, " ➢ 录音通道: {} 线程已全部停止运行", logBase);
  477. } else
  478. {
  479. SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程引用计数未找到", logBase);
  480. }
  481. }
  482. /* 销毁录音线程 */
  483. void ThreadManager::destroyRecordThread()
  484. {
  485. SPDLOG_LOGGER_DEBUG(m_logger, "{} 准备销毁录音线程...", m_logBase);
  486. /* 销毁录音线程 */
  487. {
  488. std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
  489. for(auto it = m_recordThreads.begin(); it != m_recordThreads.end(); )
  490. {
  491. BaseRecordThread* pThread = *it;
  492. if(pThread == nullptr)
  493. {
  494. /* 删除空指针元素 */
  495. it = m_recordThreads.erase(it);
  496. continue;
  497. }
  498. auto threadState = pThread->getThreadInfo().threadState.load();
  499. if(EThreadState::State_Stopped == threadState ||
  500. EThreadState::State_Error == threadState )
  501. {
  502. SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁录音线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName,
  503. pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
  504. auto pRecordThread = dynamic_cast<RecordThread*>(pThread);
  505. delete pRecordThread; // 删除线程
  506. pThread = nullptr;
  507. it = m_recordThreads.erase(it);
  508. continue;
  509. }
  510. ++it;
  511. }
  512. }
  513. /* 销毁分派线程 */
  514. {
  515. std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
  516. for(auto it = m_assignSrcDataThreads.begin(); it != m_assignSrcDataThreads.end(); )
  517. {
  518. BaseRecordThread* pThread = *it;
  519. if(pThread == nullptr)
  520. {
  521. it = m_assignSrcDataThreads.erase(it);
  522. continue;
  523. }
  524. auto threadState = pThread->getThreadInfo().threadState.load();
  525. if(EThreadState::State_Stopped == threadState ||
  526. EThreadState::State_Error == threadState )
  527. {
  528. SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁分派数据线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName,
  529. pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
  530. auto pAssignSrcDataThread = dynamic_cast<AssignSrcDataThread*>(pThread);
  531. delete pAssignSrcDataThread; // 删除线程
  532. pThread = nullptr;
  533. it = m_assignSrcDataThreads.erase(it); // 从列表中移除
  534. continue;
  535. }
  536. ++it;
  537. }
  538. }
  539. /* 销毁生成wav小文件线程 */
  540. {
  541. std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
  542. for(auto it = m_createWAVThreads.begin(); it != m_createWAVThreads.end(); )
  543. {
  544. BaseRecordThread* pThread = *it;
  545. if(pThread == nullptr)
  546. {
  547. it = m_createWAVThreads.erase(it);
  548. continue;
  549. }
  550. auto threadState = pThread->getThreadInfo().threadState.load();
  551. if(EThreadState::State_Stopped == threadState ||
  552. EThreadState::State_Error == threadState )
  553. {
  554. SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateWAV 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName,
  555. pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
  556. auto pCreateWAVThread = dynamic_cast<CreateWAVThread*>(pThread);
  557. delete pCreateWAVThread; // 删除线程
  558. pThread = nullptr;
  559. it = m_createWAVThreads.erase(it); // 从列表中移除
  560. continue;
  561. }
  562. ++it;
  563. }
  564. }
  565. /* 销毁计算音量线程 */
  566. {
  567. std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
  568. for(auto it = m_createDBThreads.begin(); it != m_createDBThreads.end(); )
  569. {
  570. BaseRecordThread* pThread = *it;
  571. if(pThread == nullptr)
  572. {
  573. it = m_createDBThreads.erase(it);
  574. continue;
  575. }
  576. auto threadState = pThread->getThreadInfo().threadState.load();
  577. if(EThreadState::State_Stopped == threadState ||
  578. EThreadState::State_Error == threadState )
  579. {
  580. SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateDB 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName,
  581. pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
  582. auto pCreateDBThread = dynamic_cast<CreateDBThread*>(pThread);
  583. delete pCreateDBThread; // 删除线程
  584. pThread = nullptr;
  585. it = m_createDBThreads.erase(it); // 从列表中移除
  586. continue;
  587. }
  588. ++it;
  589. }
  590. }
  591. /* 销毁生成长文件线程 */
  592. {
  593. std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
  594. for(auto it = m_createLongWAVThreads.begin(); it != m_createLongWAVThreads.end(); )
  595. {
  596. BaseRecordThread* pThread = *it;
  597. if(pThread == nullptr)
  598. {
  599. it = m_createLongWAVThreads.erase(it);
  600. continue;
  601. }
  602. auto threadState = pThread->getThreadInfo().threadState.load();
  603. if(EThreadState::State_Stopped == threadState ||
  604. EThreadState::State_Error == threadState )
  605. {
  606. SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateRecordFileThread 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName,
  607. pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
  608. auto pCreateLongWAVThread = dynamic_cast<CreateRecordFileThread*>(pThread);
  609. delete pCreateLongWAVThread; // 删除线程
  610. pThread = nullptr;
  611. it = m_createLongWAVThreads.erase(it); // 从列表中移除
  612. continue;
  613. }
  614. ++it;
  615. }
  616. }
  617. /* 销毁发送RTP数据线程 */
  618. {
  619. std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
  620. for(auto it = m_rtpSendThreads.begin(); it != m_rtpSendThreads.end(); )
  621. {
  622. BaseRecordThread* pThread = *it;
  623. if(pThread == nullptr)
  624. {
  625. it = m_rtpSendThreads.erase(it);
  626. continue;
  627. }
  628. auto threadState = pThread->getThreadInfo().threadState.load();
  629. if(EThreadState::State_Stopped == threadState ||
  630. EThreadState::State_Error == threadState )
  631. {
  632. SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 RTP Send 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName,
  633. pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
  634. auto pRtpSendThread = dynamic_cast<RTPOneRoadThread*>(pThread);
  635. delete pRtpSendThread; // 删除线程
  636. pThread = nullptr;
  637. it = m_rtpSendThreads.erase(it); // 从列表中移除
  638. }
  639. ++it;
  640. }
  641. }
  642. SPDLOG_LOGGER_DEBUG(m_logger, "{} 录音线程销毁完成", m_logBase);
  643. }