ts-proto.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. package mpeg2
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "os"
  7. "github.com/yapingcat/gomedia/codec"
  8. )
  9. //PID
  10. type TS_PID int
  11. const (
  12. TS_PID_PAT TS_PID = 0x0000
  13. TS_PID_CAT
  14. TS_PID_TSDT
  15. TS_PID_IPMP
  16. TS_PID_Nil = 0x1FFFF
  17. )
  18. //Table id
  19. type PAT_TID int
  20. const (
  21. TS_TID_PAS PAT_TID = 0x00 // program_association_section
  22. TS_TID_CAS = 0x01 // conditional_access_section(CA_section)
  23. TS_TID_PMS = 0x02 // TS_program_map_section
  24. TS_TID_SDS = 0x03 //TS_description_section
  25. TS_TID_FORBIDDEN PAT_TID = 0xFF
  26. )
  27. type TS_STREAM_TYPE int
  28. const (
  29. TS_STREAM_AAC TS_STREAM_TYPE = 0x0F
  30. TS_STREAM_H264 TS_STREAM_TYPE = 0x1B
  31. TS_STREAM_H265 TS_STREAM_TYPE = 0x24
  32. )
  33. const (
  34. TS_PAKCET_SIZE = 188
  35. )
  36. type Display interface {
  37. PrettyPrint(file *os.File)
  38. }
  39. // transport_packet(){
  40. // sync_byte 8 bslbf
  41. // transport_error_indicator 1 bslbf
  42. // payload_unit_start_indicator 1 bslbf
  43. // transport_priority 1 bslbf
  44. // PID 13 uimsbf
  45. // transport_scrambling_control 2 bslbf
  46. // adaptation_field_control 2 bslbf
  47. // continuity_counter 4 uimsbf
  48. // if(adaptation_field_control = = '10' || adaptation_field_control = = '11'){
  49. // adaptation_field()
  50. // }
  51. // if(adaptation_field_control = = '01' || adaptation_field_control = = '11') {
  52. // for (i = 0; i < N; i++){
  53. // data_byte 8 bslbf
  54. // }
  55. // }
  56. // }
  57. type TSPacket struct {
  58. Transport_error_indicator uint8
  59. Payload_unit_start_indicator uint8
  60. Transport_priority uint8
  61. PID uint16
  62. Transport_scrambling_control uint8
  63. Adaptation_field_control uint8
  64. Continuity_counter uint8
  65. Field *Adaptation_field
  66. Payload interface{}
  67. }
  68. func (pkg *TSPacket) PrettyPrint(file *os.File) {
  69. file.WriteString(fmt.Sprintf("Transport_error_indicator:%d\n", pkg.Transport_error_indicator))
  70. file.WriteString(fmt.Sprintf("Payload_unit_start_indicator:%d\n", pkg.Payload_unit_start_indicator))
  71. file.WriteString(fmt.Sprintf("Transport_priority:%d\n", pkg.Transport_priority))
  72. file.WriteString(fmt.Sprintf("PID:%d\n", pkg.PID))
  73. file.WriteString(fmt.Sprintf("Transport_scrambling_control:%d\n", pkg.Transport_scrambling_control))
  74. file.WriteString(fmt.Sprintf("Adaptation_field_control:%d\n", pkg.Adaptation_field_control))
  75. file.WriteString(fmt.Sprintf("Continuity_counter:%d\n", pkg.Continuity_counter))
  76. }
  77. func (pkg *TSPacket) EncodeHeader(bsw *codec.BitStreamWriter) {
  78. bsw.PutByte(0x47)
  79. bsw.PutUint8(pkg.Transport_error_indicator, 1)
  80. bsw.PutUint8(pkg.Payload_unit_start_indicator, 1)
  81. bsw.PutUint8(pkg.Transport_priority, 1)
  82. bsw.PutUint16(pkg.PID, 13)
  83. bsw.PutUint8(pkg.Transport_scrambling_control, 2)
  84. bsw.PutUint8(pkg.Adaptation_field_control, 2)
  85. bsw.PutUint8(pkg.Continuity_counter, 4)
  86. if pkg.Field != nil && (pkg.Adaptation_field_control&0x02) != 0 {
  87. pkg.Field.Encode(bsw)
  88. }
  89. }
  90. func (pkg *TSPacket) DecodeHeader(bs *codec.BitStream) error {
  91. sync_byte := bs.Uint8(8)
  92. if sync_byte != 0x47 {
  93. return errors.New("ts packet must start with 0x47")
  94. }
  95. pkg.Transport_error_indicator = bs.GetBit()
  96. pkg.Payload_unit_start_indicator = bs.GetBit()
  97. pkg.Transport_priority = bs.GetBit()
  98. pkg.PID = bs.Uint16(13)
  99. pkg.Transport_scrambling_control = bs.Uint8(2)
  100. pkg.Adaptation_field_control = bs.Uint8(2)
  101. pkg.Continuity_counter = bs.Uint8(4)
  102. if pkg.Adaptation_field_control == 0x02 || pkg.Adaptation_field_control == 0x03 {
  103. if pkg.Field == nil {
  104. pkg.Field = new(Adaptation_field)
  105. }
  106. err := pkg.Field.Decode(bs)
  107. if err != nil {
  108. return err
  109. }
  110. }
  111. return nil
  112. }
  113. //
  114. // adaptation_field() {
  115. // adaptation_field_length
  116. // if (adaptation_field_length > 0) {
  117. // discontinuity_indicator
  118. // random_access_indicator
  119. // elementary_stream_priority_indicator
  120. // PCR_flag
  121. // OPCR_flag
  122. // splicing_point_flag
  123. // transport_private_data_flag
  124. // adaptation_field_extension_flag
  125. // if (PCR_flag == '1') {
  126. // program_clock_reference_base
  127. // reserved
  128. // program_clock_reference_extension
  129. // }
  130. // if (OPCR_flag == '1') {
  131. // original_program_clock_reference_base
  132. // reserved
  133. // original_program_clock_reference_extension
  134. // }
  135. // if (splicing_point_flag == '1') {
  136. // splice_countdown
  137. // }
  138. // if (transport_private_data_flag == '1') {
  139. // transport_private_data_length
  140. // for (i = 0; i < transport_private_data_length; i++) {
  141. // private_data_byte
  142. // }
  143. // }
  144. // if (adaptation_field_extension_flag == '1') {
  145. // adaptation_field_extension_length
  146. // ltw_flag piecewise_rate_flag
  147. // seamless_splice_flag
  148. // reserved
  149. // if (ltw_flag == '1') {
  150. // ltw_valid_flag
  151. // ltw_offset
  152. // }
  153. // if (piecewise_rate_flag == '1') {
  154. // reserved
  155. // piecewise_rate
  156. // }
  157. // if (seamless_splice_flag == '1') {
  158. // splice_type
  159. // DTS_next_AU[32..30]
  160. // marker_bit
  161. // DTS_next_AU[29..15]
  162. // marker_bit
  163. // DTS_next_AU[14..0]
  164. // marker_bit 1
  165. // }
  166. // for (i = 0; i < N; i++) {
  167. // reserved 8
  168. // }
  169. // }
  170. // for (i = 0; i < N; i++) {
  171. // stuffing_byte 8
  172. // }
  173. // }
  174. type Adaptation_field struct {
  175. SingleStuffingByte bool // The value 0 is for inserting a single stuffing byte in a Transport Stream packet
  176. Adaptation_field_length uint8 //8 uimsbf
  177. Discontinuity_indicator uint8 //1 bslbf
  178. Random_access_indicator uint8 //1 bslbf
  179. Elementary_stream_priority_indicator uint8 //1 bslbf
  180. PCR_flag uint8 //1 bslbf
  181. OPCR_flag uint8 //1 bslbf
  182. Splicing_point_flag uint8 //1 bslbf
  183. Transport_private_data_flag uint8 //1 bslbf
  184. Adaptation_field_extension_flag uint8 //1 bslbf
  185. Program_clock_reference_base uint64 //33 uimsbf
  186. Program_clock_reference_extension uint16 //9 uimsbf
  187. Original_program_clock_reference_base uint64 //33 uimsbf
  188. Original_program_clock_reference_extension uint16 //9 uimsbf
  189. Splice_countdown uint8 //8 uimsbf
  190. Transport_private_data_length uint8 //8 uimsbf
  191. Adaptation_field_extension_length uint8 //8 uimsbf
  192. Ltw_flag uint8 //1 bslbf
  193. Piecewise_rate_flag uint8 //1 bslbf
  194. Seamless_splice_flag uint8 //1 bslbf
  195. Ltw_valid_flag uint8 //1 bslbf
  196. Ltw_offset uint16 //15 uimsbf
  197. Piecewise_rate uint32 //22 uimsbf
  198. Splice_type uint8 //4 uimsbf
  199. DTS_next_AU uint64
  200. Stuffing_byte uint8
  201. }
  202. func (adaptation *Adaptation_field) PrettyPrint(file *os.File) {
  203. file.WriteString(fmt.Sprintf("Adaptation_field_length:%d\n", adaptation.Adaptation_field_length))
  204. file.WriteString(fmt.Sprintf("Discontinuity_indicator:%d\n", adaptation.Discontinuity_indicator))
  205. file.WriteString(fmt.Sprintf("Random_access_indicator:%d\n", adaptation.Random_access_indicator))
  206. file.WriteString(fmt.Sprintf("Elementary_stream_priority_indicator:%d\n", adaptation.Elementary_stream_priority_indicator))
  207. file.WriteString(fmt.Sprintf("PCR_flag:%d\n", adaptation.PCR_flag))
  208. file.WriteString(fmt.Sprintf("OPCR_flag:%d\n", adaptation.OPCR_flag))
  209. file.WriteString(fmt.Sprintf("Splicing_point_flag:%d\n", adaptation.Splicing_point_flag))
  210. file.WriteString(fmt.Sprintf("Transport_private_data_flag:%d\n", adaptation.Transport_private_data_flag))
  211. file.WriteString(fmt.Sprintf("Adaptation_field_extension_flag:%d\n", adaptation.Adaptation_field_extension_flag))
  212. if adaptation.PCR_flag == 1 {
  213. file.WriteString(fmt.Sprintf("Program_clock_reference_base:%d\n", adaptation.Program_clock_reference_base))
  214. file.WriteString(fmt.Sprintf("Program_clock_reference_extension:%d\n", adaptation.Program_clock_reference_extension))
  215. }
  216. if adaptation.OPCR_flag == 1 {
  217. file.WriteString(fmt.Sprintf("Original_program_clock_reference_base:%d\n", adaptation.Original_program_clock_reference_base))
  218. file.WriteString(fmt.Sprintf("Original_program_clock_reference_extension:%d\n", adaptation.Original_program_clock_reference_extension))
  219. }
  220. if adaptation.Splicing_point_flag == 1 {
  221. file.WriteString(fmt.Sprintf("Splice_countdown:%d\n", adaptation.Splice_countdown))
  222. }
  223. if adaptation.Transport_private_data_flag == 1 {
  224. file.WriteString(fmt.Sprintf("Transport_private_data_length:%d\n", adaptation.Transport_private_data_length))
  225. }
  226. if adaptation.Adaptation_field_extension_flag == 1 {
  227. file.WriteString(fmt.Sprintf("Adaptation_field_extension_length:%d\n", adaptation.Adaptation_field_extension_length))
  228. file.WriteString(fmt.Sprintf("Ltw_flag:%d\n", adaptation.Ltw_flag))
  229. file.WriteString(fmt.Sprintf("Piecewise_rate_flag:%d\n", adaptation.Piecewise_rate_flag))
  230. file.WriteString(fmt.Sprintf("Seamless_splice_flag:%d\n", adaptation.Seamless_splice_flag))
  231. if adaptation.Ltw_flag == 1 {
  232. file.WriteString(fmt.Sprintf("Ltw_valid_flag:%d\n", adaptation.Ltw_valid_flag))
  233. file.WriteString(fmt.Sprintf("Ltw_offset:%d\n", adaptation.Ltw_offset))
  234. }
  235. if adaptation.Piecewise_rate_flag == 1 {
  236. file.WriteString(fmt.Sprintf("Piecewise_rate:%d\n", adaptation.Piecewise_rate))
  237. }
  238. if adaptation.Seamless_splice_flag == 1 {
  239. file.WriteString(fmt.Sprintf("Splice_type:%d\n", adaptation.Splice_type))
  240. file.WriteString(fmt.Sprintf("DTS_next_AU:%d\n", adaptation.DTS_next_AU))
  241. }
  242. }
  243. }
  244. func (adaptation *Adaptation_field) Encode(bsw *codec.BitStreamWriter) {
  245. loc := bsw.ByteOffset()
  246. bsw.PutUint8(adaptation.Adaptation_field_length, 8)
  247. if adaptation.SingleStuffingByte {
  248. return
  249. }
  250. bsw.Markdot()
  251. bsw.PutUint8(adaptation.Discontinuity_indicator, 1)
  252. bsw.PutUint8(adaptation.Random_access_indicator, 1)
  253. bsw.PutUint8(adaptation.Elementary_stream_priority_indicator, 1)
  254. bsw.PutUint8(adaptation.PCR_flag, 1)
  255. bsw.PutUint8(adaptation.OPCR_flag, 1)
  256. bsw.PutUint8(adaptation.Splicing_point_flag, 1)
  257. bsw.PutUint8(0 /*adaptation.Transport_private_data_flag*/, 1)
  258. bsw.PutUint8(0 /*adaptation.Adaptation_field_extension_flag*/, 1)
  259. if adaptation.PCR_flag == 1 {
  260. bsw.PutUint64(adaptation.Program_clock_reference_base, 33)
  261. bsw.PutUint8(0, 6)
  262. bsw.PutUint16(adaptation.Program_clock_reference_extension, 9)
  263. }
  264. if adaptation.OPCR_flag == 1 {
  265. bsw.PutUint64(adaptation.Original_program_clock_reference_base, 33)
  266. bsw.PutUint8(0, 6)
  267. bsw.PutUint16(adaptation.Original_program_clock_reference_extension, 9)
  268. }
  269. if adaptation.Splicing_point_flag == 1 {
  270. bsw.PutUint8(adaptation.Splice_countdown, 8)
  271. }
  272. //TODO
  273. // if adaptation.Transport_private_data_flag == 0 {
  274. // }
  275. // if adaptation.Adaptation_field_extension_flag == 0 {
  276. // }
  277. adaptation.Adaptation_field_length = uint8(bsw.DistanceFromMarkDot() / 8)
  278. bsw.PutRepetValue(0xff, int(adaptation.Stuffing_byte))
  279. adaptation.Adaptation_field_length += adaptation.Stuffing_byte
  280. bsw.SetByte(adaptation.Adaptation_field_length, loc)
  281. }
  282. func (adaptation *Adaptation_field) Decode(bs *codec.BitStream) error {
  283. if bs.RemainBytes() < 1 {
  284. return errors.New("len of data < 1 byte")
  285. }
  286. adaptation.Adaptation_field_length = bs.Uint8(8)
  287. startoffset := bs.ByteOffset()
  288. //fmt.Printf("Adaptation_field_length=%d\n", adaptation.Adaptation_field_length)
  289. if bs.RemainBytes() < int(adaptation.Adaptation_field_length) {
  290. return errors.New("len of data < Adaptation_field_length")
  291. }
  292. if adaptation.Adaptation_field_length == 0 {
  293. return nil
  294. }
  295. adaptation.Discontinuity_indicator = bs.GetBit()
  296. adaptation.Random_access_indicator = bs.GetBit()
  297. adaptation.Elementary_stream_priority_indicator = bs.GetBit()
  298. adaptation.PCR_flag = bs.GetBit()
  299. adaptation.OPCR_flag = bs.GetBit()
  300. adaptation.Splicing_point_flag = bs.GetBit()
  301. adaptation.Transport_private_data_flag = bs.GetBit()
  302. adaptation.Adaptation_field_extension_flag = bs.GetBit()
  303. if adaptation.PCR_flag == 1 {
  304. adaptation.Program_clock_reference_base = bs.GetBits(33)
  305. bs.SkipBits(6)
  306. adaptation.Program_clock_reference_extension = uint16(bs.GetBits(9))
  307. }
  308. if adaptation.OPCR_flag == 1 {
  309. adaptation.Original_program_clock_reference_base = bs.GetBits(33)
  310. bs.SkipBits(6)
  311. adaptation.Original_program_clock_reference_extension = uint16(bs.GetBits(9))
  312. }
  313. if adaptation.Splicing_point_flag == 1 {
  314. adaptation.Splice_countdown = bs.Uint8(8)
  315. }
  316. if adaptation.Transport_private_data_flag == 1 {
  317. adaptation.Transport_private_data_length = bs.Uint8(8)
  318. bs.SkipBits(8 * int(adaptation.Transport_private_data_length))
  319. }
  320. if adaptation.Adaptation_field_extension_flag == 1 {
  321. adaptation.Adaptation_field_extension_length = bs.Uint8(8)
  322. bs.Markdot()
  323. adaptation.Ltw_flag = bs.GetBit()
  324. adaptation.Piecewise_rate_flag = bs.GetBit()
  325. adaptation.Seamless_splice_flag = bs.GetBit()
  326. bs.SkipBits(5)
  327. if adaptation.Ltw_flag == 1 {
  328. adaptation.Ltw_valid_flag = bs.GetBit()
  329. adaptation.Ltw_offset = uint16(bs.GetBits(15))
  330. }
  331. if adaptation.Piecewise_rate_flag == 1 {
  332. bs.SkipBits(2)
  333. adaptation.Piecewise_rate = uint32(bs.GetBits(22))
  334. }
  335. if adaptation.Seamless_splice_flag == 1 {
  336. adaptation.Splice_type = uint8(bs.GetBits(4))
  337. adaptation.DTS_next_AU = bs.GetBits(3)
  338. bs.SkipBits(1)
  339. adaptation.DTS_next_AU = adaptation.DTS_next_AU<<15 | bs.GetBits(15)
  340. bs.SkipBits(1)
  341. adaptation.DTS_next_AU = adaptation.DTS_next_AU<<15 | bs.GetBits(15)
  342. bs.SkipBits(1)
  343. }
  344. bitscount := bs.DistanceFromMarkDot()
  345. if bitscount%8 > 0 {
  346. panic("maybe parser ts file failed")
  347. }
  348. bs.SkipBits(int(adaptation.Adaptation_field_extension_length*8 - uint8(bitscount)))
  349. }
  350. endoffset := bs.ByteOffset()
  351. bs.SkipBits((int(adaptation.Adaptation_field_length) - (endoffset - startoffset)) * 8)
  352. return nil
  353. }
  354. type PmtPair struct {
  355. Program_number uint16
  356. PID uint16
  357. }
  358. type Pat struct {
  359. Table_id uint8 //8 uimsbf
  360. Section_syntax_indicator uint8 //1 bslbf
  361. Section_length uint16 //12 uimsbf
  362. Transport_stream_id uint16 //16 uimsbf
  363. Version_number uint8 //5 uimsbf
  364. Current_next_indicator uint8 //1 bslbf
  365. Section_number uint8 //8 uimsbf
  366. Last_section_number uint8 //8 uimsbf
  367. Pmts []PmtPair
  368. }
  369. func NewPat() *Pat {
  370. return &Pat{
  371. Table_id: uint8(TS_TID_PAS),
  372. Pmts: make([]PmtPair, 0, 8),
  373. }
  374. }
  375. func (pat *Pat) PrettyPrint(file *os.File) {
  376. file.WriteString(fmt.Sprintf("Table id:%d\n", pat.Table_id))
  377. file.WriteString(fmt.Sprintf("Section_syntax_indicator:%d\n", pat.Section_syntax_indicator))
  378. file.WriteString(fmt.Sprintf("Section_length:%d\n", pat.Section_length))
  379. file.WriteString(fmt.Sprintf("Transport_stream_id:%d\n", pat.Transport_stream_id))
  380. file.WriteString(fmt.Sprintf("Version_number:%d\n", pat.Version_number))
  381. file.WriteString(fmt.Sprintf("Current_next_indicator:%d\n", pat.Current_next_indicator))
  382. file.WriteString(fmt.Sprintf("Section_number:%d\n", pat.Section_number))
  383. file.WriteString(fmt.Sprintf("Last_section_number:%d\n", pat.Last_section_number))
  384. for i, pmt := range pat.Pmts {
  385. file.WriteString(fmt.Sprintf("----pmt %d\n", i))
  386. file.WriteString(fmt.Sprintf(" program_number:%d\n", pmt.Program_number))
  387. if pmt.Program_number == 0x0000 {
  388. file.WriteString(fmt.Sprintf(" network_PID:%d\n", pmt.PID))
  389. } else {
  390. file.WriteString(fmt.Sprintf(" program_map_PID:%d\n", pmt.PID))
  391. }
  392. }
  393. }
  394. func (pat *Pat) Encode(bsw *codec.BitStreamWriter) {
  395. bsw.PutUint8(0x00, 8)
  396. loc := bsw.ByteOffset()
  397. bsw.PutUint8(pat.Section_syntax_indicator, 1)
  398. bsw.PutUint8(0x00, 1)
  399. bsw.PutUint8(0x03, 2)
  400. bsw.PutUint16(0, 12)
  401. bsw.Markdot()
  402. bsw.PutUint16(pat.Transport_stream_id, 16)
  403. bsw.PutUint8(0x03, 2)
  404. bsw.PutUint8(pat.Version_number, 5)
  405. bsw.PutUint8(pat.Current_next_indicator, 1)
  406. bsw.PutUint8(pat.Section_number, 8)
  407. bsw.PutUint8(pat.Last_section_number, 8)
  408. for _, pms := range pat.Pmts {
  409. bsw.PutUint16(pms.Program_number, 16)
  410. bsw.PutUint8(0x07, 3)
  411. bsw.PutUint16(pms.PID, 13)
  412. }
  413. length := bsw.DistanceFromMarkDot()
  414. //|Section_syntax_indicator|'0'|reserved|Section_length|
  415. pat.Section_length = uint16(length)/8 + 4
  416. bsw.SetUint16(pat.Section_length&0x0FFF|(uint16(pat.Section_syntax_indicator)<<15)|0x3000, loc)
  417. crc := codec.CalcCrc32(0xffffffff, bsw.Bits()[bsw.ByteOffset()-int(pat.Section_length-4)-3:bsw.ByteOffset()])
  418. tmpcrc := make([]byte, 4)
  419. binary.LittleEndian.PutUint32(tmpcrc, crc)
  420. bsw.PutBytes(tmpcrc)
  421. }
  422. func (pat *Pat) Decode(bs *codec.BitStream) error {
  423. pat.Table_id = bs.Uint8(8)
  424. if pat.Table_id != uint8(TS_TID_PAS) {
  425. return errors.New("table id is Not TS_TID_PAS")
  426. }
  427. pat.Section_syntax_indicator = bs.Uint8(1)
  428. bs.SkipBits(3)
  429. pat.Section_length = bs.Uint16(12)
  430. pat.Transport_stream_id = bs.Uint16(16)
  431. bs.SkipBits(2)
  432. pat.Version_number = bs.Uint8(5)
  433. pat.Current_next_indicator = bs.Uint8(1)
  434. pat.Section_number = bs.Uint8(8)
  435. pat.Last_section_number = bs.Uint8(8)
  436. for i := 0; i+4 <= int(pat.Section_length)-5-4; i = i + 4 {
  437. tmp := PmtPair{
  438. Program_number: 0,
  439. PID: 0,
  440. }
  441. tmp.Program_number = bs.Uint16(16)
  442. bs.SkipBits(3)
  443. tmp.PID = bs.Uint16(13)
  444. pat.Pmts = append(pat.Pmts, tmp)
  445. }
  446. return nil
  447. }
  448. type StreamPair struct {
  449. StreamType uint8 //8 uimsbf
  450. Elementary_PID uint16 //13 uimsbf
  451. ES_Info_Length uint16 //12 uimsbf
  452. }
  453. type Pmt struct {
  454. Table_id uint8 //8 uimsbf
  455. Section_syntax_indicator uint8 //1 bslbf
  456. Section_length uint16 //12 uimsbf
  457. Program_number uint16 //16 uimsbf
  458. Version_number uint8 //5 uimsbf
  459. Current_next_indicator uint8 //1 bslbf
  460. Section_number uint8 //8 uimsbf
  461. Last_section_number uint8 //8 uimsbf
  462. PCR_PID uint16 //13 uimsbf
  463. Program_info_length uint16 //12 uimsbf
  464. Streams []StreamPair
  465. }
  466. func NewPmt() *Pmt {
  467. return &Pmt{
  468. Table_id: uint8(TS_TID_PMS),
  469. Streams: make([]StreamPair, 0, 8),
  470. }
  471. }
  472. func (pmt *Pmt) PrettyPrint(file *os.File) {
  473. file.WriteString(fmt.Sprintf("Table id:%d\n", pmt.Table_id))
  474. file.WriteString(fmt.Sprintf("Section_syntax_indicator:%d\n", pmt.Section_syntax_indicator))
  475. file.WriteString(fmt.Sprintf("Section_length:%d\n", pmt.Section_length))
  476. file.WriteString(fmt.Sprintf("Program_number:%d\n", pmt.Program_number))
  477. file.WriteString(fmt.Sprintf("Version_number:%d\n", pmt.Version_number))
  478. file.WriteString(fmt.Sprintf("Current_next_indicator:%d\n", pmt.Current_next_indicator))
  479. file.WriteString(fmt.Sprintf("Section_number:%d\n", pmt.Section_number))
  480. file.WriteString(fmt.Sprintf("Last_section_number:%d\n", pmt.Last_section_number))
  481. file.WriteString(fmt.Sprintf("PCR_PID:%d\n", pmt.PCR_PID))
  482. file.WriteString(fmt.Sprintf("program_info_length:%d\n", pmt.Program_info_length))
  483. for i, stream := range pmt.Streams {
  484. file.WriteString(fmt.Sprintf("----stream %d\n", i))
  485. if stream.StreamType == uint8(TS_STREAM_AAC) {
  486. file.WriteString(" stream_type:AAC\n")
  487. } else if stream.StreamType == uint8(TS_STREAM_H264) {
  488. file.WriteString(" stream_type:H264\n")
  489. } else if stream.StreamType == uint8(TS_STREAM_H265) {
  490. file.WriteString(" stream_type:H265\n")
  491. }
  492. file.WriteString(fmt.Sprintf(" elementary_PID:%d\n", stream.Elementary_PID))
  493. file.WriteString(fmt.Sprintf(" ES_info_length:%d\n", stream.ES_Info_Length))
  494. }
  495. }
  496. func (pmt *Pmt) Encode(bsw *codec.BitStreamWriter) {
  497. bsw.PutUint8(pmt.Table_id, 8)
  498. loc := bsw.ByteOffset()
  499. bsw.PutUint8(pmt.Section_syntax_indicator, 1)
  500. bsw.PutUint8(0x00, 1)
  501. bsw.PutUint8(0x03, 2)
  502. bsw.PutUint16(pmt.Section_length, 12)
  503. bsw.Markdot()
  504. bsw.PutUint16(pmt.Program_number, 16)
  505. bsw.PutUint8(0x03, 2)
  506. bsw.PutUint8(pmt.Version_number, 5)
  507. bsw.PutUint8(pmt.Current_next_indicator, 1)
  508. bsw.PutUint8(pmt.Section_number, 8)
  509. bsw.PutUint8(pmt.Last_section_number, 8)
  510. bsw.PutUint8(0x07, 3)
  511. bsw.PutUint16(pmt.PCR_PID, 13)
  512. bsw.PutUint8(0x0f, 4)
  513. //TODO Program info length
  514. bsw.PutUint16(0x0000 /*pmt.Program_info_length*/, 12)
  515. for _, stream := range pmt.Streams {
  516. bsw.PutUint8(stream.StreamType, 8)
  517. bsw.PutUint8(0x00, 3)
  518. bsw.PutUint16(stream.Elementary_PID, 13)
  519. bsw.PutUint8(0x00, 4)
  520. //TODO ES_info
  521. bsw.PutUint8(0 /*ES_info_length*/, 12)
  522. }
  523. length := bsw.DistanceFromMarkDot()
  524. pmt.Section_length = uint16(length)/8 + 4
  525. bsw.SetUint16(pmt.Section_length&0x0FFF|(uint16(pmt.Section_syntax_indicator)<<15)|0x3000, loc)
  526. crc := codec.CalcCrc32(0xffffffff, bsw.Bits()[bsw.ByteOffset()-int(pmt.Section_length-4)-3:bsw.ByteOffset()])
  527. tmpcrc := make([]byte, 4)
  528. binary.LittleEndian.PutUint32(tmpcrc, crc)
  529. bsw.PutBytes(tmpcrc)
  530. }
  531. func (pmt *Pmt) Decode(bs *codec.BitStream) error {
  532. pmt.Table_id = bs.Uint8(8)
  533. if pmt.Table_id != uint8(TS_TID_PMS) {
  534. return errors.New("table id is Not TS_TID_PAS")
  535. }
  536. pmt.Section_syntax_indicator = bs.Uint8(1)
  537. bs.SkipBits(3)
  538. pmt.Section_length = bs.Uint16(12)
  539. pmt.Program_number = bs.Uint16(16)
  540. bs.SkipBits(2)
  541. pmt.Version_number = bs.Uint8(5)
  542. pmt.Current_next_indicator = bs.Uint8(1)
  543. pmt.Section_number = bs.Uint8(8)
  544. pmt.Last_section_number = bs.Uint8(8)
  545. bs.SkipBits(3)
  546. pmt.PCR_PID = bs.Uint16(13)
  547. bs.SkipBits(4)
  548. pmt.Program_info_length = bs.Uint16(12)
  549. //TODO N loop descriptors
  550. bs.SkipBits(int(pmt.Program_info_length) * 8)
  551. //fmt.Printf("section length %d pmt.Pogram_info_length=%d\n", pmt.Section_length, pmt.Pogram_info_length)
  552. for i := 0; i < int(pmt.Section_length)-9-int(pmt.Program_info_length)-4; {
  553. tmp := StreamPair{
  554. StreamType: 0,
  555. Elementary_PID: 0,
  556. ES_Info_Length: 0,
  557. }
  558. tmp.StreamType = bs.Uint8(8)
  559. bs.SkipBits(3)
  560. tmp.Elementary_PID = bs.Uint16(13)
  561. bs.SkipBits(4)
  562. tmp.ES_Info_Length = bs.Uint16(12)
  563. //TODO N loop descriptors
  564. bs.SkipBits(int(tmp.ES_Info_Length) * 8)
  565. pmt.Streams = append(pmt.Streams, tmp)
  566. i += 5 + int(tmp.ES_Info_Length)
  567. }
  568. return nil
  569. }