#ifndef AVPLAYER2_AUDIO_PLAY_THREAD_H #define AVPLAYER2_AUDIO_PLAY_THREAD_H #pragma once #include #include #include #include #include #include #include #include #include #include #include "packets_sync.h" #include "ThreadBase.h" #define BUFFER_LEN 8192 // 1024 typedef struct AudioData { uint16_t len = 0; char buffer[BUFFER_LEN] = {0}; } AudioData; typedef struct AudioFrameFmt { uint sample_rate; uint sample_fmt; // AV_SAMPLE_FMT_S16 uint channel; int byte_order; // QAudioFormat::LittleEndian; int sample_type; // QAudioFormat::SignedInt } AudioFrameFmt; class AudioPlayThread : public ThreadBase { public: explicit AudioPlayThread(VideoState* pState = nullptr); virtual ~AudioPlayThread(); public: void print_device() const; bool init_device(int sample_rate = 8000, int channel = 1, AVSampleFormat sample_fmt = AV_SAMPLE_FMT_S16, float default_vol = 0.8); void stop_device(); void play_file(const QString& file); void play_buf(const uint8_t* buf, int datasize); bool init_resample_param(AVCodecContext* pAudio, AVSampleFormat sample_fmt, VideoState* is); void final_resample_param(); float get_device_volume() const; void set_device_volume(float volume); void send_visual_open(bool bSend = true) { m_bSendToVisual = bSend; }; void setOnUpdatePlayTime(std::function cb) { m_onUpdatePlayTime = std::move(cb); } void setOnDataVisualReady(std::function cb) { m_onDataVisualReady = std::move(cb); } protected: void run() override; private: int audio_decode_frame(VideoState* is); private: typedef struct Audio_Resample { struct SwrContext* swrCtx{nullptr}; } Audio_Resample; private: QAudioOutput* m_pOutput; QIODevice* m_audioDevice{nullptr}; VideoState* m_pState{nullptr}; Audio_Resample m_audioResample; bool m_bSendToVisual{false}; std::function m_onUpdatePlayTime; std::function m_onDataVisualReady; }; #endif // AVPLAYER2_AUDIO_PLAY_THREAD_H