// Copyright 2020, Chef. All rights reserved. // https://github.com/q191201771/lal // // Use of this source code is governed by a MIT-style license // that can be found in the License file. // // Author: Chef (191201771@qq.com) package mpegts import ( "github.com/q191201771/naza/pkg/nazabits" "github.com/q191201771/naza/pkg/nazalog" ) // ---------------------------------------- // Program Map Table // <2.4.4.8> // table_id [8b] * // section_syntax_indicator [1b] // 0 [1b] // reserved [2b] // section_length [12b] ** // program_number [16b] ** // reserved [2b] // version_number [5b] // current_next_indicator [1b] * // section_number [8b] * // last_section_number [8b] * // reserved [3b] // PCR_PID [13b] ** // reserved [4b] // program_info_length [12b] ** // -----loop----- // stream_type [8b] * // reserved [3b] // elementary_PID [13b] ** // reserved [4b] // ES_info_length_length [12b] ** // -------------- // CRC32 [32b] **** // ---------------------------------------- type Pmt struct { tid uint8 ssi uint8 sl uint16 pn uint16 vn uint8 cni uint8 sn uint8 lsn uint8 pp uint16 pil uint16 ProgramElements []PmtProgramElement crc32 uint32 } type PmtProgramElement struct { StreamType uint8 Pid uint16 Length uint16 } func ParsePmt(b []byte) (pmt Pmt) { br := nazabits.NewBitReader(b) pmt.tid, _ = br.ReadBits8(8) pmt.ssi, _ = br.ReadBits8(1) _, _ = br.ReadBits8(3) pmt.sl, _ = br.ReadBits16(12) len := pmt.sl - 13 pmt.pn, _ = br.ReadBits16(16) _, _ = br.ReadBits8(2) pmt.vn, _ = br.ReadBits8(5) pmt.cni, _ = br.ReadBits8(1) pmt.sn, _ = br.ReadBits8(8) pmt.lsn, _ = br.ReadBits8(8) _, _ = br.ReadBits8(3) pmt.pp, _ = br.ReadBits16(13) _, _ = br.ReadBits8(4) pmt.pil, _ = br.ReadBits16(12) if pmt.pil != 0 { nazalog.Warn(pmt.pil) _, _ = br.ReadBytes(uint(pmt.pil)) } for i := uint16(0); i < len; i += 5 { var ppe PmtProgramElement ppe.StreamType, _ = br.ReadBits8(8) _, _ = br.ReadBits8(3) ppe.Pid, _ = br.ReadBits16(13) _, _ = br.ReadBits8(4) ppe.Length, _ = br.ReadBits16(12) if ppe.Length != 0 { nazalog.Warn(ppe.Length) _, _ = br.ReadBits32(uint(ppe.Length)) } pmt.ProgramElements = append(pmt.ProgramElements, ppe) } return } func (pmt *Pmt) SearchPid(pid uint16) *PmtProgramElement { for _, ppe := range pmt.ProgramElements { if ppe.Pid == pid { return &ppe } } return nil }