派生自 development/c++

pans
2019-03-30 25928e3093a7c0257128192d7785ec3f74e89e81
添加注释
6个文件已修改
68 ■■■■ 已修改文件
QiaoJiaSystem/GB28181DecoderModel/FFmpegDecoderJPG.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
QiaoJiaSystem/GB28181DecoderModel/FFmpegDecoderJPG.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
QiaoJiaSystem/GB28181DecoderModel/GB28181Server.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
QiaoJiaSystem/GB28181DecoderModel/SpinLock.hpp 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
QiaoJiaSystem/GB28181DecoderModel/VideoCaptureElementWithRtp.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
QiaoJiaSystem/GB28181DecoderModel/VideoCaptureElementWithRtp.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
QiaoJiaSystem/GB28181DecoderModel/FFmpegDecoderJPG.cpp
@@ -45,7 +45,9 @@
}
BASICGB28181::FFmpegDecoderJPG::~FFmpegDecoderJPG() {
    //清空队列
    while (m_rtpQueue.count_queue()) {
        //#todo delete frameBuffInfo*
        m_rtpQueue.popNotWait();
    }
@@ -75,10 +77,9 @@
    }
#ifdef TestCode
        DBG(" m_rtpQueue.push before ");
        DBG(" m_rtpQueue.push befores ");
#endif
        m_rtpQueue.
        push(info);
        m_rtpQueue.push(info);
#ifdef TestCode
        DBG(" m_rtpQueue.push after ");
