-
Notifications
You must be signed in to change notification settings - Fork 1
/
PcrBrCommenter.go
66 lines (57 loc) · 1.7 KB
/
PcrBrCommenter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package main
import (
"fmt"
"log"
)
// PcrBrCommenter measures the bitrate of the
// stream passing through it using the specified
// PCR PID. This is an "offline" method. The current
// bitrate will be recorded in the packet comment.
type PcrBrCommenter struct {
PcrPid int
LastPcr int64
lastPktCnt int64
CurBr float64
TsNode
}
//register with global AvailableNodes map
func init() {
AvailableNodes.Register("PcrBrCommenter", NewPcrBrCommenter)
}
func NewPcrBrCommenter(pcrPid int) (*PcrBrCommenter, error) {
node := &PcrBrCommenter{}
node.PcrPid = pcrPid
node.LastPcr = -MAX_PCR_STEP - 1 // sentinel to detect first run
node.input = make(chan TsPacket, CHAN_BUF_SIZE)
go node.process()
return node, nil
}
func (node *PcrBrCommenter) process() {
defer node.closeDown()
for pkt := range node.input {
node.PktsIn++
if pkt.Header.Pid == node.PcrPid && (pkt.Header.Afc > 1) && pkt.AdaptationField.Pcrf {
// todo: don't just use the PCR base, use ext also
dPkt := float64(node.PktsIn - node.lastPktCnt)
dPcr := float64(pkt.AdaptationField.Pcrb - node.LastPcr)
if dPcr > MAX_PCR_STEP {
// if last PCR is negative, this is first run so discon expected
if node.LastPcr > 0 {
// pcr discon, resync
log.Printf("PCR jumps by more than 10 sec (%.0f ticks) in packet %d", dPcr, node.PktsIn)
}
} else {
node.CurBr = (dPkt * TS_PKT_SIZE * 8) / (dPcr / 90000.0)
pkt.Comment = fmt.Sprintf("%f", node.CurBr)
}
node.LastPcr = pkt.AdaptationField.Pcrb
node.lastPktCnt = node.PktsIn
}
node.Send(pkt)
}
}
func (node *PcrBrCommenter) closeDown() {
node.Active = false
log.Printf("closing down PcrBrCommenter on pcr pid %d", node.PcrPid)
node.output.Close()
}