DvppRtpDecoder.h 3.52 KB
#ifndef __DVPP_RTP_DECODER_H__
#define __DVPP_RTP_DECODER_H__

#include <stdint.h>
#include <atomic>
#include <thread>
#include <queue>
#include <mutex>
#include <chrono>
#include <string>

#include "depend_headers.h"
#include "dvpp_headers.h"
#include "DvppDataMemory.hpp"

#include "FFRecoderTaskManager.h"

#include "VpcUtils.h"

using namespace std;

#define MAX_RTP_BUFFER_SIZE 4194304 // 4M = 4 * 1024 * 1024 = 4194304 字节


typedef void(*CallBack_DecodeFinished)(void* userdata);

class DvppRtpDecoder
{
public:
	DvppRtpDecoder();
	~DvppRtpDecoder();

public:
    bool Init(FFDecConfig cfg);
    void Close();
    bool start();
    void pause();
    void resume();

    void setDecKeyframe(bool bKeyframe);

    bool isRunning();
    bool isFinished();
    bool isPausing();
    bool getResolution( int &width, int &height );
    bool getOutResolution( int &width, int &height );

    bool isSurport(FFDecConfig& cfg);

    float fps();

    void setName(string nm){
        m_dec_name = nm;
    }

    string getName(){
        return m_dec_name;
    }

    DeviceMemory* snapshot();

    void setPostDecArg(const void* postDecArg);
    void setFinishedDecArg(const void* finishedDecArg);

	DvppDataMemory* GetFrame();

    void doRecode(RecoderInfo& recoderInfo);

    void set_mq_callback(mq_callback_t cb);

	void CacheBuffer(uint8_t* buf, int buf_size);

	int ReadBuffer(uint8_t* buf, int buffsize);

    void SetFinishedCallback(CallBack_DecodeFinished cb, void* param);

public:
    void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData);
    void doProcessReport();

private:
    bool init_dvpp(FFDecConfig cfg);
    void release_ffmpeg();
    void read_thread();
	bool probe();//阻塞式探测国标流并获取解码参数
    
    int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb);
    bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
    void release_dvpp();

    int getVdecType(int videoType, int profile);

    void calcOutResolution(int w, int h);

private:
    FFDecConfig m_cfg;
    string m_dec_name;

    const void * m_finishedDecArg {nullptr};

    bool m_bFinished{false};
    bool m_bRunning{false};
    bool m_bPause{false};

    bool m_bExitReportThd{false};

    // 读取数据
    AVFormatContext *fmt_ctx{nullptr};
	int  mVideoIndex {-1};
    AVPixelFormat pix_fmt;
    AVCodecContext *avctx{nullptr};
    AVBSFContext * h264bsfc{nullptr};

    int frame_width{0};
	int frame_height{0};
    int out_frame_width{0};
	int out_frame_height{0};
    float m_fps{0.0};

    std::thread* m_read_thread{nullptr};

    bool m_dec_keyframe {false};
    bool m_bResize {false};

    // 解码
    int m_dvpp_deviceId {-1};
    int m_dvpp_channel {-1};
    aclrtContext m_context{nullptr};
    acldvppStreamFormat m_enType;

    const void * m_postDecArg {nullptr};
    POST_DECODE_CALLBACK post_decoded_cbk {nullptr};

    int m_vdec_out_size {-1};

    FFRecoderTaskManager m_recoderManager;

    queue<DvppDataMemory*> m_decoded_data_queue;
    mutex m_decoded_data_queue_mtx;

    long long last_ts {0};

    long long m_last_read_ts {0};

    uint64_t m_in_count {0};
    uint64_t m_out_count {0};

    int m_frameSkip {1};

    std::atomic<int> m_DvppCacheCounter{0};
    int m_cache_gop{0};

    VpcUtils m_vpcUtils;

    void*           m_finishParam;
	CallBack_DecodeFinished m_finish_cbk;				// 录像流结束回调

    int m_buffer_waiting_time{3000} ;

    std::atomic<char> m_buffer[MAX_RTP_BUFFER_SIZE];
	std::atomic_int   m_bufferSize {0};

};
#endif //__DVPP_RTP_DECODER_H__