28181流媒體,ps流解析,nalu分析,出來的數據封裝成rtmp包發送rtmp,此處僅關心rtmp發送問題
這個連接有完整的調用librtmp發送h264的代碼,但是裏面發送h264包時候有問題,沒有區分包類型
https://blog.csdn.net/godspeed513/article/details/8972947
sps,pps包的構建可以參考這個連接
https://blog.csdn.net/u011003120/article/details/78378632
rtmp包的結構,可以參考這個連接,講的很清楚
https://blog.csdn.net/dqxiaoxiao/article/details/94820599
h264 的nalu分析
https://blog.csdn.net/xiaoluer/article/details/53462894
int SendPacket(unsigned int nPacketType,
unsigned int size,
unsigned int nTimestamp)
{
if(m_pRtmp == NULL)
{
return FALSE;
}
m_RTMPPacket.m_packetType = nPacketType;
//m_RTMPPacket.m_hasAbsTimestamp = 0;
m_RTMPPacket.m_nChannel = 0x04;
m_RTMPPacket.m_headerType = RTMP_PACKET_SIZE_LARGE;
m_RTMPPacket.m_nTimeStamp = nTimestamp;
m_RTMPPacket.m_nInfoField2 = m_pRtmp->m_stream_id;
m_RTMPPacket.m_nBodySize = size;
int nRet = RTMP_SendPacket(m_pRtmp,&m_RTMPPacket,0);
return nRet;
}
//過濾sei包,sei,輔助增強信息
if (packet.type == NaluPacket::NALU_SEI)
{
return;
}
//sps,pps一般成對出現
if (packet.type == NaluPacket::NALU_SPS)
{
//sps, sequenceParameterSetLength
body[0] = 0x17;
body[1] = 0x00;//avc packet type, 0,sequeue header, 1, nalu,視頻幀數據爲1,其他爲0
body[2] = 0x00;//3個字節,composition time,當上個字節包類型爲0時
body[3] = 0x00;//這3個字節也爲0
body[4] = 0x00;
// 如果包類型爲0, 此處是AVCDecoderConfigurationRecord結構
body[5] = 0x01;//版本號,固定爲1
body[6] = *(packet.data + 1);//AVCProfileIndication,sps信息裏面去除頭部信息和sps標誌後的第一個字節
//sps標誌爲0x67
body[7] = *(packet.data + 2);//profile_compatibility,h264 profile支持級別
body[8] = *(packet.data + 3);//AVCLevelIndication, level_idc syntax element,默認值21
//表示支持的最大分辨率和採樣率,21爲HHR,5068.8k samples/second
//最大值爲51,4096*2304, 251658.24k samples/second
body[9] = 0xff; //高6位保留,默認爲'111111', 低2位表示lengthSizeMinusOne
body[10] = 0xe1; //高3位保留,默認爲'111', 低5位表示numOfSequenceParameterSets,
//sequeue參數設置的格式,此處爲1,即只有1個sps
body[11] = (size >> 8) & 0xff; //sequenceParameterSetLength,2個字節,sps長度
body[12] = size & 0xff;
bodyLength = 13;
memcpy(&body[13], packet.data, size);//sps內容
bodyLength += size;
m_setsps = 1;
}
else if (packet.type == NaluPacket::NALU_PPS)
{
/*pps,PictureParameterSets*/
body[bodyLength++] = 0x01;//numOfPictureParameterSets,pps個數
body[bodyLength++] = (size >> 8) & 0xff;//pictureParameterSetLength,pps長度,2個字節
body[bodyLength++] = (size) & 0xff;
memcpy(&body[bodyLength], packet.data, size);//pictureParameterSetNaLUUnit,pps內容
bodyLength += size;
//如果profile_idc爲100,110,122,144時,需要填充sequenceParameterSetExtLength,即sps擴展
//sps擴展,nalu 類型爲13
memcpy(body, body, bodyLength);
//發送數據包
}
if(packet.type == 5)
{
body[i++] = 0x17;// 1:Iframe 7:AVC
}
else
{
body[i++] = 0x27;// 2:Pframe 7:AVC
}
body[i++] = 0x01;// AVC NALU
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
// NALU size
body[i++] = size>>24;
body[i++] = size>>16;
body[i++] = size>>8;
body[i++] = size&0xff;;
// NALU data
memcpy(&(body[i]),packet.data,size);
//發送數據包