/**
* 发送视频的sps和pps、vps信息
*
* @param pps 存储视频的pps信息
* @param pps_len 视频的pps信息长度
* @param sps 存储视频的pps信息
* @param sps_len 视频的sps信息长度
* @param vps 存储视频的vps信息
* @param vps_len 视频的vps信息长度
*
* @成功则返回 1 , 失败则返回0
*/
int SendVideoSpsPps(unsigned char *pps,int pps_len,unsigned char * sps,int sps_len,unsigned char* vps, int vps_len)
{
RTMPPacket * packet=NULL;//rtmp包结构
unsigned char * body=NULL;
int i;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+1024);
//RTMPPacket_Reset(packet);//重置packet状态
memset(packet,0,RTMP_HEAD_SIZE+1024);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
body = (unsigned char *)packet->m_body;
int i = 0;
body[i++] = 0x1C;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
//general_profile_idc 8bit
body[i++] = sps[1];
//general_profile_compatibility_flags 32 bit
body[i++] = sps[2];
body[i++] = sps[3];
body[i++] = sps[4];
body[i++] = sps[5];
// 48 bit NUll nothing deal in rtmp
body[i++] = sps[6];
body[i++] = sps[7];
body[i++] = sps[8];
body[i++] = sps[9];
body[i++] = sps[10];
body[i++] = sps[11];
//general_level_idc
body[i++] = sps[12];
// 48 bit NUll nothing deal in rtmp
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
//bit(16) avgFrameRate;
body[i++] = 0x00;
body[i++] = 0x00;
/* bit(2) constantFrameRate; */
/* bit(3) numTemporalLayers; */
/* bit(1) temporalIdNested; */
body[i++] = 0x00;
/* unsigned int(8) numOfArrays; 03 */
body[i++] = 0x03;
printf("HEVCDecoderConfigurationRecord data = %s\n", body);
body[i++] = 0x20; //vps 32
body[i++] = (1 >> 8) & 0xff;
body[i++] = 1 & 0xff;
body[i++] = (vps_len >> 8) & 0xff;
body[i++] = (vps_len) & 0xff;
memcpy(&body[i], vps, vps_len);
i += vps_len;
//sps
body[i++] = 0x21; //sps 33
body[i++] = (1 >> 8) & 0xff;
body[i++] = 1 & 0xff;
body[i++] = (sps_len >> 8) & 0xff;
body[i++] = sps_len & 0xff;
memcpy(&body[i], sps, sps_len);
i += sps_len;
//pps
body[i++] = 0x22; //pps 34
body[i++] = (1 >> 8) & 0xff;
body[i++] = 1 & 0xff;
body[i++] = (pps_len >> 8) & 0xff;
body[i++] = (pps_len) & 0xff;
memcpy(&body[i], pps, pps_len);
i += pps_len;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
packet->m_nBodySize = i;
packet->m_nChannel = 0x04;
packet->m_nTimeStamp = 0;
packet->m_hasAbsTimestamp = 0;
packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
packet->m_nInfoField2 = m_pRtmp->m_stream_id;
/*调用发送接口*/
int nRet = RTMP_SendPacket(m_pRtmp,packet,TRUE);
free(packet); //释放内存
return nRet;
}
/**
* 发送H265数据帧
*
* @param data 存储数据帧内容
* @param size 数据帧的大小
* @param bIsKeyFrame 记录该帧是否为关键帧
* @param nTimeStamp 当前帧的时间戳
*
* @成功则返回 1 , 失败则返回0
*/
int SendH265Packet(unsigned char *data,unsigned int size,int bIsKeyFrame,unsigned int nTimeStamp)
{
if(data == NULL && size<11){
return false;
}
unsigned char *body = (unsigned char*)malloc(size+9);
memset(body,0,size+9);
int i = 0;
if(bIsKeyFrame){
body[i++] = 0x1C;// 1:Iframe 7:AVC 这里改为C(12)nginx转发必须的
SendVideoSpsPps(metaData.Pps,metaData.nPpsLen,metaData.Sps,metaData.nSpsLen,metaData.Vps,metaData.nVpsLen);
}else{
body[i++] = 0x2C;// 2:Pframe 7:AVC
}
body[i++] = 0x01;// AVC NALU
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
// NALU size
body[i++] = size >> 24 & 0xff;
body[i++] = size >> 16 & 0xff;
body[i++] = size >> 8 & 0xff;
body[i++] = size & 0xff;
// NALU data
memcpy(&body[i], data, size);
int bRet = SendPacket(RTMP_PACKET_TYPE_VIDEO,body,i+size,nTimeStamp);
free(body);
return bRet;
}