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 | 236 ++++++++++++++++++++++++++++++++++++----------------------
1 files changed, 145 insertions(+), 91 deletions(-)
diff --git a/csrc/thirdparty/gb28181/include/PsToEs.hpp b/csrc/thirdparty/gb28181/include/PsToEs.hpp
index 366db70..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;
@@ -77,7 +94,8 @@
pthread_mutex_unlock(&mtx);
}
- void clearAll(std::function<void(T)> fn){
+ template<class F>
+ void clearAll(F&& fn){
pthread_mutex_lock(&mtx);
while (!q.empty()){
T value = q.front();
@@ -90,8 +108,6 @@
deque<T> q;
pthread_mutex_t mtx;
pthread_cond_t cond;
- timespec t;
- struct timeval now;
};
typedef struct _buffInfo {
@@ -99,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);
}
@@ -109,13 +207,24 @@
printf("GB28181API end!\n");
// m_rtpQueue.clearAll();
m_rtpQueue.clearAll([](frameBuffInfo *info){
- delete[] info->buff;
- delete 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];
@@ -140,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;
}
@@ -155,6 +264,13 @@
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");
@@ -177,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(10000);
- 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;
@@ -255,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