1.资源下载
(23条消息) rtsp传输h264和h265视频推流c代码-Linux文档类资源-CSDN文库
h265和h264都可以通过rtsp传输
h265修改部分代码
1.fifo写数据部分
int HisiPutH265DataToBuffer(IMPEncoderStream *stream)
{
int i;
int a;
for (i = 0; i < stream->packCount; i++){
if(n<NMAX){
memcpy(ringfifo[iput].buffer, stream->virAddr, stream->pack[i].length);
ringfifo[iput].size= stream->pack[i].length;
iput = addring(iput);
n++;
}
}
return 1;
}
2.结构体部分增加
typedef struct
{
//byte 0
unsigned char u1Lid:1;
unsigned char u6Type:6;
unsigned char u1F:1;
} StFuIndicator_h265_1; /**/ /* 1 BYTES */
typedef struct
{
//byte 0
unsigned char u3Tid:3;
unsigned char u5Lid:5;
} StFuIndicator_h265_2; /**/ /* 1 BYTES */
typedef struct
{
//byte 0
unsigned char u6Type:6;
unsigned char u1E:1;
unsigned char u1S:1;
} StFuHdr_h265; /**/ /* 1 BYTES */
typedef struct _tagStRtpHandle
{
.....
StFuIndicator_h265_1 *pFuInd_1;
StFuIndicator_h265_2 *pFuInd_2;
StFuHdr_h265 *pFuHdr_h265;
.....
#endif
} StRtpObj, *HndRtp;
3.h265组包方式函数接口
static int SendNalu265(HndRtp hRtp, char *pNalBuf, int s32NalBufSize)
{
char *pNaluPayload;
char *pSendBuf;
int s32Bytes = 0;
int s32Ret = 0;
struct timeval stTimeval;
char *pNaluCurr;
int s32NaluRemain;
unsigned char u8NaluBytes_1;
unsigned char u8NaluBytes_2;
char *buf = NULL;
#if 0 //for debug
int idx = 0;
static int g_num = 0;
if(g_num < 20){
while(idx<(s32NalBufSize < 64 ? s32NalBufSize : 64)){
printf("%02x ",pNalBuf[idx]);
idx++;
if(idx%16 == 0){
printf("\n");
}
}
g_num++;
printf("size=%d\n\n",s32NalBufSize);
}
#endif
pSendBuf = (char *)calloc(MAX_RTP_PKT_LENGTH + 100, sizeof(char));
if(NULL == pSendBuf)
{
s32Ret = -1;
goto cleanup;
}
hRtp->pRtpFixedHdr = (StRtpFixedHdr *)pSendBuf;
hRtp->pRtpFixedHdr->u7Payload = H264;
hRtp->pRtpFixedHdr->u2Version = 2;
hRtp->pRtpFixedHdr->u1Marker = 0;
hRtp->pRtpFixedHdr->u32SSrc = hRtp->u32SSrc;
//计算时间戳
hRtp->pRtpFixedHdr->u32TimeStamp = htonl(hRtp->u32TimeStampCurr * (90000 / 1000));
//printf("sendnalu264 timestamp:%lld\n",hRtp->u32TimeStampCurr);
if(gettimeofday(&stTimeval, NULL) == -1)
{
printf("Failed to get os time\n");
s32Ret = -1;
goto cleanup;
}
//保存nalu首2 byte
u8NaluBytes_1 = *(pNalBuf+4);
u8NaluBytes_2 = *(pNalBuf+5);
//设置未发送的Nalu数据指针位置
pNaluCurr = pNalBuf + 4;
//设置剩余的Nalu数据数量
s32NaluRemain = s32NalBufSize - 4;
//NALU包小于等于最大包长度,直接发送
if(s32NaluRemain <= MAX_RTP_PKT_LENGTH)
{
hRtp->pRtpFixedHdr->u1Marker = 1;
hRtp->pRtpFixedHdr->u16SeqNum = htons(hRtp->u16SeqNum ++);
pNaluPayload = (pSendBuf + 12);
memcpy(pNaluPayload, pNaluCurr, s32NaluRemain);
s32Bytes = s32NaluRemain + 12;
if(sendto(hRtp->s32Sock, pSendBuf, s32Bytes, 0, (struct sockaddr *)&hRtp->stServAddr, sizeof(hRtp->stServAddr)) < 0)
{
s32Ret = -1;
goto cleanup;
}
#ifdef SAVE_NALU
fwrite(pSendBuf, s32Bytes, 1, hRtp->pNaluFile);
#endif
}
//NALU包大于最大包长度,分批发送
else
{
//去掉nalu首2 byte
pNaluCurr = pNaluCurr + 2;
s32NaluRemain = s32NaluRemain - 2;
//指定fu indicator位置
hRtp->pFuInd_1 = (StFuIndicator *)(pSendBuf + 12);
hRtp->pFuInd_1->u1F = (u8NaluBytes_1 & 0x80) >> 7;
hRtp->pFuInd_1->u1Lid = u8NaluBytes_1 & 0x01;
hRtp->pFuInd_1->u6Type = 49;
hRtp->pFuInd_2 = (StFuIndicator *)(pSendBuf + 13);
hRtp->pFuInd_2->u3Tid = u8NaluBytes_2 & 0x07;
hRtp->pFuInd_2->u5Lid = (u8NaluBytes_2 & 0xf0) >> 4;
//指定fu header位置
hRtp->pFuHdr_h265 = (StFuHdr *)(pSendBuf + 14);
hRtp->pFuHdr_h265->u6Type = (u8NaluBytes_1 >> 1) & 0x3F;
//指定payload位置
pNaluPayload = (pSendBuf + 15);
//当剩余Nalu数据多于0时分批发送nalu数据
while(s32NaluRemain > 0)
{
/*配置fixed header*/
//每个包序号增1
hRtp->pRtpFixedHdr->u16SeqNum = htons(hRtp->u16SeqNum ++);
hRtp->pRtpFixedHdr->u1Marker = (s32NaluRemain <= MAX_RTP_PKT_LENGTH) ? 1 : 0;
/*配置fu header*/
//最后一批数据则置1
hRtp->pFuHdr_h265->u1E = (s32NaluRemain <= MAX_RTP_PKT_LENGTH) ? 1 : 0;
//第一批数据则置1
hRtp->pFuHdr_h265->u1S = (s32NaluRemain == (s32NalBufSize - 6)) ? 1 : 0;
s32Bytes = (s32NaluRemain < MAX_RTP_PKT_LENGTH) ? s32NaluRemain : MAX_RTP_PKT_LENGTH;
memcpy(pNaluPayload, pNaluCurr, s32Bytes);
//发送本批次
s32Bytes = s32Bytes + 15;
if(sendto(hRtp->s32Sock, pSendBuf, s32Bytes, 0, (struct sockaddr *)&hRtp->stServAddr, sizeof(hRtp->stServAddr)) < 0)
{
s32Ret = -1;
goto cleanup;
}
#ifdef SAVE_NALU
fwrite(pSendBuf, s32Bytes, 1, hRtp->pNaluFile);
#endif
//指向下批数据
pNaluCurr += MAX_RTP_PKT_LENGTH;
//计算剩余的nalu数据长度
s32NaluRemain -= MAX_RTP_PKT_LENGTH;
}
}
cleanup:
if(pSendBuf)
{
free((void *)pSendBuf);
}
return s32Ret;
}
4.sdp修改
strcat(pDescr,"H264/90000");//strcat(pDescr,"H265/90000"); //h265需要修改这里
5.建立RTP套接字修改
rtp_s->hndRtp = (struct _tagStRtpHandle*)RtpCreate((unsigned int)(((struct sockaddr_in *)(&pRtsp->stClientAddr))->sin_addr.s_addr), Transport.u.udp.cli_ports.RTP, _h265nalu);//_h264nalu