DvppDecoder2.h 3.94 KB
#include<string>

#include "depend_headers.h"
#include "CircularQueue.hpp"
#include "FFReceiver.h"
#include "DvppDec.h"

using namespace std;

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

    FFImgInfo* snapshot();

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

    int getCachedQueueLength();

public:
    void taskFinishing();

private:

    FFDecConfig m_cfg;
    string m_dec_name;

    CircularQueue<AVPacket *> *m_pktQueueptr;
    FFReceiver m_receiver;
    DvppDec m_decoder;

    const void * m_finishedDecArg;
    DECODE_FINISHED_CALLBACK decode_finished_cbk;

};

void receiver_finish_cbk(const void* userPtr){
    if(userPtr != nullptr){
        DvppDecoder2* self = (DvppDecoder2*)userPtr;
        self->taskFinishing();
    }
}

DvppDecoder2::DvppDecoder2(){
    m_pktQueueptr = new CircularQueue<AVPacket *>();
}

DvppDecoder2::~DvppDecoder2(){
    delete m_pktQueueptr;
    m_pktQueueptr = nullptr;
}

bool DvppDecoder2::init(FFDecConfig cfg){
    
    ReceiverConfig receiver_config;
    receiver_config.uri = cfg.uri.c_str();
    receiver_config.dec_name = cfg.dec_name;
    receiver_config.force_tcp = cfg.force_tcp;
    receiver_config.pktQueueptr = m_pktQueueptr;
    receiver_config.receiver_finished_cbk = receiver_finish_cbk;
    AVCodecContext* avctx = m_receiver.init_FFmpeg(receiver_config);
    if(avctx == nullptr){
        return false;
    }
    m_receiver.setFinishCbkArg(this);

    DvppDecConfig dec_cfg;
    if(avctx->codec_id == AV_CODEC_ID_H264){
        dec_cfg.codec_id = 0;
    }else if(avctx->codec_id == AV_CODEC_ID_HEVC){
        dec_cfg.codec_id = 1;
    }else {
        return false;
    }
    dec_cfg.dec_name = cfg.dec_name;
    dec_cfg.post_decoded_cbk = cfg.post_decoded_cbk;
    dec_cfg.dev_id = cfg.gpuid;
    dec_cfg.force_tcp = cfg.force_tcp;
    dec_cfg.skip_frame = cfg.skip_frame;
    dec_cfg.profile = avctx->profile;
    dec_cfg.pktQueueptr = m_pktQueueptr;
    dec_cfg.width = avctx->width;
    dec_cfg.height = avctx->height;
    bool bRet = m_decoder.init_vdpp(dec_cfg);
    if(!bRet){
        return false;
    }

    m_cfg = cfg;

    decode_finished_cbk = cfg.decode_finished_cbk;

    return true;
}

bool DvppDecoder2::isSurport(FFDecConfig& cfg){
    return true;
}

bool DvppDecoder2::start(){
    m_receiver.start();
    m_decoder.start();
    return true;
}

void DvppDecoder2::close(){
    m_receiver.close();
}

void DvppDecoder2::setPostDecArg(const void* postDecArg){
    m_decoder.setPostDecArg(postDecArg);
}

void DvppDecoder2::setFinishedDecArg(const void* finishedDecArg){
    m_finishedDecArg = finishedDecArg;
}

void DvppDecoder2::pause(){
    m_receiver.pause();
}

void DvppDecoder2::resume(){
    m_receiver.resume();
}

void DvppDecoder2::setDecKeyframe(bool bKeyframe){
    m_receiver.setDecKeyframe(bKeyframe);
}

bool DvppDecoder2::isRunning(){
    return m_receiver.isRunning();
}

bool DvppDecoder2::isFinished(){
    return m_receiver.isFinished();
}

bool DvppDecoder2::isPausing(){
    return m_receiver.isPausing();
}

bool DvppDecoder2::getResolution(int &width, int &height){
    return m_receiver.getResolution(width, height);
}

float DvppDecoder2::fps(){
    return m_receiver.fps();
}

FFImgInfo* DvppDecoder2::snapshot(){
	// TODO
	return nullptr;
}

int DvppDecoder2::getCachedQueueLength(){
    return 0;
}

void DvppDecoder2::taskFinishing(){
    // receiver 中读取线程结束时执行
    m_decoder.close();
    decode_finished_cbk(m_finishedDecArg);

    LOG_INFO("[{}]- task finished.", m_dec_name);

}