From 9e5babf9db52e64bdae60137be7696e56241fca6 Mon Sep 17 00:00:00 2001
From: xingzilong <xingzilong@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期五, 18 八月 2017 18:12:17 +0800
Subject: [PATCH] H264 NALU解析  并在RTSPServer判断

---
 RtspFace/PreAllocBufferQueue.h   |    2 +
 RtspFace/PL_RTSPServer2.cpp      |  100 +++++++++++++++++++++++++++++++++++++++++++++-----
 RtspFace/PL_RTSPServer2.h        |    1 
 RtspFace/PreAllocBufferQueue.cpp |   10 +++++
 4 files changed, 103 insertions(+), 10 deletions(-)

diff --git a/RtspFace/PL_RTSPServer2.cpp b/RtspFace/PL_RTSPServer2.cpp
index 0506315..7974fb5 100644
--- a/RtspFace/PL_RTSPServer2.cpp
+++ b/RtspFace/PL_RTSPServer2.cpp
@@ -12,6 +12,32 @@
 #include "PreAllocBufferQueue.h"
 #include "MediaHelper.h"
 
+typedef enum {
+    NALU_TYPE_SLICE    = 1,
+    NALU_TYPE_DPA      = 2,
+    NALU_TYPE_DPB      = 3,
+    NALU_TYPE_DPC      = 4,
+    NALU_TYPE_IDR      = 5,
+    NALU_TYPE_SEI      = 6,
+    NALU_TYPE_SPS      = 7,
+    NALU_TYPE_PPS      = 8,
+    NALU_TYPE_AUD      = 9,
+    NALU_TYPE_EOSEQ    = 10,
+    NALU_TYPE_EOSTREAM = 11,
+    NALU_TYPE_FILL     = 12,
+} NaluType;
+
+typedef struct
+{
+    int startcodeprefix_len;      //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)
+    unsigned len;                 //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)
+    unsigned max_size;            //! Nal Unit Buffer size
+    int forbidden_bit;            //! should be always FALSE
+    int nal_reference_idc;        //! NALU_PRIORITY_xxxx
+    int nal_unit_type;            //! NALU_TYPE_xxxx
+    char *buf;                    //! contains the first byte followed by the EBSP
+} NALU_t;
+
 struct RTSPServer2_Internal
 {
 	RTSPServer2Config config;
@@ -28,12 +54,20 @@
 
 	bool auxLineSet;
 
+    uint8_t lastSps[50];
+    uint8_t lastPps[50];
+    uint8_t lastSpsPps[100];
+
+    size_t lastSpsSize;
+    size_t lastPpsSize;
+
 	RTSPServer2_Internal() : 
 		config(),
 		live_daemon_thid(0), live_daemon_running(false),
 		server(nullptr),
 		frameQueue(nullptr), queue_mutex(nullptr), queue_empty_mutex(nullptr), queue_full_mutex(nullptr), //#todo from config
-		auxLineSet(false)
+		auxLineSet(false),
+        lastSps(), lastPps(),lastSpsPps(),lastSpsSize(0),lastPpsSize(0)
 	{
 	}
 	
@@ -86,6 +120,8 @@
 		server = nullptr; //#todo delete
 
 		auxLineSet = false;
+        lastSpsSize = 0;
+        lastPpsSize = 0;
 	}
 };
 
@@ -122,6 +158,18 @@
 			lastBuffer = nullptr;
 		}
 	}
+
+    static int get_nalu_info(NALU_t* _p_nalu_info,const uint8_t* _pbuffer,const size_t _len)
+    {
+        if((nullptr==_pbuffer)||(_len<=4))
+        {
+            return -1;
+        }
+        _p_nalu_info->forbidden_bit = _pbuffer[4] & 0x80; //1 bit
+        _p_nalu_info->nal_reference_idc = _pbuffer[4] & 0x60; // 2 bit
+        _p_nalu_info->nal_unit_type = _pbuffer[4] & 0x1f;// 5 bit
+        return 0;
+    }
 
 	static bool deliverFrame(void* args, uint8_t*& buffer, size_t& buffSize, timeval& pts)
 	{
@@ -161,8 +209,23 @@
 		}
 
 		//#todo
+#if 0
 		//find frameQueue->Seek is pps/sps
+        PreAllocBufferQueue::Buffer* _p_Buffer = _this->in->frameQueue->Seek();
 		// if not: send bufferred pps , return;
