1
1
mirror of https://github.com/wader/fq.git synced 2024-12-24 05:41:38 +03:00
fq/format/mpeg/mpeg_pes.go

85 lines
1.7 KiB
Go
Raw Normal View History

2020-06-08 03:29:51 +03:00
package mpeg
// TODO: probeable?
// http://dvdnav.mplayerhq.hu/dvdinfo/mpeghdrs.html
import (
"log"
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/decode"
2020-06-08 03:29:51 +03:00
)
var pesPacketFormat decode.Group
var spuFormat decode.Group
2020-06-08 03:29:51 +03:00
func init() {
registry.MustRegister(decode.Format{
2020-06-08 03:29:51 +03:00
Name: format.MPEG_PES,
Description: "MPEG Packetized elementary stream",
DecodeFn: pesDecode,
RootArray: true,
2021-09-16 17:26:31 +03:00
RootName: "packets",
2020-06-08 03:29:51 +03:00
Dependencies: []decode.Dependency{
{Names: []string{format.MPEG_PES_PACKET}, Group: &pesPacketFormat},
{Names: []string{format.MPEG_SPU}, Group: &spuFormat},
2020-06-08 03:29:51 +03:00
},
})
}
type subStream struct {
b []byte
l int
}
func pesDecode(d *decode.D, in interface{}) interface{} {
substreams := map[int]*subStream{}
prefix := d.PeekBits(24)
if prefix != 0b0000_0000_0000_0000_0000_0001 {
d.Errorf("no pes prefix found")
2020-06-08 03:29:51 +03:00
}
i := 0
spuD := d.FieldArrayValue("spus")
2020-06-08 03:29:51 +03:00
2021-09-16 17:26:31 +03:00
for d.NotEnd() {
dv, v, err := d.TryFieldFormat("packet", pesPacketFormat, nil)
2021-09-16 17:26:31 +03:00
if dv == nil || err != nil {
log.Printf("errs[0]: %#+v\n", err)
break
}
switch dvv := v.(type) {
case subStreamPacket:
s, ok := substreams[dvv.number]
if !ok {
s = &subStream{}
substreams[dvv.number] = s
2020-06-08 03:29:51 +03:00
}
2021-09-16 17:26:31 +03:00
b, _ := dvv.bb.BytesRange(0, int(dvv.bb.Len()/8))
s.b = append(s.b, b...)
2020-06-08 03:29:51 +03:00
2021-09-16 17:26:31 +03:00
if s.l == 0 && len(b) >= 2 {
s.l = int(b[0])<<8 | int(b[1])
// TODO: zero l?
2020-06-08 03:29:51 +03:00
}
2021-09-16 17:26:31 +03:00
// TODO: is this how spu end is signalled?
if s.l == len(s.b) {
spuD.FieldFormatBitBuf("spu", bitio.NewBufferFromBytes(s.b, -1), spuFormat, nil)
s.b = nil
s.l = 0
}
2020-06-08 03:29:51 +03:00
}
2021-09-16 17:26:31 +03:00
i++
}
2020-06-08 03:29:51 +03:00
return nil
}