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