+
+        NALU_t _obj_NALU_t;
+        get_nalu_info(&_obj_NALU_t,_p_Buffer->buffer,_p_Buffer->buffSize);
+        if(NALU_TYPE_PPS!=_obj_NALU_t.nal_unit_type)
+        {
+            memcpy(_this->in->lastSpsPps,_this->in->lastSps,_this->in->lastSpsSize);
+            memcpy(_this->in->lastSpsPps+_this->in->lastSpsSize,_this->in->lastPps,_this->in->lastPpsSize);
+            buffer = _this->in->lastSpsPps;
+            buffSize = _this->in->lastSpsSize+_this->in->lastPpsSize;
+            gettimeofday(&pts, NULL);
+            return true;
+        }
+#endif
 
 
 		_this->lastBuffer = _this->in->frameQueue->Dequeue();
@@ -286,9 +349,32 @@
 		}
 	}
 
+    MB_Frame* frame = (MB_Frame*)pm.buffer;
+    if (frame->buffer == nullptr || frame->buffSize == 0)
+        return false;
+    //LOG_WARN << "sizeR=" << frame->buffSize << LOG_ENDL;
+
+
+
 //#todo
-	// find if is pps/sps
-	// buffer the frame into RTSPServer2_Internal
+#if 0
+	// find if is pps/
+    // buffer the frame into spsRTSPServer2_Internal
+
+    if(frame->type==MB_Frame::MBFT_H264_NALU)
+    {
+        NALU_t objNALU_t;
+        DeliverFrameCallback::get_nalu_info(&objNALU_t,(const uint8_t*)(frame->buffer),frame->buffSize);
+        if(NALU_TYPE_PPS!=objNALU_t.nal_unit_type)
+        {
+            memcpy(in->lastPps,frame->buffer,frame->buffSize);
+        }
+        else if(NALU_TYPE_SPS!=objNALU_t.nal_unit_type)
+        {
+            memcpy(in->lastSps,frame->buffer,frame->buffSize);
+        }
+    }
+#endif
 
 	while (in->config.payBlockFullQueue && in->frameQueue->Full())
 	{
@@ -304,12 +390,6 @@
 		//	return false;
 		//}
 	}
-
-	MB_Frame* frame = (MB_Frame*)pm.buffer;
-	if (frame->buffer == nullptr || frame->buffSize == 0)
-		return false;
-
-	//LOG_WARN << "sizeR=" << frame->buffSize << LOG_ENDL;
 
 	ScopeLocker<pthread_mutex_t>(in->queue_mutex);
 	//if (in->frameQueue->Full())
@@ -364,5 +444,5 @@
 	pm.buffer = nullptr;
 	pm.buffSize = 0;
 	pm.former = this;
-	return true;
+	return false;
 }
diff --git a/RtspFace/PL_RTSPServer2.h b/RtspFace/PL_RTSPServer2.h
index 5e3a6f2..b336d3f 100644
--- a/RtspFace/PL_RTSPServer2.h
+++ b/RtspFace/PL_RTSPServer2.h
@@ -29,6 +29,7 @@
 	
 private:
 	void* internal;
+
 };
 
 PipeLineElem* create_PL_RTSPServer2();
diff --git a/RtspFace/PreAllocBufferQueue.cpp b/RtspFace/PreAllocBufferQueue.cpp
index f06e9d5..01e6222 100644
--- a/RtspFace/PreAllocBufferQueue.cpp
+++ b/RtspFace/PreAllocBufferQueue.cpp
@@ -71,6 +71,16 @@
 	return qbuff;
 }
 
+PreAllocBufferQueue::Buffer* PreAllocBufferQueue::Seek()
+{
+	if (usedBuffers.empty())
+		return nullptr;
+
+	Buffer* qbuff = usedBuffers.front();
+
+	return qbuff;
+}
+
 bool PreAllocBufferQueue::Empty() const
 {
 	return usedBuffers.empty();
diff --git a/RtspFace/PreAllocBufferQueue.h b/RtspFace/PreAllocBufferQueue.h
index 7c70b79..71b40ab 100644
--- a/RtspFace/PreAllocBufferQueue.h
+++ b/RtspFace/PreAllocBufferQueue.h
@@ -37,6 +37,8 @@
 	void Release(Buffer* buffer);
 
 	Buffer* Enqueue();
+
+	Buffer* Seek();
 	
 	bool Empty() const;
 	bool Full() const;

--
Gitblit v1.8.0