add WritePES/PSI
This commit is contained in:
parent
5680c3b102
commit
13160821be
17
checksum.go
17
checksum.go
@ -67,10 +67,6 @@ type Crc32Reader struct {
|
||||
|
||||
var debugCrc32 = false
|
||||
|
||||
func NewCrc32Reader(r io.Reader) *Crc32Reader {
|
||||
return &Crc32Reader{R: r, Crc32: 0xffffffff}
|
||||
}
|
||||
|
||||
func (self *Crc32Reader) Read(b []byte) (n int, err error) {
|
||||
if n, err = self.R.Read(b); err != nil {
|
||||
return
|
||||
@ -93,3 +89,16 @@ func (self *Crc32Reader) ReadCrc32UIntAndCheck() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
type Crc32Writer struct {
|
||||
W io.Writer
|
||||
Crc32 uint32
|
||||
}
|
||||
|
||||
func (self *Crc32Writer) Write(b []byte) (n int, err error) {
|
||||
if n, err = self.W.Write(b); err != nil {
|
||||
return
|
||||
}
|
||||
self.Crc32 = updateIeeeCrc32(self.Crc32, b)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err
|
||||
}
|
||||
}
|
||||
|
||||
cr = NewCrc32Reader(r)
|
||||
cr = &Crc32Reader{R: r, Crc32: 0xffffffff}
|
||||
|
||||
// table_id
|
||||
if self.TableId, err = ReadUInt(cr, 1); err != nil {
|
||||
@ -463,8 +463,8 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
|
||||
Length int
|
||||
Desc string
|
||||
}{
|
||||
{2, "PES_scrambling_control"},
|
||||
{1, "PES_priority"},
|
||||
{2, "scrambling_control"},
|
||||
{1, "priority"},
|
||||
{1, "data_alignment_indicator"},
|
||||
{1, "copyright"},
|
||||
{1, "original_or_copy"},
|
||||
|
5
ts.go
5
ts.go
@ -68,6 +68,11 @@ func PESUIntToTs(v uint64) (ts uint64) {
|
||||
return (((v>>33)&0x7)<<30) | (((v>>17)&0x7fff)<<15) | ((v>>1)&0x7fff)
|
||||
}
|
||||
|
||||
func PESTsToUInt(ts uint64) (v uint64) {
|
||||
// 0010 PTS 32..30 1 PTS 29..15 1 PTS 14..00 1
|
||||
return ((ts>>30)&0x7)<<33 | ((ts>>15)&0x7fff)<<17 | (v&0x7fff)<<1 | 0x100010001
|
||||
}
|
||||
|
||||
func UIntToPCR(v uint64) uint64 {
|
||||
// base(33)+resverd(6)+ext(9)
|
||||
base := v>>15
|
||||
|
155
writer.go
155
writer.go
@ -107,20 +107,157 @@ func WriteTSHeader(w io.Writer, self TSHeader) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
type PSIWriter struct {
|
||||
W *TSWriter
|
||||
}
|
||||
func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
|
||||
// pointer(8)
|
||||
// table_id(8)
|
||||
// reserved(4)=0xb,section_length(10)
|
||||
// Table ID extension(16)
|
||||
// resverd(2)=3,version(5),Current_next_indicator(1)
|
||||
// section_number(8)
|
||||
// last_section_number(8)
|
||||
// data
|
||||
// crc(32)
|
||||
|
||||
// pointer(8)
|
||||
if err = WriteUInt(w, 0, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cw := &Crc32Writer{W: w, Crc32: 0xffffffff}
|
||||
|
||||
// table_id(8)
|
||||
if err = WriteUInt(cw, self.TableId, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// reserved(4)=0xb,section_length(10)
|
||||
var flags, length uint
|
||||
length = 2+3+4+uint(len(data))
|
||||
flags = 0xb<<10|length
|
||||
if err = WriteUInt(cw, flags, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Table ID extension(16)
|
||||
if err = WriteUInt(cw, self.TableIdExtension, 2); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// resverd(2)=3,version(5)=0,Current_next_indicator(1)=1
|
||||
flags = 0x3<<6|1
|
||||
if err = WriteUInt(cw, flags, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// section_number(8)
|
||||
if err = WriteUInt(cw, self.SecNum, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// last_section_number(8)
|
||||
if err = WriteUInt(cw, self.LastSecNum, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// data
|
||||
if _, err = cw.Write(data); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// crc(32)
|
||||
if err = WriteUInt(w, uint(cw.Crc32), 4); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
func (self PSIWriter) Write(b []byte) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (self PSIWriter) Finish() (err error) {
|
||||
return
|
||||
}
|
||||
func WritePES(w io.Writer, self PESHeader, data []byte) (err error) {
|
||||
// http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
|
||||
|
||||
type PESWriter struct {
|
||||
W io.Writer
|
||||
var pts_dts_flags, header_length, packet_length uint
|
||||
|
||||
// start code(24) 000001
|
||||
// StreamId(8)
|
||||
// packet_length(16)
|
||||
// resverd(6,2)=2,original_or_copy(0,1)=1
|
||||
// pts_dts_flags(6,2)
|
||||
// header_length(8)
|
||||
// pts(40)?
|
||||
// dts(40)?
|
||||
// data
|
||||
|
||||
// start code(24) 000001
|
||||
if err = WriteUInt(w, 0x000001, 3); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// StreamId(8)
|
||||
if err = WriteUInt(w, self.StreamId, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
const PTS = 1<<7
|
||||
const DTS = 1<<6
|
||||
|
||||
if self.PTS != 0 {
|
||||
pts_dts_flags |= PTS
|
||||
if self.DTS != 0 {
|
||||
pts_dts_flags |= DTS
|
||||
}
|
||||
}
|
||||
|
||||
if pts_dts_flags & PTS != 0 {
|
||||
header_length += 5
|
||||
}
|
||||
if pts_dts_flags & DTS != 0 {
|
||||
header_length += 5
|
||||
}
|
||||
packet_length = 3+header_length+uint(len(data))
|
||||
|
||||
// packet_length(16)
|
||||
if err = WriteUInt(w, packet_length, 2); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// resverd(6,2)=2,original_or_copy(0,1)=1
|
||||
if err = WriteUInt(w, 2<<6|1, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// pts_dts_flags(6,2)
|
||||
if err = WriteUInt(w, pts_dts_flags, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// header_length(8)
|
||||
if err = WriteUInt(w, header_length, 1); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// pts(40)?
|
||||
// dts(40)?
|
||||
if pts_dts_flags & PTS != 0 {
|
||||
if pts_dts_flags & DTS != 0 {
|
||||
if err = WriteUInt64(w, PESTsToUInt(self.PTS)|3<<36, 5); err != nil {
|
||||
return
|
||||
}
|
||||
if err = WriteUInt64(w, PESTsToUInt(self.DTS)|1<<36, 5); err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = WriteUInt64(w, PESTsToUInt(self.PTS)|2<<36, 5); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// data
|
||||
if _, err = w.Write(data); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type SimpleH264Writer struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user