// // Created by 29019 on 2019/5/4. // #include "rtp.h" #include "librtsp.h" int Pack264(unsigned char *frame,int size, Vector **outbuf){ int i = 0; static short seq = 0; if((0 == frame) || (0 == outbuf)){ return 0; } // fill rtsp interleaved header RtspInterleavedFrameHeader rtspInterleavedFrameHeader; rtspInterleavedFrameHeader.magic = 0x24; rtspInterleavedFrameHeader.channel = 0; //fill rtp header CRtpHeader header; header.version = 2; header.cc = 0; header.m = 0; header.p = 0; header.pt = 96; header.ts = htonl(1201233060); header.x = 0; header.ssrc = htonl(0x055aaee0); if((frame[0] != 0x00)&&(frame[1] != 0x00)&&(frame[2] != 0x00) && (frame[3] != 0x01)){ return -1; } int packCnt = (size - 5) /MAX_RTP_LEN; printf("%d package pack\r\n",packCnt); if(packCnt == 0){ header.seq = htons(seq++); outbuf[0]->data = (unsigned char *)malloc(sizeof(FuIdentifier) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader) + size - 5); outbuf[0]->length = size - 5 + sizeof(FuIdentifier) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); FuIdentifier identifier; identifier.FUType = frame[4]&0x1f; //sps or pps identifier.NRI = (frame[4]&0xe0)>>5; identifier.F = 0; rtspInterleavedFrameHeader.length = htons(size - 5 + sizeof(FuIdentifier) + sizeof(CRtpHeader) ); int index = 0; memcpy(outbuf[0]->data,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy(outbuf[0]->data + index,&header,sizeof(header)); index += sizeof(header); memcpy(outbuf[0]->data + index,&identifier,sizeof(FuIdentifier)); index += sizeof(identifier); memcpy(outbuf[0]->data + index,frame + 5,size - 5); return 1; // return one package }else{ if(packCnt % MAX_RTP_LEN != 0){ packCnt +=1; } CH264NalUnit nalUnit; nalUnit.Identifier.FUType = 28; // fu-a nalUnit.Identifier.NRI = (frame[4]&0xe0)>>5; nalUnit.Identifier.F = 0; nalUnit.Header.NALUnitType = (frame[4]&0x1f); // idr picture or non-idr picture nalUnit.Header.Forbid = 0; for(i = 0;i < packCnt;i++) { header.seq = htons(seq++); if(i == packCnt - 1) { if(packCnt % MAX_RTP_LEN == 0){ (*outbuf + i)->data = (unsigned char *)malloc(sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader) + MAX_RTP_LEN); (*outbuf + i)->length = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); rtspInterleavedFrameHeader.length = htons(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); }else{ (*outbuf + i)->data = (unsigned char *)malloc(sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader) + (size - 5)%MAX_RTP_LEN); (*outbuf + i)->length = (size - 5)%MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); rtspInterleavedFrameHeader.length = htons((size - 5)%MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); } nalUnit.Header.End = 1; nalUnit.Header.Start = 0; int index = 0; memcpy((*outbuf + i)->data,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy((*outbuf + i)->data + index,&header,sizeof(header)); index += sizeof(header); memcpy((*outbuf + i)->data + index,&nalUnit,sizeof(nalUnit)); index += sizeof(nalUnit); memcpy((*outbuf + i)->data + index,frame + 5 + i*MAX_RTP_LEN,(size - 5)%MAX_RTP_LEN); }else if(i == 0){ nalUnit.Header.End = 0; nalUnit.Header.Start = 1; (*outbuf + i)->data = (unsigned char *)malloc(sizeof(FuIdentifier) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader) + MAX_RTP_LEN); (*outbuf + i)->length = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); rtspInterleavedFrameHeader.length = htons(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); int index = 0; memcpy((*outbuf + i)->data,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy((*outbuf + i)->data + index,&header,sizeof(header)); index += sizeof(header); memcpy((*outbuf + i)->data + index,&nalUnit,sizeof(nalUnit)); index += sizeof(nalUnit); memcpy((*outbuf + i)->data + index,frame + 5 + i*MAX_RTP_LEN,MAX_RTP_LEN); }else{ (*outbuf + i)->data = (unsigned char *)malloc(sizeof(FuIdentifier) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader) + MAX_RTP_LEN); (*outbuf + i)->length = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); nalUnit.Header.End = 0; nalUnit.Header.Start = 0; rtspInterleavedFrameHeader.length = htons(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); int index = 0; memcpy((*outbuf + i)->data,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy((*outbuf + i)->data + index,&header,sizeof(header)); index += sizeof(header); memcpy((*outbuf + i)->data + index,&nalUnit,sizeof(nalUnit)); index += sizeof(nalUnit); memcpy((*outbuf + i)->data + index,frame + 5 + i*MAX_RTP_LEN,MAX_RTP_LEN); } } return packCnt; } } char *sendBuf = 0; int Pack264AndSend(unsigned char *frame,int size,RtspClient * p){ int i = 0; static short seq = 0; int sendLength = 0; int length = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(RtspInterleavedFrameHeader); if(0 == frame || NULL == p) { return 0; } if( 0 == sendBuf) sendBuf = malloc(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(RtspInterleavedFrameHeader)); // fill rtsp interleaved header RtspInterleavedFrameHeader rtspInterleavedFrameHeader; rtspInterleavedFrameHeader.magic = 0x24; rtspInterleavedFrameHeader.channel = 0; //fill rtp header CRtpHeader header; header.version = 2; header.cc = 0; header.m = 0; header.p = 0; header.pt = 96; header.ts = htonl(1201233060); header.x = 0; header.ssrc = htonl(0x055aaee0); if((frame[0] != 0x00)&&(frame[1] != 0x00)&&(frame[2] != 0x00) && (frame[3] != 0x01)){ return -1; } int packCnt = (size - 5) /MAX_RTP_LEN; // printf("%d package pack\r\n",packCnt); if(packCnt == 0) { header.seq = htons(seq++); sendLength = size - 5 + sizeof(FuIdentifier) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); FuIdentifier identifier; identifier.FUType = frame[4]&0x1f; //sps or pps identifier.NRI = (frame[4]&0xe0)>>5; identifier.F = 0; rtspInterleavedFrameHeader.length = htons(size - 5 + sizeof(FuIdentifier) + sizeof(CRtpHeader) ); int index = 0; memcpy(sendBuf,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy(sendBuf + index,&header,sizeof(header)); index += sizeof(header); memcpy(sendBuf + index,&identifier,sizeof(FuIdentifier)); index += sizeof(identifier); memcpy(sendBuf + index,frame + 5,size - 5); SendRtpPackage(p,sendBuf,sendLength); return 1; // return one package }else{ if(packCnt % MAX_RTP_LEN != 0){ packCnt +=1; } CH264NalUnit nalUnit; nalUnit.Identifier.FUType = 28; // fu-a nalUnit.Identifier.NRI = (frame[4]&0xe0)>>5; nalUnit.Identifier.F = 0; nalUnit.Header.NALUnitType = (frame[4]&0x1f); // idr picture or non-idr picture nalUnit.Header.Forbid = 0; for(i = 0;i < packCnt;i++) { header.seq = htons(seq++); if(i == packCnt - 1) { if(packCnt % MAX_RTP_LEN == 0){ sendLength = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(RtspInterleavedFrameHeader); rtspInterleavedFrameHeader.length = htons(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); }else{ sendLength = (size - 5)%MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(RtspInterleavedFrameHeader); //printf("last package send %d length\r\n",sendLength); rtspInterleavedFrameHeader.length = htons((size - 5)%MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); } nalUnit.Header.End = 1; nalUnit.Header.Start = 0; int index = 0; memcpy(sendBuf,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy(sendBuf + index,&header,sizeof(header)); index += sizeof(header); memcpy(sendBuf + index,&nalUnit,sizeof(nalUnit)); index += sizeof(nalUnit); memcpy(sendBuf + index,frame + 5 + i*MAX_RTP_LEN,(size - 5)%MAX_RTP_LEN); SendRtpPackage(p,sendBuf,sendLength); }else if(i == 0) { nalUnit.Header.End = 0; nalUnit.Header.Start = 1; sendLength = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); rtspInterleavedFrameHeader.length = htons(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); int index = 0; memcpy(sendBuf,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy(sendBuf + index,&header,sizeof(header)); index += sizeof(header); memcpy(sendBuf + index,&nalUnit,sizeof(nalUnit)); index += sizeof(nalUnit); memcpy(sendBuf + index,frame + 5 + i*MAX_RTP_LEN,MAX_RTP_LEN); SendRtpPackage(p,sendBuf,sendLength); }else{ sendLength = MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader) + sizeof(rtspInterleavedFrameHeader); nalUnit.Header.End = 0; nalUnit.Header.Start = 0; rtspInterleavedFrameHeader.length = htons(MAX_RTP_LEN + sizeof(CH264NalUnit) + sizeof(CRtpHeader)); int index = 0; memcpy(sendBuf,&rtspInterleavedFrameHeader,sizeof(rtspInterleavedFrameHeader)); index += sizeof(rtspInterleavedFrameHeader); memcpy(sendBuf + index,&header,sizeof(header)); index += sizeof(header); memcpy(sendBuf + index,&nalUnit,sizeof(nalUnit)); index += sizeof(nalUnit); memcpy(sendBuf + index,frame + 5 + i*MAX_RTP_LEN,MAX_RTP_LEN); SendRtpPackage(p,sendBuf,sendLength); } } // free(sendBuf); return packCnt; } }