一:MPEG2_TS_H264_AAC_Mux 代码分析
该代码是把H264裸流和AAC(有ADTS头)封装为TS流。
读取本地的H264裸流文件和AAC文件,封装为TS流。 还有一点bug,没有bug的版本在tsmux文件中。
主要是两个函数
int Take_Out_Pes( TsPes * tspes ,unsigned long time_pts,unsigned int frametype,unsigned int * videoframetype )
1:是把原始码流(H264和AAC)封装为PES头的码流。
int PES2TS( TsPes * ts_pes, unsigned int Video_Audio_PID , Ts_Adaptation_field * ts_adaptation_field_Head , Ts_Adaptation_field * ts_adaptation_field_Tail,
unsigned long Videopts, unsigned long Adudiopts )
2:是把PES头的码流(H264和AAC)封装为TS头的TS标准流。
二:封装H264(AAC)为TS流
一般情况下,一个nal一个帧。H264的码流组成,我省略了。
1:把码流封装为pes头
H264—>读取一个个的nal,然后把一个个的nal封装为pes头的形式,不懂怎么封装为pes头的,看前面的代码就可以很清晰了。
AAC—>读取AAC音频包,去掉ADTS头,然后给音频包封装为pes头的形式。
2:pes -> ts。把pes头的码流,封装为TS标准流。
在封装成ts流的时候,还需要打入pat和pmt。怎么打入,请看代码。
这里需要注意给pts的赋值:
这里以视频帧率为25HZ,90Khz的视频频率为例:
pts==1/25*90000 = 3600 个clk。
三: TS流的格式
TS流是基于Packet的位流格式,每个包是188个字节(或204个字节,在188个字节后加上了16字节的CRC校验数据,其他格式一样)。整个TS流组成形式如下:
TS流是由一个个Packet(包)构成的,每个包都是由Packet Header(包头)和Packet Data(包数据)组成的。其中Packet Header指示了该Packet是什么属性的,并给出了该Packet Data的数据的唯一网络标识符PID。
关于PAT表
PAT表定义了当前TS流中所有的节目,其PID为0x0000,它是PSI的根节点,要查寻找节目必须从PAT表开始查找。PAT表主要包含频道号码和每一个频道对应的PMT的PID号码。
PAT表的结构体:
typedef struct TS_PAT_Program
{
unsigned program_number : 16; //节目号
unsigned program_map_PID : 13; // 节目映射表的PID,节目号大于0时对应的PID,每个节目对应一个
}TS_PAT_Program
typedef struct TS_PAT
{
unsigned table_id : 8; //固定为0x00 ,标志是该表是PAT表
unsigned section_syntax_indicator : 1; //段语法标志位,固定为1
unsigned zero : 1; //0
unsigned reserved_1 : 2; // 保留位
unsigned section_length : 12; //表示从下一个字段开始到CRC32(含)之间有用的字节数
unsigned transport_stream_id : 16; //该传输流的ID,区别于一个网络中其它多路复用的流
unsigned reserved_2 : 2;// 保留位
unsigned version_number : 5; //范围0-31,表示PAT的版本号
unsigned current_next_indicator : 1; //发送的PAT是当前有效还是下一个PAT有效
unsigned section_number : 8; //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段
unsigned last_section_number : 8; //最后一个分段的号码
std::vector program;
unsigned reserved_3 : 3; // 保留位
unsigned network_PID : 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID
unsigned CRC_32 : 32; //CRC32校验码
} TS_PAT;
关于PMT表
如果一个TS流中含有多个频道,那么就会包含多个PID不同的PMT表。
PMT表中包含的数据如下:
(1) 当前频道中包含的所有Video数据的PID
(2) 当前频道中包含的所有Audio数据的PID
(3) 和当前频道关联在一起的其他数据的PID(如数字广播,数据通讯等使用的PID)
http://blog.csdn.net/zxh821112/article/details/17587215
http://blog.csdn.net/bingqingsuimeng/article/details/9942829
http://blog.csdn.net/max_min_go/article/details/39463675