现在的版权保护系统都要求对媒体文件的ES数据进行加密,方便其转码、切片等操作。之前写过一篇基于ffmpeg对TS文件中的ES数据进行加密的文,今天这篇就讨论一下不借助其他开源模块而是根据TS文件的结构“徒手”拆解出ES数据并进行加密的流程。
关于TS文件结构就不在本文中描述了,不了解的话,可找度娘咨询,本文默认大家都了解,现在进入正题:
一、分析TS文件信息,获取ES数据的PID
解析PAT表
/*解析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<TS_PAT_Program> program;
unsigned reserved_3 : 3; // 保留位
unsigned network_PID : 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID
unsigned CRC_32 : 32; //CRC32校验码
} TS_PAT;
static HRESULT adjust_PAT_table( TS_PAT * packet, unsigned char * buffer) {
packet->table_id = buffer[0];
packet->section_syntax_indicator = buffer[1] >> 7;
packet->zero = buffer[1] >> 6 & 0x1;
packet->reserved_1 = buffer[1] >> 4 & 0x3;
packet->section_length = (buffer[1] & 0x0F) << 8 | buffer[2];
packet->transport_stream_id = buffer[3] << 8 | buffer[4];
packet->reserved_2