DvppDecoder.h 2.84 KB
#include<string>

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

#include <queue>
#include <mutex>
#include <thread>
#include <chrono>
#include <atomic>

#include "FFRecoderTaskManager.h"

using namespace std;

typedef void(*RECEIVER_FINISHED_CALLBACK)(const void* userPtr);


struct Vdec_CallBack_UserData;

class DvppDecoder{
public:
    DvppDecoder();
    ~DvppDecoder();
    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 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);

    int getCachedQueueLength();

    void doRecode(RecoderInfo& recoderInfo);

    void set_mq_callback(mq_callback_t cb);

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

private:
    AVCodecContext* init_FFmpeg(FFDecConfig config);
    bool init_vdpp(FFDecConfig cfg, AVCodecContext* avctx);
    void release_ffmpeg();
    void read_thread();
    
    int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb);
    bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
    void release_dvpp();

    void display_thread();

    int getVdecType(int videoType, int profile);

private:
    FFDecConfig m_cfg;
    string m_dec_name;

    const void * m_finishedDecArg {nullptr};
    DECODE_FINISHED_CALLBACK decode_finished_cbk {nullptr};

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

    bool m_bExitReportThd{false};
    bool m_bExitDisplayThd{false};

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

    int frame_width{0};
	int frame_height{0};
    bool m_bReal {false}; // 是否实时流
    float m_fps{0.0};

    std::thread* m_read_thread{nullptr};

    bool m_dec_keyframe {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};

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

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