#include #include #include #include #include #include "librtsp.h" using namespace std; template class MyQueue { public: MyQueue():mtx(PTHREAD_MUTEX_INITIALIZER), cond(PTHREAD_COND_INITIALIZER){ t.tv_sec = 0; t.tv_nsec = 20000000; } ~MyQueue() { } public: void push(T v) { pthread_mutex_lock(&mtx); q.push_back(v); pthread_cond_signal(&cond); pthread_mutex_unlock(&mtx); } //向队列的前面插入元素 void push_front_one(T v) { pthread_mutex_lock(&mtx); q.push_front(v); pthread_cond_signal(&cond); pthread_mutex_unlock(&mtx); } T pop() { pthread_mutex_lock(&mtx); while (q.empty()) { pthread_cond_wait(&cond, &mtx); pthread_cond_timedwait(&cond, &mtx, &t); } T value = q.front(); q.pop_front(); pthread_mutex_unlock(&mtx); return value; } T popNotWait() { pthread_mutex_lock(&mtx); T value = q.front(); q.pop_front(); pthread_mutex_unlock(&mtx); return value; } int count_queue() { return q.size(); } T clearAll(){ pthread_mutex_lock(&mtx); while (!q.empty()) q.pop_front(); pthread_mutex_unlock(&mtx); } private: deque q; pthread_mutex_t mtx; pthread_cond_t cond; timespec t; }; typedef struct _buffInfo { unsigned char *buff; int buffLen; } frameBuffInfo; MyQueue m_rtpQueue; long Handle; bool pushInfo(unsigned char *data, int datalen) { 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; } 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 "); //从缓存中获取buffinfo frameBuffInfo *buffinfo = m_rtpQueue.pop(); // DBG(" m_rtpQueue.pop after "); diff = len - buffinfo->buffLen; //帧长大于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); m_rtpQueue.push_front_one(info); } 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; } while (diff > 0); return bufsize; } void streamCallBack(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata) { //GB28181API *_this = (GB28181API *)userdata; printf("userdata:%ld,datatype:%d, frametype:%d, datalen:%d\n", userdata, datatype, frametype, datalen); // //debug=============== // static int count = 0; // static FILE *fp_write = NULL; // if(count < 100) { // count++; // // if (!fp_write) { // fp_write = fopen("stream_callback.mp4", "wb+"); // } // // fwrite(data, sizeof(char), datalen, fp_write); // } // if(count >= 100){ // if (!fp_write) { // fclose(fp_write); // } // } // //debug=============== static bool startFlag = false; if(frametype == GB_VIDEO_FRAME_I){ startFlag = true; } if((data != NULL) && (startFlag == true)){ pushInfo(data, datalen); } } long addCamera(string &rtsp){ printf("RTSPSTREAM_Open\n"); long userdata = 1001; Handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, userdata); return Handle; } void deleteCamera(void){ m_rtpQueue.clearAll(); RTSPSTREAM_Close(Handle); Handle = 0; }