From 18a05d269516a5e33d8460291c2f93e73d95adce Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期二, 26 十二月 2023 10:45:31 +0800 Subject: [PATCH] GetYUV format is NV12 --- csrc/thirdparty/gb28181/include/PsToEs.hpp | 216 +++++++++++++++++++++++++++++++---------------------- 1 files changed, 126 insertions(+), 90 deletions(-) diff --git a/csrc/thirdparty/gb28181/include/PsToEs.hpp b/csrc/thirdparty/gb28181/include/PsToEs.hpp index 4128360..54dc25f 100644 --- a/csrc/thirdparty/gb28181/include/PsToEs.hpp +++ b/csrc/thirdparty/gb28181/include/PsToEs.hpp @@ -7,20 +7,23 @@ #include <unistd.h> #include "librtsp.h" #include <sys/time.h> - +#include <errno.h> using namespace std; template<typename T> class MyQueue { public: - MyQueue():mtx(PTHREAD_MUTEX_INITIALIZER), cond(PTHREAD_COND_INITIALIZER){ - t.tv_sec = 0; - t.tv_nsec = 0; + MyQueue():mtx(PTHREAD_MUTEX_INITIALIZER){ + pthread_condattr_t attr; + pthread_condattr_init(&attr); + pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + pthread_cond_init(&cond, &attr); + pthread_condattr_destroy(&attr); } ~MyQueue() { - + pthread_cond_destroy(&cond); } public: @@ -40,14 +43,28 @@ } T pop() { + 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); - if (q.empty()) { - gettimeofday(&now, NULL); - t.tv_sec = now.tv_sec + 3; - t.tv_nsec = now.tv_usec * 1000; -// pthread_cond_wait(&cond, &mtx); - pthread_cond_timedwait(&cond, &mtx, &t); + while(q.empty()){ + if(pthread_cond_timedwait(&cond, &mtx, &to) == ETIMEDOUT){ + printf("======>>timeout quit\n"); + break; + } } + // printf("======>>queue size %lu\n", q.size()); + if (q.empty()) { pthread_mutex_unlock(&mtx); return 0; @@ -91,8 +108,6 @@ deque<T> q; pthread_mutex_t mtx; pthread_cond_t cond; - timespec t; - struct timeval now; }; typedef struct _buffInfo { @@ -100,8 +115,90 @@ 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: + + static int capturePic(void *opaque, char *buf, int *bufsize, const int tt) { + + GB28181API *_this = (GB28181API *) opaque; + int len = 0; + *bufsize = 0; + + int ttt = 0; + do { + if (ttt > tt) return 0; + ttt++; + + //浠庣紦瀛樹腑鑾峰彇buffinfo + if (_this->m_rtpQueue.count_queue() == 0) { +// printf(" count_queue == 0 \n"); + usleep(200000); + continue; + } + + frameBuffInfo *buffinfo = _this->m_rtpQueue.pop(); + if (buffinfo == nullptr) { + printf(" buffinfo == nullptr \n"); + return 0; + } +//////////////////////////////////////////////////////// + FILE* fpJpg = NULL; + char fileJpgName[32] = "./tmpCaptureJpg.jpg"; + char fileIFrameName[32] = "./tmpCaptureX264IFrame"; + char cmd[512] = {0}; + + for(int i = 0; i < 10 * 25; i++){ + if (!buffinfo){ + buffinfo = _this->m_rtpQueue.pop(); + } + if (!buffinfo) continue; + + auto fpIframe = fopen(fileIFrameName, "wb+"); + fwrite(buffinfo->buff, buffinfo->buffLen, 1, fpIframe); + fflush(fpIframe); + fclose(fpIframe); + + memset(cmd, 0, 512); + sprintf(cmd, "ffmpeg -i %s -y -f image2 -ss 00:00:00 -vframes 1 %s >/dev/null", fileIFrameName, + fileJpgName); + int rr = system(cmd); + + delete[] buffinfo->buff; + delete buffinfo; + buffinfo = nullptr; + + fpJpg = fopen(fileJpgName, "rb"); + if (fpJpg) { + break; + } + } +/////////////////////////////////////////////////////////// + + fseek(fpJpg, 0, SEEK_END); + len = ftell(fpJpg); + fseek(fpJpg, 0, SEEK_SET); + *bufsize = fread(buf, sizeof(char), len, fpJpg); + fclose(fpJpg); + + memset(cmd, 0, 128); + sprintf(cmd, "rm %s %s >/dev/null", fileIFrameName, fileJpgName); + system(cmd); + } while (*bufsize == 0); + + return *bufsize; + } + GB28181API(/*string rtspUrl*/){ // handle = addCamera(rtspUrl); } @@ -118,9 +215,10 @@ deleteCamera(); } + static const int keep_queue_count = 126; bool pushInfo(unsigned char *data, int datalen) { - while(m_rtpQueue.count_queue() > 120){ + while(m_rtpQueue.count_queue() > keep_queue_count){ auto p = m_rtpQueue.popNotWait(); if (p){ delete[] p->buff; @@ -151,7 +249,7 @@ frameBuffInfo *buffinfo = _this->m_rtpQueue.pop(); // printf(" m_rtpQueue.pop after \n"); if(buffinfo != nullptr){ - diff = len - buffinfo->buffLen; + diff = len - buffinfo->buffLen; }else{ return 0; } @@ -166,7 +264,7 @@ info->buff = new unsigned char[buffinfo->buffLen - len]{}; memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len); - while(_this->m_rtpQueue.count_queue() > 120){ + while(_this->m_rtpQueue.count_queue() > keep_queue_count){ auto p = _this->m_rtpQueue.popNotWait(); if (p){ delete[] p->buff; @@ -195,76 +293,6 @@ return bufsize; } - static int capturePic(void *opaque, char *buf, int *bufsize, const int tt) { - - GB28181API *_this = (GB28181API *) opaque; - int len = 0; - *bufsize = 0; - - int ttt = 0; - do { - if (ttt > tt) return 0; - ttt++; - - //浠庣紦瀛樹腑鑾峰彇buffinfo - if (_this->m_rtpQueue.count_queue() == 0) { -// printf(" count_queue == 0 \n"); - usleep(200000); - continue; - } - - frameBuffInfo *buffinfo = _this->m_rtpQueue.pop(); - if (buffinfo == nullptr) { - printf(" buffinfo == nullptr \n"); - return 0; - } -//////////////////////////////////////////////////////// - FILE* fpJpg = NULL; - char fileJpgName[32] = "./tmpCaptureJpg.jpg"; - char fileIFrameName[32] = "./tmpCaptureX264IFrame"; - char cmd[512] = {0}; - - for(int i = 0; i < 10 * 25; i++){ - if (!buffinfo){ - buffinfo = _this->m_rtpQueue.pop(); - } - if (!buffinfo) continue; - - auto fpIframe = fopen(fileIFrameName, "wb+"); - fwrite(buffinfo->buff, buffinfo->buffLen, 1, fpIframe); - fflush(fpIframe); - fclose(fpIframe); - - memset(cmd, 0, 512); - sprintf(cmd, "ffmpeg -i %s -y -f image2 -ss 00:00:00 -vframes 1 %s >/dev/null", fileIFrameName, - fileJpgName); - int rr = system(cmd); - - delete[] buffinfo->buff; - delete buffinfo; - buffinfo = nullptr; - - fpJpg = fopen(fileJpgName, "rb"); - if (fpJpg) { - break; - } - } -/////////////////////////////////////////////////////////// - - fseek(fpJpg, 0, SEEK_END); - len = ftell(fpJpg); - fseek(fpJpg, 0, SEEK_SET); - *bufsize = fread(buf, sizeof(char), len, fpJpg); - fclose(fpJpg); - - memset(cmd, 0, 128); - sprintf(cmd, "rm %s %s >/dev/null", fileIFrameName, fileJpgName); - system(cmd); - } while (*bufsize == 0); - - return *bufsize; - } - static void streamCallBack(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata) { GB28181API *_this = (GB28181API *)userdata; @@ -273,30 +301,38 @@ 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); + _this->pushInfo(data, datalen); } } 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; } void deleteCamera(){ printf("RTSPSTREAM_Close\n"); - if(handle != -1){ + if(handle > -1){ RTSPSTREAM_Close(handle); } handle = -1; - } + } + const int getDataType(){return datatype_;} private: + int datatype_ = -1; MyQueue<frameBuffInfo *> m_rtpQueue; long handle = -1; }; -- Gitblit v1.8.0