123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- package mpeg2
- import (
- "encoding/binary"
- "fmt"
- "os"
- "github.com/yapingcat/gomedia/codec"
- )
- type Error interface {
- NeedMore() bool
- ParserError() bool
- StreamIdNotFound() bool
- }
- var errNeedMore error = &needmoreError{}
- type needmoreError struct{}
- func (e *needmoreError) Error() string { return "need more bytes" }
- func (e *needmoreError) NeedMore() bool { return true }
- func (e *needmoreError) ParserError() bool { return false }
- func (e *needmoreError) StreamIdNotFound() bool { return false }
- var errParser error = &parserError{}
- type parserError struct{}
- func (e *parserError) Error() string { return "parser packet error" }
- func (e *parserError) NeedMore() bool { return false }
- func (e *parserError) ParserError() bool { return true }
- func (e *parserError) StreamIdNotFound() bool { return false }
- var errNotFound error = &sidNotFoundError{}
- type sidNotFoundError struct{}
- func (e *sidNotFoundError) Error() string { return "stream id not found" }
- func (e *sidNotFoundError) NeedMore() bool { return false }
- func (e *sidNotFoundError) ParserError() bool { return false }
- func (e *sidNotFoundError) StreamIdNotFound() bool { return true }
- type PS_STREAM_TYPE int
- const (
- PS_STREAM_UNKNOW PS_STREAM_TYPE = 0xFF
- PS_STREAM_AAC PS_STREAM_TYPE = 0x0F
- PS_STREAM_H264 PS_STREAM_TYPE = 0x1B
- PS_STREAM_H265 PS_STREAM_TYPE = 0x24
- PS_STREAM_G711A PS_STREAM_TYPE = 0x90
- PS_STREAM_G711U PS_STREAM_TYPE = 0x91
- )
- // Table 2-33 – Program Stream pack header
- // pack_header() {
- // pack_start_code 32 bslbf
- // '01' 2 bslbf
- // system_clock_reference_base [32..30] 3 bslbf
- // marker_bit 1 bslbf
- // system_clock_reference_base [29..15] 15 bslbf
- // marker_bit 1 bslbf
- // system_clock_reference_base [14..0] 15 bslbf
- // marker_bit 1 bslbf
- // system_clock_reference_extension 9 uimsbf
- // marker_bit 1 bslbf
- // program_mux_rate 22 uimsbf
- // marker_bit 1 bslbf
- // marker_bit 1 bslbf
- // reserved 5 bslbf
- // pack_stuffing_length 3 uimsbf
- // for (i = 0; i < pack_stuffing_length; i++) {
- // stuffing_byte 8 bslbf
- // }
- // if (nextbits() == system_header_start_code) {
- // system_header ()
- // }
- // }
- type PSPackHeader struct {
- IsMpeg1 bool
- System_clock_reference_base uint64 //33 bits
- System_clock_reference_extension uint16 //9 bits
- Program_mux_rate uint32 //22 bits
- Pack_stuffing_length uint8 //3 bitss
- }
- func (ps_pkg_hdr *PSPackHeader) PrettyPrint(file *os.File) {
- file.WriteString(fmt.Sprintf("IsMpeg1:%t\n", ps_pkg_hdr.IsMpeg1))
- file.WriteString(fmt.Sprintf("System_clock_reference_base:%d\n", ps_pkg_hdr.System_clock_reference_base))
- file.WriteString(fmt.Sprintf("System_clock_reference_extension:%d\n", ps_pkg_hdr.System_clock_reference_extension))
- file.WriteString(fmt.Sprintf("Program_mux_rate:%d\n", ps_pkg_hdr.Program_mux_rate))
- file.WriteString(fmt.Sprintf("Pack_stuffing_length:%d\n", ps_pkg_hdr.Pack_stuffing_length))
- }
- func (ps_pkg_hdr *PSPackHeader) Decode(bs *codec.BitStream) error {
- if bs.RemainBytes() < 5 {
- return errNeedMore
- }
- if bs.Uint32(32) != 0x000001BA {
- panic("ps header must start with 000001BA")
- }
- if bs.NextBits(2) == 0x01 { //mpeg2
- if bs.RemainBytes() < 10 {
- return errNeedMore
- }
- return ps_pkg_hdr.decodeMpeg2(bs)
- } else if bs.NextBits(4) == 0x02 { //mpeg1
- if bs.RemainBytes() < 8 {
- return errNeedMore
- }
- ps_pkg_hdr.IsMpeg1 = true
- return ps_pkg_hdr.decodeMpeg1(bs)
- } else {
- return errParser
- }
- }
- func (ps_pkg_hdr *PSPackHeader) decodeMpeg2(bs *codec.BitStream) error {
- bs.SkipBits(2)
- ps_pkg_hdr.System_clock_reference_base = bs.GetBits(3)
- bs.SkipBits(1)
- ps_pkg_hdr.System_clock_reference_base = ps_pkg_hdr.System_clock_reference_base<<15 | bs.GetBits(15)
- bs.SkipBits(1)
- ps_pkg_hdr.System_clock_reference_base = ps_pkg_hdr.System_clock_reference_base<<15 | bs.GetBits(15)
- bs.SkipBits(1)
- ps_pkg_hdr.System_clock_reference_extension = bs.Uint16(9)
- bs.SkipBits(1)
- ps_pkg_hdr.Program_mux_rate = bs.Uint32(22)
- bs.SkipBits(1)
- bs.SkipBits(1)
- bs.SkipBits(5)
- ps_pkg_hdr.Pack_stuffing_length = bs.Uint8(3)
- if bs.RemainBytes() < int(ps_pkg_hdr.Pack_stuffing_length) {
- bs.UnRead(10 * 8)
- return errNeedMore
- }
- bs.SkipBits(int(ps_pkg_hdr.Pack_stuffing_length) * 8)
- return nil
- }
- func (ps_pkg_hdr *PSPackHeader) decodeMpeg1(bs *codec.BitStream) error {
- bs.SkipBits(4)
- ps_pkg_hdr.System_clock_reference_base = bs.GetBits(3)
- bs.SkipBits(1)
- ps_pkg_hdr.System_clock_reference_base = ps_pkg_hdr.System_clock_reference_base<<15 | bs.GetBits(15)
- bs.SkipBits(1)
- ps_pkg_hdr.System_clock_reference_base = ps_pkg_hdr.System_clock_reference_base<<15 | bs.GetBits(15)
- bs.SkipBits(1)
- ps_pkg_hdr.System_clock_reference_extension = 1
- ps_pkg_hdr.Program_mux_rate = bs.Uint32(7)
- bs.SkipBits(1)
- ps_pkg_hdr.Program_mux_rate = ps_pkg_hdr.Program_mux_rate<<15 | bs.Uint32(15)
- bs.SkipBits(1)
- return nil
- }
- func (ps_pkg_hdr *PSPackHeader) Encode(bsw *codec.BitStreamWriter) {
- bsw.PutBytes([]byte{0x00, 0x00, 0x01, 0xBA})
- bsw.PutUint8(1, 2)
- bsw.PutUint64(ps_pkg_hdr.System_clock_reference_base>>30, 3)
- bsw.PutUint8(1, 1)
- bsw.PutUint64(ps_pkg_hdr.System_clock_reference_base>>15, 15)
- bsw.PutUint8(1, 1)
- bsw.PutUint64(ps_pkg_hdr.System_clock_reference_base, 15)
- bsw.PutUint8(1, 1)
- bsw.PutUint16(ps_pkg_hdr.System_clock_reference_extension, 9)
- bsw.PutUint8(1, 1)
- bsw.PutUint32(ps_pkg_hdr.Program_mux_rate, 22)
- bsw.PutUint8(1, 1)
- bsw.PutUint8(1, 1)
- bsw.PutUint8(0x1F, 5)
- bsw.PutUint8(ps_pkg_hdr.Pack_stuffing_length, 3)
- bsw.PutRepetValue(0xFF, int(ps_pkg_hdr.Pack_stuffing_length))
- }
- type Elementary_Stream struct {
- Stream_id uint8
- P_STD_buffer_bound_scale uint8
- P_STD_buffer_size_bound uint16
- }
- func NewElementary_Stream(sid uint8) *Elementary_Stream {
- return &Elementary_Stream{
- Stream_id: sid,
- }
- }
- // system_header () {
- // system_header_start_code 32 bslbf
- // header_length 16 uimsbf
- // marker_bit 1 bslbf
- // rate_bound 22 uimsbf
- // marker_bit 1 bslbf
- // audio_bound 6 uimsbf
- // fixed_flag 1 bslbf
- // CSPS_flag 1 bslbf
- // system_audio_lock_flag 1 bslbf
- // system_video_lock_flag 1 bslbf
- // marker_bit 1 bslbf
- // video_bound 5 uimsbf
- // packet_rate_restriction_flag 1 bslbf
- // reserved_bits 7 bslbf
- // while (nextbits () == '1') {
- // stream_id 8 uimsbf
- // '11' 2 bslbf
- // P-STD_buffer_bound_scale 1 bslbf
- // P-STD_buffer_size_bound 13 uimsbf
- // }
- // }
- type System_header struct {
- Header_length uint16
- Rate_bound uint32
- Audio_bound uint8
- Fixed_flag uint8
- CSPS_flag uint8
- System_audio_lock_flag uint8
- System_video_lock_flag uint8
- Video_bound uint8
- Packet_rate_restriction_flag uint8
- Streams []*Elementary_Stream
- }
- func (sh *System_header) PrettyPrint(file *os.File) {
- file.WriteString(fmt.Sprintf("Header_length:%d\n", sh.Header_length))
- file.WriteString(fmt.Sprintf("Rate_bound:%d\n", sh.Rate_bound))
- file.WriteString(fmt.Sprintf("Audio_bound:%d\n", sh.Audio_bound))
- file.WriteString(fmt.Sprintf("Fixed_flag:%d\n", sh.Fixed_flag))
- file.WriteString(fmt.Sprintf("CSPS_flag:%d\n", sh.CSPS_flag))
- file.WriteString(fmt.Sprintf("System_audio_lock_flag:%d\n", sh.System_audio_lock_flag))
- file.WriteString(fmt.Sprintf("System_video_lock_flag:%d\n", sh.System_video_lock_flag))
- file.WriteString(fmt.Sprintf("Video_bound:%d\n", sh.Video_bound))
- file.WriteString(fmt.Sprintf("Packet_rate_restriction_flag:%d\n", sh.Packet_rate_restriction_flag))
- for i, es := range sh.Streams {
- file.WriteString(fmt.Sprintf("----streams %d\n", i))
- file.WriteString(fmt.Sprintf(" Stream_id:%d\n", es.Stream_id))
- file.WriteString(fmt.Sprintf(" P_STD_buffer_bound_scale:%d\n", es.P_STD_buffer_bound_scale))
- file.WriteString(fmt.Sprintf(" P_STD_buffer_size_bound:%d\n", es.P_STD_buffer_size_bound))
- }
- }
- func (sh *System_header) Encode(bsw *codec.BitStreamWriter) {
- bsw.PutBytes([]byte{0x00, 0x00, 0x01, 0xBB})
- loc := bsw.ByteOffset()
- bsw.PutUint16(0, 16)
- bsw.Markdot()
- bsw.PutUint8(1, 1)
- bsw.PutUint32(sh.Rate_bound, 22)
- bsw.PutUint8(1, 1)
- bsw.PutUint8(sh.Audio_bound, 6)
- bsw.PutUint8(sh.Fixed_flag, 1)
- bsw.PutUint8(sh.CSPS_flag, 1)
- bsw.PutUint8(sh.System_audio_lock_flag, 1)
- bsw.PutUint8(sh.System_video_lock_flag, 1)
- bsw.PutUint8(1, 1)
- bsw.PutUint8(sh.Video_bound, 5)
- bsw.PutUint8(sh.Packet_rate_restriction_flag, 1)
- bsw.PutUint8(0x7F, 7)
- for _, stream := range sh.Streams {
- bsw.PutUint8(stream.Stream_id, 8)
- bsw.PutUint8(3, 2)
- bsw.PutUint8(stream.P_STD_buffer_bound_scale, 1)
- bsw.PutUint16(stream.P_STD_buffer_size_bound, 13)
- }
- length := bsw.DistanceFromMarkDot() / 8
- bsw.SetUint16(uint16(length), loc)
- }
- func (sh *System_header) Decode(bs *codec.BitStream) error {
- if bs.RemainBytes() < 12 {
- return errNeedMore
- }
- if bs.Uint32(32) != 0x000001BB {
- panic("system header must start with 000001BB")
- }
- sh.Header_length = bs.Uint16(16)
- if bs.RemainBytes() < int(sh.Header_length) {
- bs.UnRead(6 * 8)
- return errNeedMore
- }
- if sh.Header_length < 6 || (sh.Header_length-6)%3 != 0 {
- return errParser
- }
- bs.SkipBits(1)
- sh.Rate_bound = bs.Uint32(22)
- bs.SkipBits(1)
- sh.Audio_bound = bs.Uint8(6)
- sh.Fixed_flag = bs.Uint8(1)
- sh.CSPS_flag = bs.Uint8(1)
- sh.System_audio_lock_flag = bs.Uint8(1)
- sh.System_video_lock_flag = bs.Uint8(1)
- bs.SkipBits(1)
- sh.Video_bound = bs.Uint8(5)
- sh.Packet_rate_restriction_flag = bs.Uint8(1)
- bs.SkipBits(7)
- sh.Streams = sh.Streams[:0]
- least := sh.Header_length - 6
- for least > 0 && bs.NextBits(1) == 0x01 {
- es := new(Elementary_Stream)
- es.Stream_id = bs.Uint8(8)
- bs.SkipBits(2)
- es.P_STD_buffer_bound_scale = bs.GetBit()
- es.P_STD_buffer_size_bound = bs.Uint16(13)
- sh.Streams = append(sh.Streams, es)
- least -= 3
- }
- if least > 0 {
- return errParser
- }
- return nil
- }
- type Elementary_stream_elem struct {
- Stream_type uint8
- Elementary_stream_id uint8
- Elementary_stream_info_length uint16
- }
- func NewElementary_stream_elem(stype uint8, esid uint8) *Elementary_stream_elem {
- return &Elementary_stream_elem{
- Stream_type: stype,
- Elementary_stream_id: esid,
- }
- }
- // program_stream_map() {
- // packet_start_code_prefix 24 bslbf
- // map_stream_id 8 uimsbf
- // program_stream_map_length 16 uimsbf
- // current_next_indicator 1 bslbf
- // reserved 2 bslbf
- // program_stream_map_version 5 uimsbf
- // reserved 7 bslbf
- // marker_bit 1 bslbf
- // program_stream_info_length 16 uimsbf
- // for (i = 0; i < N; i++) {
- // descriptor()
- // }
- // elementary_stream_map_length 16 uimsbf
- // for (i = 0; i < N1; i++) {
- // stream_type 8 uimsbf
- // elementary_stream_id 8 uimsbf
- // elementary_stream_info_length 16 uimsbf
- // for (i = 0; i < N2; i++) {
- // descriptor()
- // }
- // }
- // CRC_32 32 rpchof
- // }
- type Program_stream_map struct {
- Map_stream_id uint8
- Program_stream_map_length uint16
- Current_next_indicator uint8
- Program_stream_map_version uint8
- Program_stream_info_length uint16
- Elementary_stream_map_length uint16
- Stream_map []*Elementary_stream_elem
- }
- func (psm *Program_stream_map) PrettyPrint(file *os.File) {
- file.WriteString(fmt.Sprintf("map_stream_id:%d\n", psm.Map_stream_id))
- file.WriteString(fmt.Sprintf("program_stream_map_length:%d\n", psm.Program_stream_map_length))
- file.WriteString(fmt.Sprintf("current_next_indicator:%d\n", psm.Current_next_indicator))
- file.WriteString(fmt.Sprintf("program_stream_map_version:%d\n", psm.Program_stream_map_version))
- file.WriteString(fmt.Sprintf("program_stream_info_length:%d\n", psm.Program_stream_info_length))
- file.WriteString(fmt.Sprintf("elementary_stream_map_length:%d\n", psm.Elementary_stream_map_length))
- for i, es := range psm.Stream_map {
- file.WriteString(fmt.Sprintf("----ES stream %d\n", i))
- if es.Stream_type == uint8(PS_STREAM_AAC) {
- file.WriteString(" stream_type:AAC\n")
- } else if es.Stream_type == uint8(PS_STREAM_G711A) {
- file.WriteString(" stream_type:G711A\n")
- } else if es.Stream_type == uint8(PS_STREAM_G711U) {
- file.WriteString(" stream_type:G711U\n")
- } else if es.Stream_type == uint8(PS_STREAM_H264) {
- file.WriteString(" stream_type:H264\n")
- } else if es.Stream_type == uint8(PS_STREAM_H265) {
- file.WriteString(" stream_type:H265\n")
- }
- file.WriteString(fmt.Sprintf(" elementary_stream_id:%d\n", es.Elementary_stream_id))
- file.WriteString(fmt.Sprintf(" elementary_stream_info_length:%d\n", es.Elementary_stream_info_length))
- }
- }
- func (psm *Program_stream_map) Encode(bsw *codec.BitStreamWriter) {
- bsw.PutBytes([]byte{0x00, 0x00, 0x01, 0xBC})
- loc := bsw.ByteOffset()
- bsw.PutUint16(psm.Program_stream_map_length, 16)
- bsw.Markdot()
- bsw.PutUint8(psm.Current_next_indicator, 1)
- bsw.PutUint8(3, 2)
- bsw.PutUint8(psm.Program_stream_map_version, 5)
- bsw.PutUint8(0x7F, 7)
- bsw.PutUint8(1, 1)
- bsw.PutUint16(0, 16)
- psm.Elementary_stream_map_length = uint16(len(psm.Stream_map) * 4)
- bsw.PutUint16(psm.Elementary_stream_map_length, 16)
- for _, streaminfo := range psm.Stream_map {
- bsw.PutUint8(streaminfo.Stream_type, 8)
- bsw.PutUint8(streaminfo.Elementary_stream_id, 8)
- bsw.PutUint16(0, 16)
- }
- length := bsw.DistanceFromMarkDot()/8 + 4
- bsw.SetUint16(uint16(length), loc)
- crc := codec.CalcCrc32(0xffffffff, bsw.Bits()[bsw.ByteOffset()-int(length-4)-4:bsw.ByteOffset()])
- tmpcrc := make([]byte, 4)
- binary.LittleEndian.PutUint32(tmpcrc, crc)
- bsw.PutBytes(tmpcrc)
- }
- func (psm *Program_stream_map) Decode(bs *codec.BitStream) error {
- if bs.RemainBytes() < 16 {
- return errNeedMore
- }
- if bs.Uint32(24) != 0x000001 {
- panic("program stream map must startwith 0x000001")
- }
- psm.Map_stream_id = bs.Uint8(8)
- if psm.Map_stream_id != 0xBC {
- panic("map stream id must be 0xBC")
- }
- psm.Program_stream_map_length = bs.Uint16(16)
- if bs.RemainBytes() < int(psm.Program_stream_map_length) {
- bs.UnRead(6 * 8)
- return errNeedMore
- }
- psm.Current_next_indicator = bs.Uint8(1)
- bs.SkipBits(2)
- psm.Program_stream_map_version = bs.Uint8(5)
- bs.SkipBits(8)
- psm.Program_stream_info_length = bs.Uint16(16)
- if bs.RemainBytes() < int(psm.Program_stream_info_length)+2 {
- bs.UnRead(10 * 8)
- return errNeedMore
- }
- bs.SkipBits(int(psm.Program_stream_info_length) * 8)
- psm.Elementary_stream_map_length = bs.Uint16(16)
- if psm.Program_stream_map_length != 6+psm.Program_stream_info_length+psm.Elementary_stream_map_length+4 {
- return errParser
- }
- if bs.RemainBytes() < int(psm.Elementary_stream_map_length)+4 {
- bs.UnRead(12*8 + int(psm.Program_stream_info_length)*8)
- return errNeedMore
- }
- i := 0
- psm.Stream_map = psm.Stream_map[:0]
- for i < int(psm.Elementary_stream_map_length) {
- elem := new(Elementary_stream_elem)
- elem.Stream_type = bs.Uint8(8)
- elem.Elementary_stream_id = bs.Uint8(8)
- elem.Elementary_stream_info_length = bs.Uint16(16)
- //TODO Parser descriptor
- if bs.RemainBytes() < int(elem.Elementary_stream_info_length) {
- return errParser
- }
- bs.SkipBits(int(elem.Elementary_stream_info_length) * 8)
- i += int(4 + elem.Elementary_stream_info_length)
- psm.Stream_map = append(psm.Stream_map, elem)
- }
- if i != int(psm.Elementary_stream_map_length) {
- return errParser
- }
- bs.SkipBits(32)
- return nil
- }
- type Program_stream_directory struct {
- PES_packet_length uint16
- }
- func (psd *Program_stream_directory) Decode(bs *codec.BitStream) error {
- if bs.RemainBytes() < 6 {
- return errNeedMore
- }
- if bs.Uint32(32) != 0x000001FF {
- panic("program stream directory 000001FF")
- }
- psd.PES_packet_length = bs.Uint16(16)
- if bs.RemainBytes() < int(psd.PES_packet_length) {
- bs.UnRead(6 * 8)
- return errNeedMore
- }
- //TODO Program Stream directory
- bs.SkipBits(int(psd.PES_packet_length) * 8)
- return nil
- }
- type CommonPesPacket struct {
- Stream_id uint8
- PES_packet_length uint16
- }
- func (compes *CommonPesPacket) Decode(bs *codec.BitStream) error {
- if bs.RemainBytes() < 6 {
- return errNeedMore
- }
- bs.SkipBits(24)
- compes.Stream_id = bs.Uint8(8)
- compes.PES_packet_length = bs.Uint16(16)
- if bs.RemainBytes() < int(compes.PES_packet_length) {
- bs.UnRead(6 * 8)
- return errNeedMore
- }
- bs.SkipBits(int(compes.PES_packet_length) * 8)
- return nil
- }
- type PSPacket struct {
- Header *PSPackHeader
- System *System_header
- Psm *Program_stream_map
- Psd *Program_stream_directory
- CommPes *CommonPesPacket
- Pes *PesPacket
- }
|