DvppDecoder.h 2.65 KB
#include<string>

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

#include <queue>
#include <mutex>
#include <condition_variable>


using namespace std;

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

const int g_pkt_size = 1024 * 1024;  // 单个AVPacket大小的最大值

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();

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

private:
    AVCodecContext* init_FFmpeg(FFDecConfig config);
    bool init_vdpp(FFDecConfig cfg, AVCodecContext* avctx);
    void release_ffmpeg();
    void read_thread();
    
    void decode_thread();
    int sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count);
    bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
    void release_dvpp();

private:
    FFDecConfig m_cfg;
    string m_dec_name;

    const void * m_finishedDecArg;
    DECODE_FINISHED_CALLBACK decode_finished_cbk {nullptr};

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

    // 读取数据
    AVStream* stream{nullptr};
    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; // 是否实时流
    float m_fps{0.0};

    pthread_t m_read_thread{0};

    bool m_dec_keyframe;

    mutex m_pktQueue_mutex;
    queue<AVPacket*> m_pktQueue;

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

    pthread_t m_decode_thread{0};
    mutex m_vdecQueue_mutex;
    queue<void*> m_vdecQueue;

    const void * m_postDecArg;
    POST_DECODE_CALLBACK post_decoded_cbk {nullptr};

    int m_vdec_out_size {-1};

    // 截图
    bool m_bSnapShoting{false};
    DvppDataMemory* m_cached_mem{nullptr};
    mutex m_cached_mutex;
    condition_variable m_cached_cond;
};