解析完成PAT之后,就得到了PRogram的信息了,如果program中存放了PMT的信息,那么就把program中PMT的PID记录下来,根据PID查找对应的TS包,找到之后就可以从该TS包中解析出PMT了
// 从TS包中读取PMT friend PMT& Operator<<(PMT& pmt, Packet& packet) { const char* payload; // 从TS包中读取负载 packet.getPayload(payload); // 强制转换为PMT pmt = *reinterpret_cast<const PMT*> (payload); // 判断table的id是否等于0x02,如果是,那么表示真的是PMT if (pmt.table_id == TABLE_ID_PMT) { pmt.good = true; } return pmt; }从PMT中解析stream的信息
stream的定义
class Stream { public: friend class PMT; // stream的类型 enum StreamType { MPEG_1_VIDEO = 0x01, // MPEG1的视频 MPEG_2_VIDEO = 0x02, // MPEG2的视频 MPEG_1_AUDIO = 0x03, // MPEG1的音频 MPEG_2_AUDIO = 0x04, // MPEG2的音频 }; inline StreamType getStreamType() const { return static_cast<StreamType> (stream_type); } inline uint16_t getElementaryPid() const { return (elementary_pid1 << 8) | elementary_pid2; } private: uint8_t stream_type; // stream的类型 uint8_t elementary_pid1 :5; // PID uint8_t reserved1 :3; uint8_t elementary_pid2; uint8_t es_info_length1 :2; // ES 描述符长度 uint8_t reserved2 :6; uint8_t es_info_length2; // FIXME no ES descriptor };读取stream的信息
stream中就存放了音视频数据的信息,例如类型和状态这些音视频数据的TS包等
// 返回stream std::vector<PMT::Stream> getStreams() const { std::vector<PMT::Stream> streams; // 在PMT头部与crc之间存放了stream的信息 for (const uint8_t* off = data; off < data + getSectionLength() - sizeof(CRC32) - (data - §ion_length2); off += sizeof(Stream)) { // 强制转换 Stream stream = *reinterpret_cast<const Stream*> (off); off += (stream.es_info_length1 << 8) | stream.es_info_length2; streams.push_back(stream); } return streams; }
新闻热点
疑难解答