video analysis2.0拆分,ffmpeg封装go接口库
zhangmeng
2023-12-26 18a05d269516a5e33d8460291c2f93e73d95adce
csrc/thirdparty/gb28181/include/PsToEs.hpp
@@ -43,16 +43,22 @@
    }
    T pop() {
        struct timespec now, end;
        clock_gettime(CLOCK_MONOTONIC, &now);
        static uint64_t waitS = 12; // wait
        end.tv_sec = now.tv_sec + waitS;
        end.tv_nsec = now.tv_nsec;
        struct timespec to;
        clock_gettime(CLOCK_MONOTONIC, &to);
        static uint64_t waitMS = 620; // wait
        uint64_t sec = waitMS / 1000;
        uint64_t nsec = (waitMS % 1000) * 1e6;
        to.tv_sec = to.tv_sec + sec;
        nsec += to.tv_nsec;
        sec = nsec / 1000000000;
        nsec = nsec % 1000000000;
        to.tv_sec += sec;
        to.tv_nsec = nsec;
        // printf("======>>wait stream data\n");
        pthread_mutex_lock(&mtx);
        while(q.empty()){
            if(pthread_cond_timedwait(&cond, &mtx, &end) == ETIMEDOUT){
            if(pthread_cond_timedwait(&cond, &mtx, &to) == ETIMEDOUT){
                printf("======>>timeout quit\n");
                break;
            }
@@ -109,100 +115,19 @@
   int buffLen;
} frameBuffInfo;
typedef enum
{
    E_VIDEO_STREAM_NONE     = -1,
    E_VIDEO_STREAM_H264     = 0,
    E_VIDEO_STREAM_MPEG2    = 1,    // MPEG4
    E_VIDEO_STREAM_MPEG4    = 2,    // MPEG4
    E_VIDEO_STREAM_SVAC     = 3,    // SVAC
    E_VIDEO_STREAM_3GP      = 4,    // 3GP
    E_VIDEO_STREAM_H265     = 5,    //H265
}VideoStreamType_E;
class GB28181API{
public:
   GB28181API(/*string rtspUrl*/){
//      handle = addCamera(rtspUrl);
   }
   ~GB28181API(){
      printf("GB28181API end!\n");
      // m_rtpQueue.clearAll();
      m_rtpQueue.clearAll([](frameBuffInfo *info){
         if (info){
            delete[] info->buff;
            delete info;
         }
      });
      deleteCamera();
   }
   bool pushInfo(unsigned char *data, int datalen) {
      while(m_rtpQueue.count_queue() > 120){
            auto p = m_rtpQueue.popNotWait();
            if (p){
                delete[] p->buff;
                delete p;
            }
        }
      frameBuffInfo *info = new frameBuffInfo();
      info->buff = new unsigned char[datalen];
      info->buffLen = datalen;
      memcpy(info->buff, data, datalen);
      //printf(" m_rtpQueue.push befores ");
      m_rtpQueue.push(info);
      //printf(" m_rtpQueue.push after ");
      return true;
   }
   static int readData(void *opaque, unsigned char *buf, int bufsize) {
      GB28181API *_this = (GB28181API *)opaque;
       int len = bufsize;
       int diff = 0;
       do {
//         printf(" m_rtpQueue.pop before \n");
         //从缓存中获取buffinfo
         frameBuffInfo *buffinfo = _this->m_rtpQueue.pop();
//         printf(" m_rtpQueue.pop after \n");
            if(buffinfo != nullptr){
         diff = len - buffinfo->buffLen;
            }else{
                return 0;
            }
         //帧长大于bufsize
         if (diff < 0) {
//            printf("/帧长大于bufsize:%d\n", diff);
            memcpy(buf + bufsize - len, buffinfo->buff, len);
            frameBuffInfo *info = new frameBuffInfo();
            info->buffLen = buffinfo->buffLen - len;
            info->buff = new unsigned char[buffinfo->buffLen - len]{};
            memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len);
            while(_this->m_rtpQueue.count_queue() > 120){
                    auto p = _this->m_rtpQueue.popNotWait();
                    if (p){
                        delete[] p->buff;
                        delete p;
                    }
                }
//            printf("/帧长大于info->buffLen:%d\n", info->buffLen);
            _this->m_rtpQueue.push_front_one(info);
//            printf("/帧长大于info->buffLen\n");
         } else if (diff == 0) {
//            printf("/帧长等于bufsize:%d\n", diff);
            memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen);
         } else if (diff > 0) {
//            printf("/帧长小于bufsize:%d\n", diff);
            memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen);
            len = len - buffinfo->buffLen;   //还需要填充的大小
            memset(buf + bufsize - len, 0, len);
            //不等待填充,直接进行解码
            diff = 0;
         }
         delete[] buffinfo->buff;
         delete buffinfo;
//         printf("/帧长大于info->buffLen1\n");
       } while (diff > 0);
       return bufsize;
   }
    static int capturePic(void *opaque, char *buf, int *bufsize, const int tt) {
@@ -274,6 +199,100 @@
        return *bufsize;
    }
   GB28181API(/*string rtspUrl*/){
//      handle = addCamera(rtspUrl);
   }
   ~GB28181API(){
      printf("GB28181API end!\n");
      // m_rtpQueue.clearAll();
      m_rtpQueue.clearAll([](frameBuffInfo *info){
         if (info){
            delete[] info->buff;
            delete info;
         }
      });
      deleteCamera();
   }
    static const int keep_queue_count = 126;
   bool pushInfo(unsigned char *data, int datalen) {
      while(m_rtpQueue.count_queue() > keep_queue_count){
            auto p = m_rtpQueue.popNotWait();
            if (p){
                delete[] p->buff;
                delete p;
            }
        }
      frameBuffInfo *info = new frameBuffInfo();
      info->buff = new unsigned char[datalen];
      info->buffLen = datalen;
      memcpy(info->buff, data, datalen);
      //printf(" m_rtpQueue.push befores ");
      m_rtpQueue.push(info);
      //printf(" m_rtpQueue.push after ");
      return true;
   }
   static int readData(void *opaque, unsigned char *buf, int bufsize) {
      GB28181API *_this = (GB28181API *)opaque;
       int len = bufsize;
       int diff = 0;
       do {
//         printf(" m_rtpQueue.pop before \n");
         //从缓存中获取buffinfo
         frameBuffInfo *buffinfo = _this->m_rtpQueue.pop();
//         printf(" m_rtpQueue.pop after \n");
            if(buffinfo != nullptr){
             diff = len - buffinfo->buffLen;
            }else{
                return 0;
            }
         //帧长大于bufsize
         if (diff < 0) {
//            printf("/帧长大于bufsize:%d\n", diff);
            memcpy(buf + bufsize - len, buffinfo->buff, len);
            frameBuffInfo *info = new frameBuffInfo();
            info->buffLen = buffinfo->buffLen - len;
            info->buff = new unsigned char[buffinfo->buffLen - len]{};
            memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len);
            while(_this->m_rtpQueue.count_queue() > keep_queue_count){
                    auto p = _this->m_rtpQueue.popNotWait();
                    if (p){
                        delete[] p->buff;
                        delete p;
                    }
                }
//            printf("/帧长大于info->buffLen:%d\n", info->buffLen);
            _this->m_rtpQueue.push_front_one(info);
//            printf("/帧长大于info->buffLen\n");
         } else if (diff == 0) {
//            printf("/帧长等于bufsize:%d\n", diff);
            memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen);
         } else if (diff > 0) {
//            printf("/帧长小于bufsize:%d\n", diff);
            memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen);
            len = len - buffinfo->buffLen;   //还需要填充的大小
            memset(buf + bufsize - len, 0, len);
            //不等待填充,直接进行解码
            diff = 0;
         }
         delete[] buffinfo->buff;
         delete buffinfo;
//         printf("/帧长大于info->buffLen1\n");
       } while (diff > 0);
       return bufsize;
   }
   static void streamCallBack(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata)
   {
      GB28181API *_this = (GB28181API *)userdata;
@@ -282,6 +301,11 @@
      if(frametype == GB_VIDEO_FRAME_I){
         startFlag = true;
      }
        // printf("streamCallBack recv data len %d frametype %d\n", datalen, startFlag);
        if (_this->datatype_ < 0)
            _this->datatype_ = datatype;
      if((data != NULL) && (startFlag == true)){
            _this->pushInfo(data, datalen);
      }
@@ -289,10 +313,11 @@
   long addCamera(string &rtsp){
        int count = 0;
        while (handle == -1 && count <= 3) {
        while (handle < 0 && count <= 3) {
            count ++;
            handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, (long) this);
            printf("RTSPSTREAM_Open, handle:%ld \n", handle);
            usleep(20000);
        }
      return handle;
   }
@@ -305,7 +330,9 @@
      handle = -1;
   }   
    const int getDataType(){return datatype_;}
private:
    int datatype_ = -1;
   MyQueue<frameBuffInfo *> m_rtpQueue;
   long handle = -1;
};