audio_play_thread.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. #include "audio_play_thread.h"
  2. #include "playercontroller.h"
  3. #include <utility>
  4. #include <QLoggingCategory>
  5. Q_LOGGING_CATEGORY(playerControllerAudioPlayThread, "player.controller.AudioPlayThread")
  6. #if !NDEBUG
  7. #define DEBUG_PLAYFILTER 0
  8. #define WRITE_AUDIO_FILE 0
  9. #else
  10. #define DEBUG_PLAYFILTER 0
  11. #define WRITE_AUDIO_FILE 0
  12. #endif
  13. #if WRITE_AUDIO_FILE
  14. #include <fstream>
  15. #endif
  16. AudioPlayThread::AudioPlayThread(VideoState* pState)
  17. : m_pOutput(nullptr)
  18. , m_pState(pState)
  19. {
  20. qRegisterMetaType<AudioData>("AudioData");
  21. }
  22. AudioPlayThread::~AudioPlayThread()
  23. {
  24. stop();
  25. stop_device();
  26. final_resample_param();
  27. // 确保QAudioOutput被正确释放
  28. if (m_pOutput) {
  29. delete m_pOutput;
  30. m_pOutput = nullptr;
  31. }
  32. }
  33. void AudioPlayThread::print_device() const
  34. {
  35. QAudioDeviceInfo deviceInfo = QAudioDeviceInfo::defaultOutputDevice();
  36. auto deviceInfos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
  37. for (const QAudioDeviceInfo& deviceInfo : std::as_const(deviceInfos))
  38. qDebug() << "Input device name: " << deviceInfo.deviceName();
  39. deviceInfos = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
  40. for (const QAudioDeviceInfo& deviceInfo : std::as_const(deviceInfos))
  41. qDebug() << "Output device name: " << deviceInfo.deviceName();
  42. const auto edians = deviceInfo.supportedByteOrders();
  43. for (const QAudioFormat::Endian& endian : edians)
  44. qDebug() << "Endian: " << endian;
  45. const auto sampleTypes = deviceInfo.supportedSampleTypes();
  46. for (const QAudioFormat::SampleType& sampleType : sampleTypes)
  47. qDebug() << "sampleType: " << sampleType;
  48. const auto codecs = deviceInfo.supportedCodecs();
  49. for (const QString& codec : codecs)
  50. qDebug() << "codec: " << codec;
  51. const auto sampleRates = deviceInfo.supportedSampleRates();
  52. for (const int& sampleRate : sampleRates)
  53. qDebug() << "sampleRate: " << sampleRate;
  54. const auto ChannelCounts = deviceInfo.supportedChannelCounts();
  55. for (const int& channelCount : ChannelCounts)
  56. qDebug() << "channelCount: " << channelCount;
  57. const auto sampleSizes = deviceInfo.supportedSampleSizes();
  58. for (const int& sampleSize : sampleSizes)
  59. qDebug() << "sampleSize: " << sampleSize;
  60. }
  61. bool AudioPlayThread::init_device(int sample_rate,
  62. int channel,
  63. AVSampleFormat sample_fmt,
  64. float default_vol)
  65. {
  66. QAudioDeviceInfo deviceInfo = QAudioDeviceInfo::defaultOutputDevice();
  67. QAudioFormat format;
  68. format.setSampleRate(sample_rate);
  69. format.setChannelCount(channel);
  70. format.setSampleSize(8 * av_get_bytes_per_sample(sample_fmt));
  71. format.setCodec("audio/pcm");
  72. format.setByteOrder(QAudioFormat::LittleEndian);
  73. format.setSampleType(QAudioFormat::SignedInt);
  74. // qDebug("sample size=%d\n", 8 * av_get_bytes_per_sample(sample_fmt));
  75. if (!deviceInfo.isFormatSupported(format)) {
  76. qWarning() << "Raw audio format not supported!";
  77. return false;
  78. }
  79. // 使用智能指针管理QAudioOutput,确保异常安全
  80. m_pOutput = new QAudioOutput(deviceInfo, format);
  81. // 注意:不设置parent,手动管理生命周期以确保正确的清理顺序
  82. set_device_volume(default_vol);
  83. m_audioDevice = m_pOutput->start();
  84. return true;
  85. }
  86. float AudioPlayThread::get_device_volume() const
  87. {
  88. if (m_pOutput)
  89. return m_pOutput->volume();
  90. return 0;
  91. }
  92. void AudioPlayThread::set_device_volume(float volume)
  93. {
  94. if (m_pOutput)
  95. m_pOutput->setVolume(volume);
  96. }
  97. void AudioPlayThread::stop_device()
  98. {
  99. if (m_pOutput) {
  100. m_pOutput->stop();
  101. m_pOutput->reset();
  102. m_audioDevice = nullptr; // 清空设备指针,避免悬空指针
  103. }
  104. }
  105. void AudioPlayThread::play_file(const QString& file)
  106. {
  107. /*play pcm file directly*/
  108. QFile audioFile;
  109. audioFile.setFileName(file);
  110. audioFile.open(QIODevice::ReadOnly);
  111. m_pOutput->start(&audioFile);
  112. }
  113. void AudioPlayThread::play_buf(const uint8_t* buf, int datasize)
  114. {
  115. if (!m_audioDevice)
  116. return;
  117. uint8_t* data = (uint8_t*) buf;
  118. while (datasize > 0) {
  119. qint64 len = m_audioDevice->write((const char*) data, datasize);
  120. if (len < 0)
  121. break;
  122. if (len > 0) {
  123. data = data + len;
  124. datasize -= len;
  125. }
  126. // qDebug("play buf:reslen:%d, write len:%d", len, datasize);
  127. }
  128. }
  129. void AudioPlayThread::run()
  130. {
  131. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] run start, m_pState:" << (void*) m_pState;
  132. assert(m_pState);
  133. VideoState* is = m_pState;
  134. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] VideoState* is:" << (void*) is
  135. << ", abort_request:" << is->abort_request;
  136. int audio_size;
  137. int loop_count = 0;
  138. for (;;) {
  139. if (isExit()) {
  140. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] m_exit set, exit.";
  141. break;
  142. }
  143. if (is->abort_request) {
  144. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] abort_request set, exit.";
  145. break;
  146. }
  147. if (is->paused) {
  148. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] paused, wait.";
  149. std::unique_lock<std::mutex> lock(m_mutex);
  150. m_cv.wait_for(lock, std::chrono::milliseconds(10), [this] { return isExit(); });
  151. continue;
  152. }
  153. qCDebug(playerControllerAudioPlayThread)
  154. << "[AudioPlayThread] call audio_decode_frame, loop:" << loop_count
  155. << ", sampq size:" << (is ? is->sampq.size : -1);
  156. audio_size = audio_decode_frame(is);
  157. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] audio_decode_frame ret:" << audio_size
  158. << ", loop:" << loop_count++;
  159. if (audio_size < 0) {
  160. qCWarning(playerControllerAudioPlayThread) << "[AudioPlayThread] audio_decode_frame failed, exit.";
  161. break;
  162. }
  163. if (!isnan(is->audio_clock)) {
  164. AVCodecContext* pAudioCodex = is->auddec.avctx;
  165. if (pAudioCodex) {
  166. int bytes_per_sec = av_samples_get_buffer_size(nullptr,
  167. pAudioCodex->ch_layout.nb_channels,
  168. pAudioCodex->sample_rate,
  169. AV_SAMPLE_FMT_S16,
  170. 1);
  171. int64_t audio_callback_time = av_gettime_relative();
  172. set_clock_at(&is->audclk,
  173. is->audio_clock - (double) (audio_size) / bytes_per_sec,
  174. is->audio_clock_serial,
  175. audio_callback_time / 1000000.0);
  176. sync_clock_to_slave(&is->extclk, &is->audclk);
  177. }
  178. }
  179. }
  180. qCDebug(playerControllerAudioPlayThread) << "[AudioPlayThread] run end, abort_request:" << is->abort_request
  181. << ", m_exit:" << (m_exit ? m_exit->load() : -1);
  182. }
  183. int AudioPlayThread::audio_decode_frame(VideoState* is)
  184. {
  185. int data_size;
  186. Frame* af;
  187. do {
  188. while (frame_queue_nb_remaining(&is->sampq) == 0) {
  189. if (is->eof) {
  190. // break;
  191. return -1;
  192. } else {
  193. av_usleep(1000);
  194. // return -1;
  195. }
  196. if (is->abort_request || isExit())
  197. break;
  198. }
  199. if (is->abort_request || isExit())
  200. return -1;
  201. if (!(af = frame_queue_peek_readable(&is->sampq)))
  202. return -1;
  203. frame_queue_next(&is->sampq);
  204. } while (af->serial != is->audioq.serial);
  205. /*data_size = av_samples_get_buffer_size(nullptr, af->frame->channels,
  206. af->frame->nb_samples,
  207. AVSampleFormat(af->frame->format), 1);*/
  208. #if USE_AVFILTER_AUDIO
  209. data_size = av_samples_get_buffer_size(nullptr,
  210. af->frame->ch_layout.nb_channels,
  211. af->frame->nb_samples,
  212. AV_SAMPLE_FMT_S16,
  213. 1);
  214. uint8_t* const buffer_audio = (uint8_t*) av_malloc(data_size * sizeof(uint8_t));
  215. memcpy(buffer_audio, af->frame->data[0], data_size);
  216. #else
  217. struct SwrContext* swrCtx = m_audioResample.swrCtx;
  218. data_size = av_samples_get_buffer_size(nullptr,
  219. af->frame->channels,
  220. af->frame->nb_samples,
  221. AV_SAMPLE_FMT_S16,
  222. 0); // AVSampleFormat(af->frame->format)
  223. uint8_t* buffer_audio = (uint8_t*) av_malloc(data_size * sizeof(uint8_t));
  224. int ret = swr_convert(swrCtx,
  225. &buffer_audio,
  226. af->frame->nb_samples,
  227. (const uint8_t**) (af->frame->data),
  228. af->frame->nb_samples);
  229. if (ret < 0) {
  230. return 0;
  231. }
  232. #endif
  233. if (is->muted && data_size > 0)
  234. memset(buffer_audio, 0, data_size); // mute
  235. #if WRITE_AUDIO_FILE
  236. std::ofstream myfile;
  237. myfile.open("audio.pcm", std::ios::out | std::ios::app | std::ios::binary);
  238. if (myfile.is_open()) {
  239. myfile.write((char*) buffer_audio, data_size);
  240. }
  241. #endif
  242. if (m_bSendToVisual) {
  243. AudioData data;
  244. // 增强的缓冲区大小检查
  245. if (data_size <= 0) {
  246. qCWarning(playerControllerAudioPlayThread) << "Invalid audio data size:" << data_size;
  247. } else if (data_size > BUFFER_LEN) {
  248. qCWarning(playerControllerAudioPlayThread) << "Audio frame too large, data_size:" << data_size
  249. << ", buffer_len:" << BUFFER_LEN << ", will truncate";
  250. }
  251. // 安全的内存拷贝
  252. if (data_size > 0 && buffer_audio) {
  253. int len = std::min(data_size, BUFFER_LEN);
  254. memcpy(data.buffer, buffer_audio, len);
  255. data.len = len;
  256. // 安全地调用回调函数
  257. try {
  258. if (m_onDataVisualReady) {
  259. m_onDataVisualReady(data);
  260. }
  261. } catch (...) {
  262. qCWarning(playerControllerAudioPlayThread) << "Exception in visual data callback";
  263. }
  264. }
  265. }
  266. play_buf(buffer_audio, data_size);
  267. av_free((void*) buffer_audio);
  268. /* update the audio clock with the pts */
  269. if (!isnan(af->pts)) {
  270. // is->audio_clock = af->pts + (double)af->frame->nb_samples /
  271. // af->frame->sample_rate;
  272. double frame = (double) af->frame->nb_samples / af->frame->sample_rate;
  273. // frame = frame * is->audio_speed;
  274. is->audio_clock = af->pts + frame;
  275. #if USE_AVFILTER_AUDIO
  276. is->audio_clock = is->audio_clock_old
  277. + (is->audio_clock - is->audio_clock_old) * is->audio_speed;
  278. // is->audio_clock = is->audio_clock * is->audio_speed;
  279. #endif
  280. #if DEBUG_PLAYFILTER
  281. static int pks_num = 0;
  282. pks_num++;
  283. qDebug("[%d]audio: clock=%0.3f pts=%0.3f, (nb:%d, sr:%d)frame:%0.3f\n",
  284. pks_num,
  285. is->audio_clock,
  286. af->pts,
  287. af->frame->nb_samples,
  288. af->frame->sample_rate,
  289. frame);
  290. // qDebug("audio: clock=%0.3f pts=%0.3f, (nb:%d, sr:%d)frame:%0.3f\n",
  291. // is->audio_clock, af->pts, af->frame->nb_samples, af->frame->sample_rate,
  292. // frame);
  293. #endif
  294. } else {
  295. is->audio_clock = NAN;
  296. }
  297. is->audio_clock_serial = af->serial;
  298. if (m_onUpdatePlayTime)
  299. m_onUpdatePlayTime();
  300. #if (!NDEBUG && PRINT_PACKETQUEUE_AUDIO_INFO)
  301. {
  302. static double last_clock;
  303. qDebug("audio: delay=%0.3f clock=%0.3f\n", is->audio_clock - last_clock, is->audio_clock);
  304. last_clock = is->audio_clock;
  305. }
  306. #endif
  307. return data_size;
  308. }
  309. bool AudioPlayThread::init_resample_param(AVCodecContext* pAudio,
  310. AVSampleFormat sample_fmt,
  311. VideoState* is)
  312. {
  313. if (pAudio) {
  314. int ret = -1;
  315. struct SwrContext* swrCtx = nullptr;
  316. #if USE_AVFILTER_AUDIO
  317. if (is) {
  318. AVFilterContext* sink = is->out_audio_filter;
  319. // int sample_rate = av_buffersink_get_sample_rate(sink);
  320. // int nb_channels = av_buffersink_get_channels(sink);
  321. AVChannelLayout channel_layout;
  322. av_buffersink_get_ch_layout(sink, &channel_layout);
  323. // int64_t channel_layout = av_buffersink_get_channel_layout(sink);
  324. int format = av_buffersink_get_format(sink);
  325. ret = swr_alloc_set_opts2(&swrCtx,
  326. &pAudio->ch_layout,
  327. sample_fmt,
  328. pAudio->sample_rate,
  329. &channel_layout,
  330. (AVSampleFormat) format,
  331. pAudio->sample_rate,
  332. 0,
  333. nullptr);
  334. /*m_audioResample.channel_layout = channel_layout;
  335. m_audioResample.sample_fmt = sample_fmt;
  336. m_audioResample.sample_rate = pAudio->sample_rate;*/
  337. }
  338. #else
  339. ret = swr_alloc_set_opts2(&swrCtx,
  340. &pAudio->ch_layout,
  341. sample_fmt,
  342. pAudio->sample_rate,
  343. &pAudio->ch_layout,
  344. pAudio->sample_fmt,
  345. pAudio->sample_rate,
  346. 0,
  347. nullptr);
  348. #endif
  349. if (!(ret < 0)) {
  350. swr_init(swrCtx);
  351. m_audioResample.swrCtx = swrCtx;
  352. return true;
  353. }
  354. }
  355. return false;
  356. }
  357. void AudioPlayThread::final_resample_param()
  358. {
  359. // 安全释放重采样上下文
  360. if (m_audioResample.swrCtx) {
  361. swr_free(&m_audioResample.swrCtx);
  362. m_audioResample.swrCtx = nullptr;
  363. }
  364. }