#include #include #include "FrameQueue.h" extern "C" { #include #include #include #include #include #include #include #include } using namespace std; /************************************************** * 接口:DXDECODER_CALLBACK * 功能:解码数据回调接口 * 参数:const dx_void * userPtr 用户自定义数据 * AVFrame * gpuFrame 解码结果帧数据,在设置的对应的gpu上,要十分注意这一点,尤其是多线程情况 * 返回:无 * 备注:当解码库数据源为实时流时(RTSP/GB28181),本接 * 口内不可进行阻塞/耗时操作。当解码库数据源为 * 非实时流时(本地/网络文件),本接口可以进行 * 阻塞/耗时操作 **************************************************/ typedef void(*POST_DECODE_CALLBACK)(const void * userPtr, AVFrame * gpuFrame); typedef void(*DECODE_FINISHED_CALLBACK)(const void* userPtr); struct FFDecConfig{ string uri; // 视频地址 POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口 DECODE_FINISHED_CALLBACK decode_finished_cbk; // 解码线程结束后的回调接口 string gpuid; // gpu id bool force_tcp{true}; // 是否指定使用tcp连接 }; struct FFImgInfo{ int width; int height; unsigned char * pData; }; class FFNvDecoder{ public: FFNvDecoder(); ~FFNvDecoder(); bool init(FFDecConfig& cfg); void close(); void start(); void pause(); void resume(); void setDecKeyframe(bool bKeyframe); bool isRunning(); bool isFinished(); bool isPausing(); bool getResolution( int &width, int &height ); void setName(string nm); string getName(); bool isSurport(FFDecConfig& cfg); int getCachedQueueLength(); static FFImgInfo* snapshot(const string& uri); static void releaseFFImgInfo(FFImgInfo*); public: AVPixelFormat getHwPixFmt(); private: void decode_thread(); void post_decode_thread(); bool init(const char* uri, const char* gpuid, bool force_tcp); void decode_finished(); public: POST_DECODE_CALLBACK post_decoded_cbk; DECODE_FINISHED_CALLBACK decode_finished_cbk; const void * m_userPtr; FFDecConfig m_cfg; private: AVStream* stream; AVCodecContext *avctx; int stream_index; AVFormatContext *fmt_ctx; AVPixelFormat hw_pix_fmt; pthread_t m_decode_thread; pthread_t m_post_decode_thread; bool m_bRunning; bool m_bFinished; string name; bool m_bPause; FrameQueue mFrameQueue; bool m_bReal; // 是否实时流 bool m_dec_keyframe; };