| | |
| | | #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;
|
| | |
| | |
|
| | | 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)
|
| | | {
|
| | | }
|
| | |
|
| | |
| | | server = nullptr; //#todo delete
|
| | |
|
| | | auxLineSet = false;
|
| | | lastSpsSize = 0;
|
| | | lastPpsSize = 0;
|
| | | }
|
| | | };
|
| | |
|
| | |
| | | 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)
|
| | | {
|
| | |
| | | }
|
| | |
|
| | | //#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();
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | 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())
|
| | | {
|
| | |
| | | // 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())
|
| | |
| | | pm.buffer = nullptr;
|
| | | pm.buffSize = 0;
|
| | | pm.former = this;
|
| | | return true;
|
| | | return false;
|
| | | }
|