#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <list>
#include <math.h>
#include <mutex>
#include "rtpdepay.h"
#include "util.h"
#include "timer.h"
#define SUPPORT_SEI_PRIVATE
// #define __DEBUG
using namespace std;
#define MAXDATASIZE 1500
//SEI私有数据类型
typedef enum tagESeiPrivateDataType
{
UNIVIEW_VIDEO_TIMESTAMP = 5, //宇视视频时间戳
TZTEK_VIDEO_TIMESTAMP = 6, //天准视频时间戳
}ESeiPrivateDataType;
typedef struct
{
unsigned short wSeq;
unsigned int dwSize;
unsigned int dwTimeStamp;
unsigned char data[MAXDATASIZE];
}TNaluPacket;
typedef struct tagRTPDEPAY_CONTEXT
{
unsigned char byCorrection; //纠错
unsigned char byStreamType; //流类型
unsigned char byVideoPayloadType; //视频负载类型
unsigned char byAudioPayloadType; //音频负载类型
unsigned char byVideoStreamType; //视频类型
unsigned char byAudioStreamType; //音频类型
unsigned char byRecvMark; //接收到mark标志
unsigned char byPrint; //print标志
unsigned int dwAudioSampleRate; //音频采样频率
unsigned int dwFrameType; //帧类型
unsigned int dwRtpTimeStamp; //时间戳
unsigned int dwRecvTimeStampSec; //接收时间戳,s部分
unsigned int dwRecvTimeStampNan; //接收时间戳,nan部分
unsigned int dwExprosureUsec;
unsigned int dwOffset; //当前视频buf偏移
unsigned int dwAudioOffset; //当前音频buf偏移
unsigned int dwAgvInterval; //两个包的平均间隔
unsigned char buf[4*1024*1024]; //video buf
unsigned char audiobuf[1*1024*1024]; //audio buf
void* pUserData;
void* pTimerHandle;
pRTPDEPAY_DataCallBack pCb;
mutex* lock;
list<TNaluPacket>* lstNaluPacket;
}RTPDEPAY_CONTEXT;
typedef struct tagRTP_FIXED_HEADER
{
/* 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
/* byte 0 */
unsigned char csrc_len:4; /* expect 0 */
unsigned char extension:1; /* expect 1, see RTP_OP below */
unsigned char padding:1; /* expect 0 */
unsigned char version:2; /* expect 2 */
/* byte 1 */
unsigned char payloadtype:7; /* RTP_PAYLOAD_RTSP */
unsigned char marker:1; /* expect 1 */
/* bytes 2,3 */
unsigned short seq_no;
/* bytes 4-7 */
unsigned int timestamp;
/* bytes 8-11 */
unsigned int ssrc; /* stream number is used here. */
} RTP_FIXED_HEADER;
/*
+---------------+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
*/
typedef struct tagH264_NALU_HEADER
{
//byte 0
unsigned char TYPE:5;
unsigned char NRI:2;
unsigned char F:1;
} H264_NALU_HEADER; // 1 BYTE
/*
+---------------+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
*/
typedef struct tagH264_FU_INDICATOR
{
//byte 0
unsigned char TYPE:5;
unsigned char NRI:2;
unsigned char F:1;
} H264_FU_INDICATOR; // 1 BYTE
/*
+---------------+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
*/
typedef struct tagH264_FU_HEADER
{
//byte 0
unsigned char TYPE:5;
unsigned char R:1;
unsigned char E:1;
unsigned char S:1;
} H264_FU_HEADER; // 1 BYTES
/*
* decode the HEVC payload header according to section 4 of draft version 6:
* Forbidden zero (F): 1 bit
* NAL unit type (Type): 6 bits
* NUH layer ID (LayerId): 6 bits
* NUH temporal ID plus 1 (TID): 3 bits
*/
typedef struct tagH265_NALU_HEADER
{
unsigned short F : 1;
unsigned short TYPE : 6;
unsigned short LAYERID : 6;
unsigned short TID : 3;
} H265_NALU_HEADER; // 2 BYTE
typedef struct tagH265_FU_INDICATOR
{
unsigned short F : 1;
unsigned short TYPE : 6;
unsigned short LAYERID : 6;
unsigned short TID : 3;
} H265_FU_INDICATOR; // 2 BYTE
/*
* decode the FU header
*
* |7|6|5|4|3|2|1|0|
* +-+-+-+-+-+-+-+-+
* |S|E| FuType |
* +---------------+
*
* Start fragment (S): 1 bit
* End fragment (E): 1 bit
* FuType: 6 bits
*/
typedef struct tagH265_FU_HEADER
{
unsigned char TYPE : 6;
unsigned char E : 1;
unsigned char S : 1;
} H265_FU_HEADER; // 1 BYTES
#pragma pack(1)
//宇视时间戳结构,已经补偿过曝光时间
typedef struct tagTUniViewVideoTimestamp
{
unsigned char byType; //sei数据类型
unsigned char byLen; //后续数据长度,不包含结束符
unsigned char bySubType; //子类型
unsigned int dwSec; //秒,UTC
unsigned int dwUsec; //微妙部分
unsigned char byTail; //结束符
}TUniViewVideoTimestamp;
//天准时间戳结构
typedef struct tagTztekVideoTimestamp
{
unsigned char byType; //sei数据类型
unsigned char byRes1[3]; //预留
unsigned int dwSec; //秒,UTC
unsigned int dwNan; //纳秒部分
unsigned int dwExposure; //曝光时间,单位us
unsigned int res2[4]; //预留
}TztekVideoTimestamp;
#pragma pop()
typedef struct tagbits_buffer_s {
unsigned char* p_data;
unsigned char i_mask;
int i_size;
int i_data;
}bits_buffer_s;
#define bits_write(buffer, count, bits)\
{\
bits_buffer_s *p_buffer = (buffer);\
int i_count = (count);\
uint64_t i_bits = (bits);\
while( i_count > 0 )\
{\
i_count--;\
if( ( i_bits >> i_count )&0x01 )\
{\
p_buffer->p_data[p_buffer->i_data] |= p_buffer->i_mask;\
}\
else\
{\
p_buffer->p_data[p_buffer->i_data] &= ~p_buffer->i_mask;\
}\
p_buffer->i_mask >>= 1; /* 操作完一个字节第一位后,操作第二位 */\
if( p_buffer->i_mask == 0 ) /* 循环完一个字节的8位后,重新开始下一位 */\
{\
p_buffer->i_data++;\
p_buffer->i_mask = 0x80;\
}\
}\
}
void RTPDEPAY_TimerCallBack(void* handle, void* userdata);
int RTPDEPAY_TimeParse(RTPDEPAY_CONTEXT * &ctx, RTP_FIXED_HEADER * pRtpHdr, RTPDEPAY_PROCESS_PARAM * ¶m);
static void rtpdepay_ebsp_to_rbsp(unsigned char *src,int srclen,unsigned char *dst,int &datalen)
{
int cz = 0;
datalen = 0;
for(int i = 0; i < srclen;i++)
{
if(cz == 2 && src[i] == 0x03 )
{
//skip
cz = 0;
continue;
}
if(src[i] == 0)
{
cz++;
}
else
{
cz = 0;
}
//save
*dst++= src[i];
datalen++;
}
return;
}
//包括固定头和可变头,通常7字节
static int aac_fill_adts_head(RTPDEPAY_CONTEXT *ctx,unsigned char *buf, int datalen)
{
bits_buffer_s bitbuf;
bitbuf.i_size = 7;
bitbuf.i_data = 0;
bitbuf.i_mask = 0x80;
bitbuf.p_data = buf;
memset(buf,0,bitbuf.i_size);
//帧同步标识一个帧的开始,固定为0xFFF
bits_write(&bitbuf,12,0xfff);
//MPEG 标示符。0表示MPEG-4,1表示MPEG-2
bits_write(&bitbuf,1,0);
//固定为’00’
bits_write(&bitbuf,
RTSP!!!!!!!!!
需积分: 0 121 浏览量
2023-09-04
18:32:46
上传
评论
收藏 4.81MB RAR 举报
m0_57542704
- 粉丝: 1
- 资源: 1