视音频流封装为ps包
ps包开头PSH头,起始码固定为0x000001BA
常见的,一个ps包一般是多个pes包组成的一个视频帧加一个音频pes包(可能一个或多个音频帧)。
对于项目中用到的视音频流(h.264编码流+aac的ADTS流)
进行了如下封装:
视频ps:PSH+(PSM)+PES (一个ps包中一或多个pes包)
音频ps:PSH+PES(一个ps包一般一个pes包)
PSM只有视频关键帧时存在,起始码0x000001bc
PES包的最大长度为65535字节,因此一帧数据有可能被分为多个PES
实际比较规范的封装方式应该是音频的pes包放在视频pes包后面,而不用单独封装成ps包。
ps包再以负载形式封装为rtp包。
ffmpeg解码播放ps流:
av_read_frame根据AVFormatContext参数从ps裸流中读取packet压缩帧数据, 音频时由于aac大小不固定,一个pkt即为一个ADTS帧(ADTS头+AAC裸数据)
视频时一个pkt仅有一个frame
音频时若frame已知固定大小如PCM/ADPCM,则一个pkt包含一个整数个数的frame,若大小不固定如mpeg audio则一个pkt含一个frame
ps流封装aac音频时需要加上ADTS头,否则音频会播放失败。而对于rtsp传输,aac音频进行RTP封装时不保留ADTS头,因为已经在会话设置阶段通过SDP描述。