commit - c5209d277a60973090abb0eaa9363428b111400f
commit + c29a1e336e2176394997df419f8e06635db3eefe
blob - e24725ee852538f5f5dd766c44b2dbe860f03d9c (mode 644)
blob + /dev/null
--- jxs/draft.txt
+++ /dev/null
-package main
-
-import (
- "rtp"
- "jxs"
-)
-
-func transmit(session *rtp.Session, payload chan *jxs.Payload) {
- for p := range payload {
- packets, err := jxs.Packets(p)
- if err != nil {
- log.Printf("payload to RTP packets: %v", err)
- continue
- }
- for _, packet := range packets {
- if err := session.Transmit(p); err != nil {
- log.Printf("transmit: %v", err)
- }
- }
- }
-}
-
-func main() {
- session, err := rtp.Dial("udp", "[::1]:5004")
- if err != nil {
- log.Fatal(err)
- }
-
- ch := make(chan *jxs.Payload)
- go transmit(session, ch)
-
- for i := 0; ; i++ {
- frame, err := jxs.DecodeFrame(os.Stdin)
- if errors.Is(err, io.EOF) {
- close(ch)
- break
- } else if err != nil {
- log.Fatal(err)
- }
- mtu := 1492 // typical network
- pus, err := jxs.Packetize(&frame, mtu)
- if err != nil {
- log.Fatal(err)
- }
- for j, pu := range pus {
- payload := &jxs.Payload{
- Header: &jxs.Header{
- Sequential: true,
- PacketMode: true,
- FrameCount: uint8(i),
- SEPCount: 0, // TODO(otl)
- PacketCount: j, // TODO(otl)
- },
- PacketizationUnit: &jxs.PacketizationUnit{
- frame.VideoBox,
- frame.ColorBox,
- },
- },
- ch <- payload
- }
- }
-}
-
-
blob - 6d43e03986813e0eca0e95d9dc0653f003cfe8ef (mode 644)
blob + /dev/null
--- jxs/jxs.go
+++ /dev/null
-package jxs
-
-const (
- codestreamStart uint16 = 0xff10
- codestreamEnd uint16 = 0xff11
-)
-
-type codestream struct {
- start uint16
- capabilities capabilities
-}
-
-type capabilities uint8
-
-const (
- starTetrixTransform capabilities = 1<<1 + iota
- quadraticTransform
- extendedTransform
- waveletDecomposition
- losslessDecode
- rawMode
-)
-
-type header struct {
- marker uint16
- length uint16
-}
blob - 87401eaeee3091c2f7e569fa61a53941cbb3055c (mode 644)
blob + /dev/null
--- jxs/payload.go
+++ /dev/null
-// Package jxs ... for transporting JPEG XS streams in RTP payloads
-// as specified in RFC 9134.
-package jxs
-
-import "encoding/binary"
-
-type ScanMode uint8
-
-const (
- ScanModeProgressive ScanMode = 0
- _
- ScanModeInterlacedFirst ScanMode = 0b00010000
- ScanModeInterlacedSecond = 0b00011000
-)
-
-/*
-type Payload struct {
- Header *Header
- PacketizationUnit *PacketizationUnit
-}
-
-type PacketizationUnit struct {
- VideoBox
- ColorBox
- // ...
-}
-*/
-
-type Header struct {
- // Sequential indicates whether packets are sent sequentially
- // or possibly out of order. may be sent out of order.
- Sequential bool
-
- // PacketMode indicates the packetization mode. If true,
- // codestream packetization is used. If false, slice
- // packetization is used and Sequential must be false.
- PacketMode bool
-
- // Last indicates whether the packet is the last packet of a
- // packetization unit.
- Last bool
-
- // InterlacedInfo specifies how the frame is scanned.
- InterlacedInfo ScanMode
-
- // FrameCount holds a 5-bit integer (modulo 32) identifying
- // the frame to which the packet belongs.
- FrameCount uint8
-
- // SEPCounter (Slice and Extended Packet counter)
- // holds an 11-bit integer which is interpreted differently
- // depending on the value of PacketMode.
- //
- // If the packetization mode is codestream, then SEPCounter is
- // incremented by 1 whenever PacketCounter overruns.
- //
- // If packetization mode is slice, then SEPCounter identifies
- // the slice (modulo 2047) to which the packet contributes.
- SEPCount uint16
-
- // PacketCounter is an 11-bit integer identifying the packet number
- // within the current packetization unit.
- PacketCount uint16
-}
-
-func unmarshalHeader(a [4]byte, hdr Header) error {
- hdr.Sequential = a[0]&0b10000000 > 0
- hdr.PacketMode = a[0]&0b01000000 > 0
- hdr.Last = a[0]&0b00100000 > 0
- hdr.InterlacedInfo = ScanMode(a[0] & 0b00011000)
-
- hdr.FrameCount = (a[0] & 0b00000111) << 2
- hdr.FrameCount |= ((a[1] & 0b11000000) >> 6)
-
- var sepc [2]byte
- sepc[0] = a[1] & 0b00111000 >> 3
- sepc[1] = a[1] & 0b00000111 << 5
- sepc[1] |= a[2] & 0b11111000 >> 3
- hdr.SEPCount = binary.BigEndian.Uint16(sepc[:])
-
- hdr.PacketCount = binary.BigEndian.Uint16([]byte{a[2] & 0b00000111, a[3]})
- return nil
-}
-
-func marshalHeader(hdr Header) [4]byte {
- var a [4]byte
- if hdr.Sequential {
- a[0] |= (1 << 7)
- }
- if hdr.PacketMode {
- a[0] |= (1 << 6)
- }
- if hdr.Last {
- a[0] |= (1 << 5)
- }
- a[0] |= byte(hdr.InterlacedInfo)
-
- // Need to pack the 5 bits in FrameCount across both a[0] and a[1].
- // Have 3 bits remaining in a[0].
- a[0] |= (hdr.FrameCount & 0b00011100) >> 2
- // Pack remaining 2 bits from FrameCount into left-most bits of a[1].
- a[1] = (hdr.FrameCount & 0b00000011) << 6
-
- // 6 bits remaining in a[1].
- // We have 11 bits in SEPCount to pack.
- b := make([]byte, 2)
- binary.BigEndian.PutUint16(b, hdr.SEPCount)
- a[1] |= (b[0] & 0b00000111) << 3
- // 3 bits remaining in a[1], so get next 3 bits from b.
- a[1] |= (b[1] & 0b11100000) >> 5
-
- // 5 bits remaining in b.
- a[2] = (b[1] & 0b00011111) << 3
-
- b[0] = 0
- b[1] = 0
- binary.BigEndian.PutUint16(b, hdr.PacketCount)
- // 3 bits spare in a[2].
- a[2] |= (b[0] & 0b00000111)
- a[3] = b[1]
- return a
-}
blob - /dev/null
blob + e24725ee852538f5f5dd766c44b2dbe860f03d9c (mode 644)
--- /dev/null
+++ internal/jxs/draft.txt
+package main
+
+import (
+ "rtp"
+ "jxs"
+)
+
+func transmit(session *rtp.Session, payload chan *jxs.Payload) {
+ for p := range payload {
+ packets, err := jxs.Packets(p)
+ if err != nil {
+ log.Printf("payload to RTP packets: %v", err)
+ continue
+ }
+ for _, packet := range packets {
+ if err := session.Transmit(p); err != nil {
+ log.Printf("transmit: %v", err)
+ }
+ }
+ }
+}
+
+func main() {
+ session, err := rtp.Dial("udp", "[::1]:5004")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ ch := make(chan *jxs.Payload)
+ go transmit(session, ch)
+
+ for i := 0; ; i++ {
+ frame, err := jxs.DecodeFrame(os.Stdin)
+ if errors.Is(err, io.EOF) {
+ close(ch)
+ break
+ } else if err != nil {
+ log.Fatal(err)
+ }
+ mtu := 1492 // typical network
+ pus, err := jxs.Packetize(&frame, mtu)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for j, pu := range pus {
+ payload := &jxs.Payload{
+ Header: &jxs.Header{
+ Sequential: true,
+ PacketMode: true,
+ FrameCount: uint8(i),
+ SEPCount: 0, // TODO(otl)
+ PacketCount: j, // TODO(otl)
+ },
+ PacketizationUnit: &jxs.PacketizationUnit{
+ frame.VideoBox,
+ frame.ColorBox,
+ },
+ },
+ ch <- payload
+ }
+ }
+}
+
+
blob - /dev/null
blob + 6d43e03986813e0eca0e95d9dc0653f003cfe8ef (mode 644)
--- /dev/null
+++ internal/jxs/jxs.go
+package jxs
+
+const (
+ codestreamStart uint16 = 0xff10
+ codestreamEnd uint16 = 0xff11
+)
+
+type codestream struct {
+ start uint16
+ capabilities capabilities
+}
+
+type capabilities uint8
+
+const (
+ starTetrixTransform capabilities = 1<<1 + iota
+ quadraticTransform
+ extendedTransform
+ waveletDecomposition
+ losslessDecode
+ rawMode
+)
+
+type header struct {
+ marker uint16
+ length uint16
+}
blob - /dev/null
blob + 87401eaeee3091c2f7e569fa61a53941cbb3055c (mode 644)
--- /dev/null
+++ internal/jxs/payload.go
+// Package jxs ... for transporting JPEG XS streams in RTP payloads
+// as specified in RFC 9134.
+package jxs
+
+import "encoding/binary"
+
+type ScanMode uint8
+
+const (
+ ScanModeProgressive ScanMode = 0
+ _
+ ScanModeInterlacedFirst ScanMode = 0b00010000
+ ScanModeInterlacedSecond = 0b00011000
+)
+
+/*
+type Payload struct {
+ Header *Header
+ PacketizationUnit *PacketizationUnit
+}
+
+type PacketizationUnit struct {
+ VideoBox
+ ColorBox
+ // ...
+}
+*/
+
+type Header struct {
+ // Sequential indicates whether packets are sent sequentially
+ // or possibly out of order. may be sent out of order.
+ Sequential bool
+
+ // PacketMode indicates the packetization mode. If true,
+ // codestream packetization is used. If false, slice
+ // packetization is used and Sequential must be false.
+ PacketMode bool
+
+ // Last indicates whether the packet is the last packet of a
+ // packetization unit.
+ Last bool
+
+ // InterlacedInfo specifies how the frame is scanned.
+ InterlacedInfo ScanMode
+
+ // FrameCount holds a 5-bit integer (modulo 32) identifying
+ // the frame to which the packet belongs.
+ FrameCount uint8
+
+ // SEPCounter (Slice and Extended Packet counter)
+ // holds an 11-bit integer which is interpreted differently
+ // depending on the value of PacketMode.
+ //
+ // If the packetization mode is codestream, then SEPCounter is
+ // incremented by 1 whenever PacketCounter overruns.
+ //
+ // If packetization mode is slice, then SEPCounter identifies
+ // the slice (modulo 2047) to which the packet contributes.
+ SEPCount uint16
+
+ // PacketCounter is an 11-bit integer identifying the packet number
+ // within the current packetization unit.
+ PacketCount uint16
+}
+
+func unmarshalHeader(a [4]byte, hdr Header) error {
+ hdr.Sequential = a[0]&0b10000000 > 0
+ hdr.PacketMode = a[0]&0b01000000 > 0
+ hdr.Last = a[0]&0b00100000 > 0
+ hdr.InterlacedInfo = ScanMode(a[0] & 0b00011000)
+
+ hdr.FrameCount = (a[0] & 0b00000111) << 2
+ hdr.FrameCount |= ((a[1] & 0b11000000) >> 6)
+
+ var sepc [2]byte
+ sepc[0] = a[1] & 0b00111000 >> 3
+ sepc[1] = a[1] & 0b00000111 << 5
+ sepc[1] |= a[2] & 0b11111000 >> 3
+ hdr.SEPCount = binary.BigEndian.Uint16(sepc[:])
+
+ hdr.PacketCount = binary.BigEndian.Uint16([]byte{a[2] & 0b00000111, a[3]})
+ return nil
+}
+
+func marshalHeader(hdr Header) [4]byte {
+ var a [4]byte
+ if hdr.Sequential {
+ a[0] |= (1 << 7)
+ }
+ if hdr.PacketMode {
+ a[0] |= (1 << 6)
+ }
+ if hdr.Last {
+ a[0] |= (1 << 5)
+ }
+ a[0] |= byte(hdr.InterlacedInfo)
+
+ // Need to pack the 5 bits in FrameCount across both a[0] and a[1].
+ // Have 3 bits remaining in a[0].
+ a[0] |= (hdr.FrameCount & 0b00011100) >> 2
+ // Pack remaining 2 bits from FrameCount into left-most bits of a[1].
+ a[1] = (hdr.FrameCount & 0b00000011) << 6
+
+ // 6 bits remaining in a[1].
+ // We have 11 bits in SEPCount to pack.
+ b := make([]byte, 2)
+ binary.BigEndian.PutUint16(b, hdr.SEPCount)
+ a[1] |= (b[0] & 0b00000111) << 3
+ // 3 bits remaining in a[1], so get next 3 bits from b.
+ a[1] |= (b[1] & 0b11100000) >> 5
+
+ // 5 bits remaining in b.
+ a[2] = (b[1] & 0b00011111) << 3
+
+ b[0] = 0
+ b[1] = 0
+ binary.BigEndian.PutUint16(b, hdr.PacketCount)
+ // 3 bits spare in a[2].
+ a[2] |= (b[0] & 0b00000111)
+ a[3] = b[1]
+ return a
+}