-
Notifications
You must be signed in to change notification settings - Fork 226
/
mpeg_pes.go
81 lines (65 loc) · 1.56 KB
/
mpeg_pes.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package mpeg
// TODO: probeable?
// http://dvdnav.mplayerhq.hu/dvdinfo/mpeghdrs.html
import (
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
)
var pesPacketGroup decode.Group
var mpegSpuGroup decode.Group
func init() {
interp.RegisterFormat(
format.MPES_PES,
&decode.Format{
Description: "MPEG Packetized elementary stream",
DecodeFn: pesDecode,
RootArray: true,
RootName: "packets",
Dependencies: []decode.Dependency{
{Groups: []*decode.Group{format.MPEG_PES_Packet}, Out: &pesPacketGroup},
{Groups: []*decode.Group{format.MPEG_SPU}, Out: &mpegSpuGroup},
},
})
}
type subStream struct {
b []byte
l int
}
func pesDecode(d *decode.D) any {
substreams := map[int]*subStream{}
prefix := d.PeekUintBits(24)
if prefix != 0b0000_0000_0000_0000_0000_0001 {
d.Errorf("no pes prefix found")
}
i := 0
spuD := d.FieldArrayValue("spus")
for d.NotEnd() {
dv, v, err := d.TryFieldFormat("packet", &pesPacketGroup, nil)
if dv == nil || err != nil {
break
}
switch dvv := v.(type) {
case subStreamPacket:
s, ok := substreams[dvv.number]
if !ok {
s = &subStream{}
substreams[dvv.number] = s
}
s.b = append(s.b, dvv.buf...)
if s.l == 0 && len(s.b) >= 2 {
s.l = int(s.b[0])<<8 | int(s.b[1])
// TODO: zero l?
}
// TODO: is this how spu end is signalled?
if s.l == len(s.b) {
spuD.FieldFormatBitBuf("spu", bitio.NewBitReader(s.b, -1), &mpegSpuGroup, nil)
s.b = nil
s.l = 0
}
}
i++
}
return nil
}