理论部分:https://blog.csdn.net/shixin_0125/article/details/78798238
以下是rtsp传输视频流时的核心代码
struct _RTP_FIXED_HEADER
{
unsigned char csrc_len:4;
unsigned char extension:1;
unsigned char padding:1;
unsigned char version:2;
unsigned char payload:7;
unsigned char marker:1;
unsigned short seq_no;
unsigned long timestamp;
unsigned long ssrc;
};
struct _NALU_HEADER
{
unsigned char TYPE:5;
unsigned char NRI:2;
unsigned char F:1;
};
struct _FU_INDICATOR
{
unsigned char TYPE:5;
unsigned char NRI:2;
unsigned char F:1;
};
struct _FU_HEADER
{
unsigned char TYPE:5;
unsigned char R:1;
unsigned char E:1;
unsigned char S:1;
};
struct _AU_HEADER
{
unsigned short au_len;
unsigned short frm_len:13;
unsigned char au_index:3;
};
typedef struct _RTP_FIXED_HEADER RTP_FIXED_HEADER;
typedef struct _NALU_HEADER NALU_HEADER;
typedef struct _FU_INDICATOR FU_INDICATOR;
typedef struct _FU_HEADER FU_HEADER;
typedef struct _AU_HEADER AU_HEADER;
HI_S32 VENC_Sent(char *buff,int buflen, unsigned int pts)
{
int is=0;
char *buffer = NULL;
RTP_FIXED_HEADER *rtp_hdr = NULL;
NALU_HEADER *nalu_hdr = NULL;
FU_INDICATOR *fu_ind = NULL;
FU_HEADER *fu_hdr = NULL;
char* nalu_payload = NULL;
int nAvFrmLen = 0;
int nIsIFrm = 0;
int nNaluType = 0;
char sendbuf[nalu_sent_len + 20 +32];
struct sockaddr_in server;
int bytes = 0;
nAvFrmLen = buflen - 5;
nNaluType = buff[4] & 0x1f;
nIsIFrm = (buff[4] & 0x60) >> 5;
buffer = buff + 5;
rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0];
rtp_hdr->payload = RTP_H264;
rtp_hdr->version = 2;
rtp_hdr->marker = 0;
if(nAvFrmLen <= nalu_sent_len)
{
rtp_hdr->marker=1;
nalu_hdr = (NALU_HEADER*)&sendbuf[12];
nalu_hdr->F = 0;
nalu_hdr->NRI = nIsIFrm;
nalu_hdr->TYPE = nNaluType;
rtp_hdr->timestamp = htonl( pts);
nalu_payload=&sendbuf[13];
memcpy(nalu_payload,buffer,nAvFrmLen);
bytes=nAvFrmLen+ 13 ;
for(is=0;is<MAX_RTSP_CLIENT;is++)
{
if(g_rtspClients[is].status == RTSP_SENDING)
{
pthread_mutex_lock(&g_sendmutex);
rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++);
rtp_hdr->ssrc = htonl(10 + is);
server.sin_family = AF_INET;
server.sin_port = htons(g_rtspClients[is].rtpport[0]);
server.sin_addr.s_addr = inet_addr(g_rtspClients[is].IP);
sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
pthread_mutex_unlock(&g_sendmutex);
}
}
}
else if(nAvFrmLen>nalu_sent_len)
{
int k=0,l=0;
k=nAvFrmLen/nalu_sent_len;
l=nAvFrmLen%nalu_sent_len;
int t=0;
rtp_hdr->timestamp = htonl( pts);
while(t<=k)
{
if(t==0)
{
rtp_hdr->marker=0;
fu_ind = (FU_INDICATOR*)&sendbuf[12];
fu_ind->F = 0;
fu_ind->NRI = nIsIFrm;
fu_ind->TYPE= 28;
fu_hdr = (FU_HEADER*)&sendbuf[13];
fu_hdr->E = 0;
fu_hdr->R = 0;
fu_hdr->S = 1;
fu_hdr->TYPE= nNaluType;
nalu_payload= &sendbuf[14];
memcpy(nalu_payload,buffer,nalu_sent_len);
bytes=nalu_sent_len+14;
for(is=0;is<MAX_RTSP_CLIENT;is++)
{
if(g_rtspClients[is].status == RTSP_SENDING)
{
pthread_mutex_lock(&g_sendmutex);
rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++);
rtp_hdr->ssrc = htonl(10 + is);
server.sin_family = AF_INET;
server.sin_port = htons(g_rtspClients[is].rtpport[0]);
server.sin_addr.s_addr = inet_addr(g_rtspClients[is].IP);
sendto( udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
pthread_mutex_unlock(&g_sendmutex);
}
}
t++;
}
else if(k==t)
{
rtp_hdr->marker = 1;
fu_ind = (FU_INDICATOR*)&sendbuf[12];
fu_ind->F = 0 ;
fu_ind->NRI = nIsIFrm ;
fu_ind->TYPE = 28;
fu_hdr = (FU_HEADER*)&sendbuf[13];
fu_hdr->R = 0;
fu_hdr->S = 0;
fu_hdr->TYPE = nNaluType;
fu_hdr->E = 1;
nalu_payload = &sendbuf[14];
memcpy(nalu_payload,buffer+t*nalu_sent_len,l);
bytes=l+14;
for(is=0;is<MAX_RTSP_CLIENT;is++)
{
if(g_rtspClients[is].status == RTSP_SENDING)
{
pthread_mutex_lock(&g_sendmutex);
rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++);
rtp_hdr->ssrc = htonl(10 + is);
server.sin_family = AF_INET;
server.sin_port = htons(g_rtspClients[is].rtpport[0]);
server.sin_addr.s_addr = inet_addr(g_rtspClients[is].IP);
sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
pthread_mutex_unlock(&g_sendmutex);
}
}
t++;
}
else if(t<k && t!=0)
{
rtp_hdr->marker=0;
fu_ind = (FU_INDICATOR*)&sendbuf[12];
fu_ind->F = 0;
fu_ind->NRI = nIsIFrm;
fu_ind->TYPE= 28;
fu_hdr = (FU_HEADER*)&sendbuf[13];
fu_hdr->R = 0;
fu_hdr->S = 0;
fu_hdr->E = 0;
fu_hdr->TYPE=nNaluType;
nalu_payload=&sendbuf[14];
memcpy(nalu_payload,buffer+t*nalu_sent_len,nalu_sent_len);
bytes=nalu_sent_len+14;
for(is=0;is<MAX_RTSP_CLIENT;is++)
{
if(g_rtspClients[is].status == RTSP_SENDING)
{
pthread_mutex_lock(&g_sendmutex);
rtp_hdr->seq_no = htons(g_rtspClients[is].seqnum++);
rtp_hdr->ssrc = htonl(10 + is);
server.sin_family = AF_INET;
server.sin_port = htons(g_rtspClients[is].rtpport[0]);
server.sin_addr.s_addr = inet_addr(g_rtspClients[is].IP);
sendto(udpfd, sendbuf, bytes, 0, (struct sockaddr *)&server,sizeof(server));
pthread_mutex_unlock(&g_sendmutex);
}
}
t++;
}
}
}
}
|