add WritePES/PSI

This commit is contained in:
nareix 2015-12-05 23:09:48 +08:00
parent 5680c3b102
commit 13160821be
4 changed files with 167 additions and 16 deletions

View File

@ -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
}

View File

@ -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
View File

@ -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
View File

@ -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 {