av/pes/pes.go

124 lines
5.5 KiB
Go
Raw Normal View History

2017-12-20 05:31:05 +03:00
/*
NAME
pes.go -
2017-12-20 05:31:05 +03:00
DESCRIPTION
See Readme.md
AUTHOR
Saxon A. Nelson-Milton <saxon.milton@gmail.com>
2017-12-20 05:31:05 +03:00
LICENSE
pes.go is Copyright (C) 2017 the Australian Ocean Lab (AusOcean)
2017-12-20 05:31:05 +03:00
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
2017-12-20 05:31:05 +03:00
*/
package pes
import "bitbucket.org/ausocean/av/tools"
const maxPesSize = 10000
2018-01-07 06:46:10 +03:00
/*
The below data struct encapsulates the fields of an PES packet. Below is
the formatting of a PES packet for reference!
PES Packet Formatting
2018-01-07 06:46:10 +03:00
============================================================================
| octet no | bit 0 | bit 1 | bit 2 | bit 3 | bit 4 | bit 5 | bit 6 | bit 7 |
============================================================================
| octet 0 | 0x00 |
----------------------------------------------------------------------------
| octet 1 | 0x00 |
----------------------------------------------------------------------------
| octet 2 | 0x01 |
----------------------------------------------------------------------------
| octet 3 | Stream ID (0xE0 for video) |
----------------------------------------------------------------------------
2018-01-07 19:18:10 +03:00
| octet 4 | PES Packet Length (no of bytes in packet after this field) |
2018-01-07 06:46:10 +03:00
----------------------------------------------------------------------------
| octet 5 | PES Length cont. |
----------------------------------------------------------------------------
| octet 6 | 0x2 | SC | Prior | DAI | Copyr | Copy |
----------------------------------------------------------------------------
| octet 7 | PDI | ESCRF | ESRF | DSMTMF| ACIF | CRCF | EF |
----------------------------------------------------------------------------
| octet 8 | PES Header Length |
----------------------------------------------------------------------------
| optional | optional fields (determined by flags above) (variable Length) |
----------------------------------------------------------------------------
| - | ... |
----------------------------------------------------------------------------
| optional | stuffing bytes (varible length) |
----------------------------------------------------------------------------
| - | ... |
----------------------------------------------------------------------------
| Optional | Data (variable length) |
----------------------------------------------------------------------------
| - | ... |
----------------------------------------------------------------------------
*/
// TODO: add DSMTM, ACI, CRC, Ext fields
2017-12-20 05:31:05 +03:00
type PESPacket struct {
StreamID byte // Type of stream
Length uint16 // Pes packet length in bytes after this field
SC byte // Scrambling control
Priority bool // Priority Indicator
DAI bool // Data alginment indicator
Copyright bool // Copyright indicator
Original bool // Original data indicator
PDI byte // PTS DTS indicator
ESCRF bool // Elementary stream clock reference flag
ESRF bool // Elementary stream rate reference flag
DSMTMF bool // Dsm trick mode flag
ACIF bool // Additional copy info flag
CRCF bool // Not sure
EF bool // Extension flag
HeaderLength byte // Pes header length
PTS uint64 // Presentation time stamp
DTS uint64 // Decoding timestamp
ESCR uint64 // Elementary stream clock reference
ESR uint32 // Elementary stream rate reference
Stuff []byte // Stuffing bytes
Data []byte // Pes packet data
2017-12-20 05:31:05 +03:00
}
func (p *PESPacket) ToByteSlice() (output []byte) {
output = make([]byte, 0, maxPesSize)
output = append(output, []byte{
0x00, 0x00, 0x01,
p.StreamID,
byte((p.Length & 0xFF00) >> 8),
byte(p.Length & 0x00FF),
2018-01-07 19:18:10 +03:00
(0x2<<6 | p.SC<<4 | tools.BoolToByte(p.Priority)<<3 | tools.BoolToByte(p.DAI)<<2 |
tools.BoolToByte(p.Copyright)<<1 | tools.BoolToByte(p.Original)),
(p.PDI<<6 | tools.BoolToByte(p.ESCRF)<<5 | tools.BoolToByte(p.ESRF)<<4 | tools.BoolToByte(p.DSMTMF)<<3 |
tools.BoolToByte(p.ACIF)<<2 | tools.BoolToByte(p.CRCF)<<1 | tools.BoolToByte(p.EF)),
p.HeaderLength,
}...)
2018-01-07 19:18:10 +03:00
if p.PDI == byte(2) {
pts := 0x2100010001 | (p.PTS&0x1C0000000)<<3 | (p.PTS&0x3FFF8000)<<2 |
(p.PTS&0x7FFF)<<1
2018-01-07 19:18:10 +03:00
output = append(output, []byte{
byte((pts & 0xFF00000000) >> 32),
byte((pts & 0x00FF000000) >> 24),
byte((pts & 0x0000FF0000) >> 16),
byte((pts & 0x000000FF00) >> 8),
2018-01-07 19:18:10 +03:00
byte(pts & 0x00000000FF),
}...)
}
output = append(output, append(p.Stuff, p.Data...)...)
return
2017-12-20 05:31:05 +03:00
}