#endif
@@ -96,10 +97,11 @@
    do {
//        DBG(" m_rtpQueue.pop before ");
        //从缓存中获取buffinfo
        frameBuffInfo *buffinfo = fFmpegDecoderJPG->m_rtpQueue.pop();
//        DBG(" m_rtpQueue.pop after ");
        diff = len - buffinfo->buffLen;
//        printf("bufsize is :%ld,len is :%ld, datalen:%d \n", bufsize, len, buffinfo->buffLen);
        //帧长大于bufsize
        if (diff < 0) {
//            DBG("/帧长大于bufsize" << diff);
@@ -130,7 +132,7 @@
        delete[] buffinfo->buff;
        delete buffinfo;
    } while (diff > 0);
    //#todo 触发信号
//    DBG("emitSigal(\"read_dataOk\") begin");
//    gSignalLock.emitSigal("read_dataOk");
    fFmpegDecoderJPG->m_readData = true;
@@ -151,12 +153,14 @@
//    avformat_network_init();
        p_this->ic = avformat_alloc_context();
        //创建ffmpeg使用的内存空间
        p_this->iobuffer = (unsigned char *) av_malloc(p_this->m_buf_size);
        if (!p_this->iobuffer) {
            ERR("av_malloc: err======" << p_this->m_camIdx);
            p_this->m_running = false;
            continue;
        }
//     使用回调函数和内存块创建 AVIOContext
        p_this->avio = avio_alloc_context(p_this->iobuffer, p_this->m_buf_size, 0, p_this, p_this->read_data, NULL,
                                          NULL);
        if (!p_this->avio) {
@@ -267,7 +271,7 @@
//        BASICGB28181::avframe_to_cvmat(frame).copyTo(p_this->m_image);
            p_this->m_image = std::move(BASICGB28181::avframe_to_cvmat(p_this->frame));
//            将i帧保存为快照
            if (p_this->m_SnapshotNotSaveRet && (p_this->pkt.flags & AV_PKT_FLAG_KEY)) {
                try {
                    std::string strNewName = "./";
@@ -304,7 +308,7 @@
#ifdef TestCode
                DBG("emitSigal(\"DecoderImageOK\") begin");
#endif
            //触发信号
            //触发上层信号
            gSignalLock.emitSigal(p_this->m_camIdx + "DecoderImageOK");
//#ifdef TestCode
//        DBG("emitSigal(\"DecoderImageOK\") after");
@@ -349,6 +353,7 @@
        }
        m_camIdx = camIdx;
        DBG("BareFlowDecoderThd camIdx : " << camIdx);
//        启动解码线程
        std::thread t_BareFlowDecoder(BareFlowDecoderThd, this);
        t_BareFlowDecoder.detach();
    );
QiaoJiaSystem/GB28181DecoderModel/FFmpegDecoderJPG.h
@@ -48,6 +48,11 @@
    static void initFFmpeg();
    /***
     * AVframe转cvmat
     * @param frame
     * @return
     */
    static cv::Mat avframe_to_cvmat(AVFrame *frame);
    typedef struct _buffInfo {
@@ -56,6 +61,7 @@
        std::string camIdx;
    } frameBuffInfo;
    //************录像模块使用的结构体********************//
    struct FrameIdPackage_s_t {
        int64_t m_frameId;
        AVPacket m_packet;
@@ -82,6 +88,7 @@
        RECORDING_VIDEO,
        STOP_RECORD,
    };
    //********************************//
//    std::map<std::string, MyQueue<frameBuffInfo *> > MapMyQueue;
    static std::mutex g_mutex;
QiaoJiaSystem/GB28181DecoderModel/GB28181Server.cpp
@@ -52,6 +52,7 @@
    bool iRet = C_InitSDK(&GBServerParam, &MysqlConnParam, NULL, enventcallback);
    DBG("iRet is " << iRet);
//    等待设备注册
    sleep(90);
    return iRet;
QiaoJiaSystem/GB28181DecoderModel/SpinLock.hpp
@@ -6,7 +6,9 @@
#define GB28181SDK_SPINLOCK_H
#include <atomic>
/***
 * 自旋锁,可能会有没锁上的bug
 */
class SpinLock {
public:
    SpinLock() : m_lock(ATOMIC_FLAG_INIT) {}
QiaoJiaSystem/GB28181DecoderModel/VideoCaptureElementWithRtp.cpp
@@ -35,17 +35,21 @@
bool BASICGB28181::VideoCaptureElementWithRtp::startRtpStream(int streamTransType) {
    //等待下层ffmpeg将rtp包解码成为图片后触发信号,然后触发当前类的submit
    std::thread waitSignalAndEmit([&](BASICGB28181::VideoCaptureElementWithRtp *p_this) {
        p_this->m_waitSignal = true;
        //循环,由成员变量来维护这个线程的运行状态
        while (p_this->m_waitSignal) {
//#TODO wait test
#ifdef TestCode
            DBG("waitSignal(\"DecoderImageOK\") begin");
#endif
            //等待信号触发
            gSignalLock.waitSignal(p_this->m_chanPubID + "DecoderImageOK");
#ifdef TestCode
            DBG("waitSignal(\"DecoderImageOK\") after");
#endif
            /****录像模块代码*****/
            p_this->m_picCount++;
            //几张选一张放入Redis
            if (p_this->m_picCount % m_nPicsPickOne != 0) {
@@ -54,6 +58,7 @@
                p_this->m_picCount.store(0);
            }
//            从ffmpeg解码类中获取图片
            p_this->m_fFmpegDecoderJPG.getImage().copyTo(p_this->m_image);
            {
                cv::Mat copyMat;
@@ -61,6 +66,8 @@
                p_this->m_image.copyTo(copyMat);
                m_pManager->SaveImageToRedis(p_this->m_chanPubID, imageName, copyMat);
            }
            /*********/
            p_this->submit();
        }
        INFO("waitSignalAndEmit is exit...");
@@ -69,6 +76,7 @@
    TryCath(
    //--------------国标设备或则国标下级平台必须支持GB28181-2016----------------------------------------------
    //解码线程,发起点播请求,启动ffmpeg解码模块
        std::thread videoCaptureElementThd([&](VideoCaptureElementWithRtp *p_this, int streamType) {
            DBG("videoCaptureElementThd start...");
            StreamTransType_E etype;
@@ -93,28 +101,36 @@
            }
            DBG("C_RealVideoStart start... m_chanPubID is " << p_this->m_chanPubID << " etype is " << etype
                                                            << " m_userdata is " << m_userdata);
            //开始点播视频
            long lrealhandle = C_RealVideoStart(const_cast<char *>(p_this->m_chanPubID.c_str()), etype,
                                                p_this->streamcallback, m_userdata);
            if (lrealhandle != -1) {
                //点播成功
                DBG(p_this->m_chanPubID << "  C_RealVideoStart ok ... type is " << etype);
                p_this->m_running = true;
                //启动ffmpeg解码模块
                p_this->m_fFmpegDecoderJPG.startThd(p_this->m_chanPubID, p_this->m_fps, p_this->m_gpuIdx);
                //阻塞线程,等待外部触发关闭点播
                while (p_this->m_running) {
//                    if(p_this->m_fFmpegDecoderJPG.getRunning()) {
                        usleep(300000);
                    usleep(300000);
//                    }else{
//                        p_this->m_running = false;
//                        break;
//                    }
                }
                DBG("videoCaptureElementThd stop ...");
                //停止点播
                C_RealVideoStop(lrealhandle);
                //将waitSignalAndEmit 线程退出
                p_this->m_waitSignal = false;
                DBG("videoCaptureElementThd stop ok...");
            } else {
                //点播失败
                p_this->m_waitSignal = false;
                p_this->m_running = false;
                //关闭ffmpeg解码模块
                p_this->m_fFmpegDecoderJPG.stopThd();
                ERR(p_this->m_chanPubID << " C_RealVideoStart is error lrealhandle is  " << lrealhandle);
            }
@@ -157,13 +173,15 @@
//        fwrite(data, sizeof(char), datalen, fp11);
    }
#endif
    //将底层组好的rtp包,存入ffmpeg中的缓存队列
    CHKDBG(p_this->m_fFmpegDecoderJPG.pushInfo(data, datalen, p_this->m_chanPubID), true,
           "pushInfo is error !! handle is " << handle << " datatype is " << datatype << " frametype is " << frametype);
}
void BASICGB28181::VideoCaptureElementWithRtp::threadFunc() {
    if ((!m_running) || (!m_waitSignal)) {
//        根据reopenTime判断是否需要重启
        if (reopenTime < 0) {
            stop();
            INFO("grabFrame faild, element stopping");
QiaoJiaSystem/GB28181DecoderModel/VideoCaptureElementWithRtp.h
@@ -17,6 +17,14 @@
    class VideoCaptureElementWithRtp : public basic::PipeElement {
    public:
        /***
         * VideoCaptureElementWithRtp 视频解码
         * @param chanPubID 通道地(摄像机id)
         * @param fps
         * @param streamTransType 请求的视频流类型
         * @param gpuIdx gpuindex
         * @param manager 上层类的指针
         */
        explicit VideoCaptureElementWithRtp(std::string &chanPubID, int fps, int streamTransType, int gpuIdx = -1,
                                            RtspAnalysManager *manager = nullptr);
@@ -28,6 +36,11 @@
         */
        bool getRunning();
        /***
         * 获取图片
         * @return
         */
        cv::Mat getImage();
        //保存视频接口,从RtspAnalysManager发起调用
@@ -74,7 +87,7 @@
        /***
         * rtp组包回调函数
         * GB28181 SDK rtp组包回调函数
         * @param handle
         * @param datatype
         * @param frametype