mirror of https://bitbucket.org/ausocean/av.git
cmd/ts-repair: got setting of discontinuity indicators working and also adding adaptation fields to pat and pmt for this reason.
This commit is contained in:
parent
c7a9e0a06b
commit
72f0087b9a
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -15,25 +16,94 @@ const (
|
||||||
errCantGetPid = "Can't get pid from packet"
|
errCantGetPid = "Can't get pid from packet"
|
||||||
errReadFail = "Read failed"
|
errReadFail = "Read failed"
|
||||||
errWriteFail = "Write to file failed"
|
errWriteFail = "Write to file failed"
|
||||||
usage = "The path to the file to be repaired"
|
errBadMode = "Bad fix mode"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
inUsage = "The path to the file to be repaired"
|
||||||
|
outUsage = "Output file path"
|
||||||
|
modeUsage = "Fix mode: 0 = cc-shift, 1 = di-update"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ccShift = iota
|
||||||
|
diUpdate
|
||||||
)
|
)
|
||||||
|
|
||||||
var ccMap = map[int]byte{
|
var ccMap = map[int]byte{
|
||||||
mts.PatPid: 1,
|
mts.PatPid: 16,
|
||||||
mts.PmtPid: 1,
|
mts.PmtPid: 16,
|
||||||
mts.VideoPid: 0,
|
mts.VideoPid: 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var packetNo int
|
||||||
|
|
||||||
|
type Option func(p *Packet)
|
||||||
|
|
||||||
type Packet [mts.PacketSize]byte
|
type Packet [mts.PacketSize]byte
|
||||||
|
|
||||||
|
func (p *Packet) CC() byte {
|
||||||
|
return (*p)[3] & 0x0f
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Packet) setCC(cc byte) {
|
func (p *Packet) setCC(cc byte) {
|
||||||
(*p)[3] |= cc & 0xf
|
(*p)[3] |= cc & 0xf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Packet) setDI(di bool) {
|
||||||
|
if di {
|
||||||
|
p[5] |= 0x80
|
||||||
|
} else {
|
||||||
|
p[5] &= 0x7f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) addAdaptationField(options ...Option) {
|
||||||
|
// Create space for adaptation field
|
||||||
|
copy(p[mts.HeadSize+mts.DefaultAdaptationSize:], p[mts.HeadSize:len(p)-mts.DefaultAdaptationSize])
|
||||||
|
|
||||||
|
// TODO: seperate into own function
|
||||||
|
// Update adaptation field control
|
||||||
|
p[mts.AdaptationControlIdx] &= 0xff ^ mts.AdaptationControlMask
|
||||||
|
p[mts.AdaptationControlIdx] |= mts.AdaptationControlMask
|
||||||
|
// Default the adaptationfield
|
||||||
|
p.resetAdaptation()
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
option(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) resetAdaptation() {
|
||||||
|
p[mts.AdaptationIdx] = mts.DefaultAdaptationBodySize
|
||||||
|
p[mts.AdaptationBodyIdx] = 0x00
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) hasAdaptation() bool {
|
||||||
|
afc := p[mts.AdaptationControlIdx] & mts.AdaptationControlMask
|
||||||
|
if afc == 0x20 || afc == 0x30 {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DiscontinuityIndicator(f bool) Option {
|
||||||
|
return func(p *Packet) {
|
||||||
|
set := byte(mts.DiscontinuityIndicatorMask)
|
||||||
|
if !f {
|
||||||
|
set = 0x00
|
||||||
|
}
|
||||||
|
p[mts.DiscontinuityIndicatorIdx] &= 0xff ^ mts.DiscontinuityIndicatorMask
|
||||||
|
p[mts.DiscontinuityIndicatorIdx] |= mts.DiscontinuityIndicatorMask & set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Deal with input flags
|
// Deal with input flags
|
||||||
inPtr := flag.String("path", "", usage)
|
inPtr := flag.String("in", "", inUsage)
|
||||||
outPtr := flag.String("out", "out.ts", usage)
|
outPtr := flag.String("out", "out.ts", outUsage)
|
||||||
|
modePtr := flag.Int("mode", diUpdate, modeUsage)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// Try and open the given input file, otherwise panic - we can't do anything
|
// Try and open the given input file, otherwise panic - we can't do anything
|
||||||
|
@ -59,14 +129,42 @@ func main() {
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
panic(errReadFail + ": " + err.Error())
|
panic(errReadFail + ": " + err.Error())
|
||||||
}
|
}
|
||||||
|
packetNo++
|
||||||
// Get the pid from the packet and set the cc based on this pid using our map
|
// Get the pid from the packet and set the cc based on this pid using our map
|
||||||
pid, err := packet.Pid((*packet.Packet)(&p))
|
pid, err := packet.Pid((*packet.Packet)(&p))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errCantGetPid)
|
panic(errCantGetPid)
|
||||||
}
|
}
|
||||||
p.setCC(ccFor(int(pid)))
|
|
||||||
|
|
||||||
|
cc := p.CC()
|
||||||
|
expect, exists := expectedCC(int(pid))
|
||||||
|
if !exists {
|
||||||
|
updateCCMap(int(pid), cc)
|
||||||
|
} else {
|
||||||
|
switch *modePtr {
|
||||||
|
case ccShift:
|
||||||
|
p.setCC(expect)
|
||||||
|
|
||||||
|
case diUpdate:
|
||||||
|
|
||||||
|
if cc != expect {
|
||||||
|
fmt.Printf("packetNo: %v pid: %v, cc: %v, expect: %v\n", packetNo, pid, cc, expect)
|
||||||
|
if p.hasAdaptation() {
|
||||||
|
fmt.Println("hasAdaptation")
|
||||||
|
p.setDI(true)
|
||||||
|
} else {
|
||||||
|
fmt.Println("doesn't have adaptation")
|
||||||
|
fmt.Println(p)
|
||||||
|
p.addAdaptationField(DiscontinuityIndicator(true))
|
||||||
|
fmt.Println(p)
|
||||||
|
}
|
||||||
|
updateCCMap(int(pid), p.CC())
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic(errBadMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
// Write this packet to the output file
|
// Write this packet to the output file
|
||||||
if _, err := outFile.Write(p[:]); err != nil {
|
if _, err := outFile.Write(p[:]); err != nil {
|
||||||
panic(errWriteFail + ": " + err.Error())
|
panic(errWriteFail + ": " + err.Error())
|
||||||
|
@ -75,8 +173,15 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ccFor gets the next cc for the given pid
|
// ccFor gets the next cc for the given pid
|
||||||
func ccFor(pid int) byte {
|
func expectedCC(pid int) (byte, bool) {
|
||||||
cc := ccMap[pid]
|
cc := ccMap[pid]
|
||||||
|
if cc == 16 {
|
||||||
|
return 16, false
|
||||||
|
}
|
||||||
|
ccMap[pid] = (cc + 1) & 0xf
|
||||||
|
return cc, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCCMap(pid int, cc byte) {
|
||||||
ccMap[pid] = (cc + 1) & 0xf
|
ccMap[pid] = (cc + 1) & 0xf
|
||||||
return cc
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue