This commit is contained in:
Ingo Oppermann 2022-07-28 18:31:52 +02:00
parent 7098ea1efd
commit 01b5cd703f
38 changed files with 717 additions and 725 deletions

View File

@ -1,4 +1,3 @@
// Package av defines basic interfaces and data structures of container demux/mux and audio encode/decode. // Package av defines basic interfaces and data structures of container demux/mux and audio encode/decode.
package av package av
@ -196,7 +195,7 @@ type PacketWriter interface {
} }
type PacketReader interface { type PacketReader interface {
ReadPacket() (Packet,error) ReadPacket() (Packet, error)
} }
// Muxer describes the steps of writing compressed audio/video packets into container formats like MP4/FLV/MPEG-TS. // Muxer describes the steps of writing compressed audio/video packets into container formats like MP4/FLV/MPEG-TS.
@ -294,12 +293,12 @@ type AudioEncoder interface {
CodecData() (AudioCodecData, error) // encoder's codec data can put into container CodecData() (AudioCodecData, error) // encoder's codec data can put into container
Encode(AudioFrame) ([][]byte, error) // encode raw audio frame into compressed pakcet(s) Encode(AudioFrame) ([][]byte, error) // encode raw audio frame into compressed pakcet(s)
Close() // close encoder, free cgo contexts Close() // close encoder, free cgo contexts
SetSampleRate(int) (error) // set encoder sample rate SetSampleRate(int) error // set encoder sample rate
SetChannelLayout(ChannelLayout) (error) // set encoder channel layout SetChannelLayout(ChannelLayout) error // set encoder channel layout
SetSampleFormat(SampleFormat) (error) // set encoder sample format SetSampleFormat(SampleFormat) error // set encoder sample format
SetBitrate(int) (error) // set encoder bitrate SetBitrate(int) error // set encoder bitrate
SetOption(string,interface{}) (error) // encoder setopt, in ffmpeg is av_opt_set_dict() SetOption(string, interface{}) error // encoder setopt, in ffmpeg is av_opt_set_dict()
GetOption(string,interface{}) (error) // encoder getopt GetOption(string, interface{}) error // encoder getopt
} }
// AudioDecoder can decode compressed audio packets into raw audio frame. // AudioDecoder can decode compressed audio packets into raw audio frame.
@ -313,4 +312,3 @@ type AudioDecoder interface {
type AudioResampler interface { type AudioResampler interface {
Resample(AudioFrame) (AudioFrame, error) // convert raw audio frames Resample(AudioFrame) (AudioFrame, error) // convert raw audio frames
} }

View File

@ -2,12 +2,12 @@ package avconv
import ( import (
"fmt" "fmt"
"io"
"time"
"github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/av/pktque" "github.com/datarhei/joy4/av/pktque"
"github.com/datarhei/joy4/av/transcode" "github.com/datarhei/joy4/av/transcode"
"io"
"time"
) )
var Debug bool var Debug bool
@ -83,7 +83,7 @@ func (self *Demuxer) prepare() (err error) {
ok = true ok = true
var enctype av.CodecType var enctype av.CodecType
for _, typ:= range supports { for _, typ := range supports {
if typ.IsAudio() { if typ.IsAudio() {
if enc, _ = avutil.DefaultHandlers.NewAudioEncoder(typ); enc != nil { if enc, _ = avutil.DefaultHandlers.NewAudioEncoder(typ); enc != nil {
enctype = typ enctype = typ
@ -152,7 +152,7 @@ func ConvertCmdline(args []string) (err error) {
flagt = false flagt = false
var f float64 var f float64
fmt.Sscanf(arg, "%f", &f) fmt.Sscanf(arg, "%f", &f)
duration = time.Duration(f*float64(time.Second)) duration = time.Duration(f * float64(time.Second))
default: default:
output = arg output = arg
@ -252,4 +252,3 @@ func ConvertCmdline(args []string) (err error) {
return return
} }

View File

@ -1,14 +1,15 @@
package avutil package avutil
import ( import (
"io"
"strings"
"fmt"
"bytes" "bytes"
"github.com/datarhei/joy4/av" "fmt"
"io"
"net/url" "net/url"
"os" "os"
"path" "path"
"strings"
"github.com/datarhei/joy4/av"
) )
type HandlerDemuxer struct { type HandlerDemuxer struct {
@ -55,16 +56,16 @@ func (self *HandlerMuxer) Close() (err error) {
type RegisterHandler struct { type RegisterHandler struct {
Ext string Ext string
ReaderDemuxer func(io.Reader)av.Demuxer ReaderDemuxer func(io.Reader) av.Demuxer
WriterMuxer func(io.Writer)av.Muxer WriterMuxer func(io.Writer) av.Muxer
UrlMuxer func(string)(bool,av.MuxCloser,error) UrlMuxer func(string) (bool, av.MuxCloser, error)
UrlDemuxer func(string)(bool,av.DemuxCloser,error) UrlDemuxer func(string) (bool, av.DemuxCloser, error)
UrlReader func(string)(bool,io.ReadCloser,error) UrlReader func(string) (bool, io.ReadCloser, error)
Probe func([]byte)bool Probe func([]byte) bool
AudioEncoder func(av.CodecType)(av.AudioEncoder,error) AudioEncoder func(av.CodecType) (av.AudioEncoder, error)
AudioDecoder func(av.AudioCodecData)(av.AudioDecoder,error) AudioDecoder func(av.AudioCodecData) (av.AudioDecoder, error)
ServerDemuxer func(string)(bool,av.DemuxCloser,error) ServerDemuxer func(string) (bool, av.DemuxCloser, error)
ServerMuxer func(string)(bool,av.MuxCloser,error) ServerMuxer func(string) (bool, av.MuxCloser, error)
CodecTypes []av.CodecType CodecTypes []av.CodecType
} }
@ -108,7 +109,7 @@ func (self *Handlers) NewAudioEncoder(typ av.CodecType) (enc av.AudioEncoder, er
} }
} }
} }
err = fmt.Errorf("avutil: encoder", typ, "not found") err = fmt.Errorf("avutil: encoder %s not found", typ)
return return
} }
@ -120,7 +121,7 @@ func (self *Handlers) NewAudioDecoder(codec av.AudioCodecData) (dec av.AudioDeco
} }
} }
} }
err = fmt.Errorf("avutil: decoder", codec.Type(), "not found") err = fmt.Errorf("avutil: decoder %s not found", codec.Type())
return return
} }

View File

@ -1,10 +1,9 @@
// Package pktque provides packet Filter interface and structures used by other components. // Package pktque provides packet Filter interface and structures used by other components.
package pktque package pktque
import ( import (
"time"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"time"
) )
type Filter interface { type Filter interface {
@ -121,7 +120,7 @@ func (self *AVSync) ModifyPacket(pkt *av.Packet, streams []av.CodecData, videoid
if self.time == nil { if self.time == nil {
self.time = make([]time.Duration, len(streams)) self.time = make([]time.Duration, len(streams))
if self.MaxTimeDiff == 0 { if self.MaxTimeDiff == 0 {
self.MaxTimeDiff = time.Millisecond*500 self.MaxTimeDiff = time.Millisecond * 500
} }
} }
@ -188,4 +187,3 @@ func (self *Walltime) ModifyPacket(pkt *av.Packet, streams []av.CodecData, video
} }
return return
} }

View File

@ -26,7 +26,7 @@ type Timeline struct {
func (self *Timeline) Push(tm time.Duration, dur time.Duration) { func (self *Timeline) Push(tm time.Duration, dur time.Duration) {
if len(self.segs) > 0 { if len(self.segs) > 0 {
tail := self.segs[len(self.segs)-1] tail := self.segs[len(self.segs)-1]
diff := tm-(tail.tm+tail.dur) diff := tm - (tail.tm + tail.dur)
if diff < 0 { if diff < 0 {
tm -= diff tm -= diff
} }
@ -58,4 +58,3 @@ func (self *Timeline) Pop(dur time.Duration) (tm time.Duration) {
return return
} }

View File

@ -2,11 +2,12 @@
package pubsub package pubsub
import ( import (
"github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/pktque"
"io" "io"
"sync" "sync"
"time" "time"
"github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/pktque"
) )
// time // time
@ -97,7 +98,6 @@ func (self *Queue) WritePacket(pkt av.Packet) (err error) {
break break
} }
} }
//println("shrink", self.curgopcount, self.maxgopcount, self.buf.Head, self.buf.Tail, "count", self.buf.Count, "size", self.buf.Size)
self.cond.Broadcast() self.cond.Broadcast()

View File

@ -1,12 +1,11 @@
// Package transcoder implements Transcoder based on Muxer/Demuxer and AudioEncoder/AudioDecoder interface. // Package transcoder implements Transcoder based on Muxer/Demuxer and AudioEncoder/AudioDecoder interface.
package transcode package transcode
import ( import (
"fmt" "fmt"
"time"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/pktque" "github.com/datarhei/joy4/av/pktque"
"time"
) )
var Debug bool var Debug bool

View File

@ -1,12 +1,12 @@
package aacparser package aacparser
import ( import (
"github.com/datarhei/joy4/utils/bits"
"github.com/datarhei/joy4/av"
"time"
"fmt"
"bytes" "bytes"
"fmt"
"github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/utils/bits"
"io" "io"
"time"
) )
// copied from libavcodec/mpeg4audio.h // copied from libavcodec/mpeg4audio.h
@ -83,12 +83,12 @@ These are the channel configurations:
var chanConfigTable = []av.ChannelLayout{ var chanConfigTable = []av.ChannelLayout{
0, 0,
av.CH_FRONT_CENTER, av.CH_FRONT_CENTER,
av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT, av.CH_FRONT_LEFT | av.CH_FRONT_RIGHT,
av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT, av.CH_FRONT_CENTER | av.CH_FRONT_LEFT | av.CH_FRONT_RIGHT,
av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT|av.CH_BACK_CENTER, av.CH_FRONT_CENTER | av.CH_FRONT_LEFT | av.CH_FRONT_RIGHT | av.CH_BACK_CENTER,
av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT|av.CH_BACK_LEFT|av.CH_BACK_RIGHT, av.CH_FRONT_CENTER | av.CH_FRONT_LEFT | av.CH_FRONT_RIGHT | av.CH_BACK_LEFT | av.CH_BACK_RIGHT,
av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT|av.CH_BACK_LEFT|av.CH_BACK_RIGHT|av.CH_LOW_FREQ, av.CH_FRONT_CENTER | av.CH_FRONT_LEFT | av.CH_FRONT_RIGHT | av.CH_BACK_LEFT | av.CH_BACK_RIGHT | av.CH_LOW_FREQ,
av.CH_FRONT_CENTER|av.CH_FRONT_LEFT|av.CH_FRONT_RIGHT|av.CH_SIDE_LEFT|av.CH_SIDE_RIGHT|av.CH_BACK_LEFT|av.CH_BACK_RIGHT|av.CH_LOW_FREQ, av.CH_FRONT_CENTER | av.CH_FRONT_LEFT | av.CH_FRONT_RIGHT | av.CH_SIDE_LEFT | av.CH_SIDE_RIGHT | av.CH_BACK_LEFT | av.CH_BACK_RIGHT | av.CH_LOW_FREQ,
} }
func ParseADTSHeader(frame []byte) (config MPEG4AudioConfig, hdrlen int, framelen int, samples int, err error) { func ParseADTSHeader(frame []byte) (config MPEG4AudioConfig, hdrlen int, framelen int, samples int, err error) {
@ -308,4 +308,3 @@ func NewCodecDataFromMPEG4AudioConfigBytes(config []byte) (self CodecData, err e
} }
return return
} }

View File

@ -50,7 +50,7 @@ func (self SpeexCodecData) PacketDuration(data []byte) (time.Duration, error) {
// libavcodec/libspeexdec.c // libavcodec/libspeexdec.c
// samples = samplerate/50 // samples = samplerate/50
// duration = 0.02s // duration = 0.02s
return time.Millisecond*20, nil return time.Millisecond * 20, nil
} }
func NewSpeexCodecData(sr int, cl av.ChannelLayout) SpeexCodecData { func NewSpeexCodecData(sr int, cl av.ChannelLayout) SpeexCodecData {
@ -61,4 +61,3 @@ func NewSpeexCodecData(sr int, cl av.ChannelLayout) SpeexCodecData {
codec.ChannelLayout_ = cl codec.ChannelLayout_ = cl
return codec return codec
} }

View File

@ -26,4 +26,3 @@ func (self CodecData) ChannelLayout() av.ChannelLayout {
func (self CodecData) SampleRate() int { func (self CodecData) SampleRate() int {
return self.SampleRate_ return self.SampleRate_
} }

View File

@ -1,12 +1,11 @@
package h264parser package h264parser
import ( import (
"bytes"
"fmt"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/utils/bits" "github.com/datarhei/joy4/utils/bits"
"github.com/datarhei/joy4/utils/bits/pio" "github.com/datarhei/joy4/utils/bits/pio"
"fmt"
"bytes"
) )
const ( const (
@ -199,8 +198,8 @@ Additionally, there is a new variable called NALULengthSizeMinusOne. This confus
An advantage to this format is the ability to configure the decoder at the start and jump into the middle of a stream. This is a common use case where the media is available on a random access medium such as a hard drive, and is therefore used in common container formats such as MP4 and MKV. An advantage to this format is the ability to configure the decoder at the start and jump into the middle of a stream. This is a common use case where the media is available on a random access medium such as a hard drive, and is therefore used in common container formats such as MP4 and MKV.
*/ */
var StartCodeBytes = []byte{0,0,1} var StartCodeBytes = []byte{0, 0, 1}
var AUDBytes = []byte{0,0,0,1,0x9,0xf0,0,0,0,1} // AUD var AUDBytes = []byte{0, 0, 0, 1, 0x9, 0xf0, 0, 0, 0, 1} // AUD
func CheckNALUsType(b []byte) (typ int) { func CheckNALUsType(b []byte) (typ int) {
_, typ = SplitNALUs(b) _, typ = SplitNALUs(b)
@ -589,8 +588,8 @@ func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) {
self.AVCProfileIndication = b[1] self.AVCProfileIndication = b[1]
self.ProfileCompatibility = b[2] self.ProfileCompatibility = b[2]
self.AVCLevelIndication = b[3] self.AVCLevelIndication = b[3]
self.LengthSizeMinusOne = b[4]&0x03 self.LengthSizeMinusOne = b[4] & 0x03
spscount := int(b[5]&0x1f) spscount := int(b[5] & 0x1f)
n += 6 n += 6
for i := 0; i < spscount; i++ { for i := 0; i < spscount; i++ {
@ -638,10 +637,10 @@ func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) {
func (self AVCDecoderConfRecord) Len() (n int) { func (self AVCDecoderConfRecord) Len() (n int) {
n = 7 n = 7
for _, sps := range self.SPS { for _, sps := range self.SPS {
n += 2+len(sps) n += 2 + len(sps)
} }
for _, pps := range self.PPS { for _, pps := range self.PPS {
n += 2+len(pps) n += 2 + len(pps)
} }
return return
} }
@ -651,8 +650,8 @@ func (self AVCDecoderConfRecord) Marshal(b []byte) (n int) {
b[1] = self.AVCProfileIndication b[1] = self.AVCProfileIndication
b[2] = self.ProfileCompatibility b[2] = self.ProfileCompatibility
b[3] = self.AVCLevelIndication b[3] = self.AVCLevelIndication
b[4] = self.LengthSizeMinusOne|0xfc b[4] = self.LengthSizeMinusOne | 0xfc
b[5] = uint8(len(self.SPS))|0xe0 b[5] = uint8(len(self.SPS)) | 0xe0
n += 6 n += 6
for _, sps := range self.SPS { for _, sps := range self.SPS {
@ -690,7 +689,7 @@ func (self SliceType) String() string {
} }
const ( const (
SLICE_P = iota+1 SLICE_P = iota + 1
SLICE_B SLICE_B
SLICE_I SLICE_I
) )
@ -702,9 +701,9 @@ func ParseSliceHeaderFromNALU(packet []byte) (sliceType SliceType, err error) {
return return
} }
nal_unit_type := packet[0]&0x1f nal_unit_type := packet[0] & 0x1f
switch nal_unit_type { switch nal_unit_type {
case 1,2,5,19: case 1, 2, 5, 19:
// slice_layer_without_partitioning_rbsp // slice_layer_without_partitioning_rbsp
// slice_data_partition_a_layer_rbsp // slice_data_partition_a_layer_rbsp
@ -727,11 +726,11 @@ func ParseSliceHeaderFromNALU(packet []byte) (sliceType SliceType, err error) {
} }
switch u { switch u {
case 0,3,5,8: case 0, 3, 5, 8:
sliceType = SLICE_P sliceType = SLICE_P
case 1,6: case 1, 6:
sliceType = SLICE_B sliceType = SLICE_B
case 2,4,7,9: case 2, 4, 7, 9:
sliceType = SLICE_I sliceType = SLICE_I
default: default:
err = fmt.Errorf("h264parser: slice_type=%d invalid", u) err = fmt.Errorf("h264parser: slice_type=%d invalid", u)
@ -740,4 +739,3 @@ func ParseSliceHeaderFromNALU(packet []byte) (sliceType SliceType, err error) {
return return
} }

View File

@ -1,9 +1,8 @@
package h264parser package h264parser
import ( import (
"testing"
"encoding/hex" "encoding/hex"
"testing"
) )
func TestParser(t *testing.T) { func TestParser(t *testing.T) {
@ -20,4 +19,3 @@ func TestParser(t *testing.T) {
nalus, ok = SplitNALUs(avccFrame) nalus, ok = SplitNALUs(avccFrame)
t.Log(ok, len(nalus)) t.Log(ok, len(nalus))
} }

1
doc.go
View File

@ -1,4 +1,3 @@
// Package joy4 is a Golang audio/video library and streaming server. // Package joy4 is a Golang audio/video library and streaming server.
// JOY4 is powerful library written in golang, well-designed interface makes a few lines // JOY4 is powerful library written in golang, well-designed interface makes a few lines
// of code can do a lot of things such as reading, writing, transcoding among // of code can do a lot of things such as reading, writing, transcoding among

View File

@ -1,14 +1,13 @@
package aac package aac
import ( import (
"github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/codec/aacparser"
"time"
"fmt"
"io"
"bufio" "bufio"
"fmt"
"github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/codec/aacparser"
"io"
"time"
) )
type Muxer struct { type Muxer struct {

View File

@ -3,7 +3,6 @@ package flv
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/datarhei/joy4/utils/bits/pio"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/avutil" "github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/codec" "github.com/datarhei/joy4/codec"
@ -11,6 +10,7 @@ import (
"github.com/datarhei/joy4/codec/fake" "github.com/datarhei/joy4/codec/fake"
"github.com/datarhei/joy4/codec/h264parser" "github.com/datarhei/joy4/codec/h264parser"
"github.com/datarhei/joy4/format/flv/flvio" "github.com/datarhei/joy4/format/flv/flvio"
"github.com/datarhei/joy4/utils/bits/pio"
"io" "io"
) )

View File

@ -1,11 +1,11 @@
package flvio package flvio
import ( import (
"strings"
"math"
"fmt" "fmt"
"time"
"github.com/datarhei/joy4/utils/bits/pio" "github.com/datarhei/joy4/utils/bits/pio"
"math"
"strings"
"time"
) )
type AMF0ParseError struct { type AMF0ParseError struct {
@ -133,7 +133,7 @@ func LenAMF0Val(_val interface{}) (n int) {
case AMFECMAArray: case AMFECMAArray:
n += 5 n += 5
for k, v := range val { for k, v := range val {
n += 2+len(k) n += 2 + len(k)
n += LenAMF0Val(v) n += LenAMF0Val(v)
} }
n += 3 n += 3
@ -142,7 +142,7 @@ func LenAMF0Val(_val interface{}) (n int) {
n++ n++
for k, v := range val { for k, v := range val {
if len(k) > 0 { if len(k) > 0 {
n += 2+len(k) n += 2 + len(k)
n += LenAMF0Val(v) n += LenAMF0Val(v)
} }
} }
@ -155,7 +155,7 @@ func LenAMF0Val(_val interface{}) (n int) {
} }
case time.Time: case time.Time:
n += 1+8+2 n += 1 + 8 + 2
case bool: case bool:
n += 2 n += 2
@ -253,7 +253,7 @@ func FillAMF0Val(b []byte, _val interface{}) (n int) {
b[n] = datemarker b[n] = datemarker
n++ n++
u := val.UnixNano() u := val.UnixNano()
f := float64(u/1000000) f := float64(u / 1000000)
n += fillBEFloat64(b[n:], f) n += fillBEFloat64(b[n:], f)
pio.PutU16BE(b[n:], uint16(0)) pio.PutU16BE(b[n:], uint16(0))
n += 2 n += 2
@ -278,7 +278,6 @@ func FillAMF0Val(b []byte, _val interface{}) (n int) {
return return
} }
func ParseAMF0Val(b []byte) (val interface{}, n int, err error) { func ParseAMF0Val(b []byte) (val interface{}, n int, err error) {
return parseAMF0Val(b, 0) return parseAMF0Val(b, 0)
} }
@ -320,7 +319,7 @@ func parseAMF0Val(b []byte, offset int) (val interface{}, n int, err error) {
err = amf0ParseErr("string.body", offset+n, err) err = amf0ParseErr("string.body", offset+n, err)
return return
} }
val = string(b[n:n+length]) val = string(b[n : n+length])
n += length n += length
case objectmarker: case objectmarker:
@ -340,7 +339,7 @@ func parseAMF0Val(b []byte, offset int) (val interface{}, n int, err error) {
err = amf0ParseErr("object.key.body", offset+n, err) err = amf0ParseErr("object.key.body", offset+n, err)
return return
} }
okey := string(b[n:n+length]) okey := string(b[n : n+length])
n += length n += length
var nval int var nval int
@ -387,7 +386,7 @@ func parseAMF0Val(b []byte, offset int) (val interface{}, n int, err error) {
err = amf0ParseErr("array.key.body", offset+n, err) err = amf0ParseErr("array.key.body", offset+n, err)
return return
} }
okey := string(b[n:n+length]) okey := string(b[n : n+length])
n += length n += length
var nval int var nval int
@ -439,7 +438,7 @@ func parseAMF0Val(b []byte, offset int) (val interface{}, n int, err error) {
return return
} }
ts := parseBEFloat64(b[n:]) ts := parseBEFloat64(b[n:])
n += 8+2 n += 8 + 2
val = time.Unix(int64(ts/1000), (int64(ts)%1000)*1000000) val = time.Unix(int64(ts/1000), (int64(ts)%1000)*1000000)
@ -455,7 +454,7 @@ func parseAMF0Val(b []byte, offset int) (val interface{}, n int, err error) {
err = amf0ParseErr("longstring.body", offset+n, err) err = amf0ParseErr("longstring.body", offset+n, err)
return return
} }
val = string(b[n:n+length]) val = string(b[n : n+length])
n += length n += length
default: default:
@ -465,4 +464,3 @@ func parseAMF0Val(b []byte, offset int) (val interface{}, n int, err error) {
return return
} }

View File

@ -2,8 +2,8 @@ package flvio
import ( import (
"fmt" "fmt"
"github.com/datarhei/joy4/utils/bits/pio"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/utils/bits/pio"
"io" "io"
"time" "time"
) )

View File

@ -1,13 +1,13 @@
package format package format
import ( import (
"github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/format/aac"
"github.com/datarhei/joy4/format/flv"
"github.com/datarhei/joy4/format/mp4" "github.com/datarhei/joy4/format/mp4"
"github.com/datarhei/joy4/format/ts"
"github.com/datarhei/joy4/format/rtmp" "github.com/datarhei/joy4/format/rtmp"
"github.com/datarhei/joy4/format/rtsp" "github.com/datarhei/joy4/format/rtsp"
"github.com/datarhei/joy4/format/flv" "github.com/datarhei/joy4/format/ts"
"github.com/datarhei/joy4/format/aac"
"github.com/datarhei/joy4/av/avutil"
) )
func RegisterAll() { func RegisterAll() {
@ -18,4 +18,3 @@ func RegisterAll() {
avutil.DefaultHandlers.Add(flv.Handler) avutil.DefaultHandlers.Add(flv.Handler)
avutil.DefaultHandlers.Add(aac.Handler) avutil.DefaultHandlers.Add(aac.Handler)
} }

View File

@ -1,9 +1,9 @@
package mp4 package mp4
import ( import (
"io"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/avutil" "github.com/datarhei/joy4/av/avutil"
"io"
) )
var CodecTypes = []av.CodecType{av.H264, av.AAC} var CodecTypes = []av.CodecType{av.H264, av.AAC}
@ -13,7 +13,7 @@ func Handler(h *avutil.RegisterHandler) {
h.Probe = func(b []byte) bool { h.Probe = func(b []byte) bool {
switch string(b[4:8]) { switch string(b[4:8]) {
case "moov","ftyp","free","mdat","moof": case "moov", "ftyp", "free", "mdat", "moof":
return true return true
} }
return false return false
@ -29,4 +29,3 @@ func Handler(h *avutil.RegisterHandler) {
h.CodecTypes = CodecTypes h.CodecTypes = CodecTypes
} }

View File

@ -213,7 +213,7 @@ type Movie struct {
func (self Movie) Marshal(b []byte) (n int) { func (self Movie) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MOOV)) pio.PutU32BE(b[4:], uint32(MOOV))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -288,7 +288,7 @@ func (self *Movie) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -336,7 +336,7 @@ type MovieHeader struct {
func (self MovieHeader) Marshal(b []byte) (n int) { func (self MovieHeader) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MVHD)) pio.PutU32BE(b[4:], uint32(MVHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -389,7 +389,7 @@ func (self MovieHeader) Len() (n int) {
n += 4 n += 4
n += 2 n += 2
n += 10 n += 10
n += 4*len(self.Matrix[:]) n += 4 * len(self.Matrix[:])
n += 4 n += 4
n += 4 n += 4
n += 4 n += 4
@ -516,7 +516,7 @@ type Track struct {
func (self Track) Marshal(b []byte) (n int) { func (self Track) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TRAK)) pio.PutU32BE(b[4:], uint32(TRAK))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -576,7 +576,7 @@ func (self *Track) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -617,7 +617,7 @@ type TrackHeader struct {
func (self TrackHeader) Marshal(b []byte) (n int) { func (self TrackHeader) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TKHD)) pio.PutU32BE(b[4:], uint32(TKHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -667,7 +667,7 @@ func (self TrackHeader) Len() (n int) {
n += 2 n += 2
n += 2 n += 2
n += 2 n += 2
n += 4*len(self.Matrix[:]) n += 4 * len(self.Matrix[:])
n += 4 n += 4
n += 4 n += 4
return return
@ -769,7 +769,7 @@ type HandlerRefer struct {
func (self HandlerRefer) Marshal(b []byte) (n int) { func (self HandlerRefer) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(HDLR)) pio.PutU32BE(b[4:], uint32(HDLR))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -840,7 +840,7 @@ type Media struct {
func (self Media) Marshal(b []byte) (n int) { func (self Media) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MDIA)) pio.PutU32BE(b[4:], uint32(MDIA))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -915,7 +915,7 @@ func (self *Media) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -955,7 +955,7 @@ type MediaHeader struct {
func (self MediaHeader) Marshal(b []byte) (n int) { func (self MediaHeader) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MDHD)) pio.PutU32BE(b[4:], uint32(MDHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1058,7 +1058,7 @@ type MediaInfo struct {
func (self MediaInfo) Marshal(b []byte) (n int) { func (self MediaInfo) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MINF)) pio.PutU32BE(b[4:], uint32(MINF))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1148,7 +1148,7 @@ func (self *MediaInfo) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -1185,7 +1185,7 @@ type DataInfo struct {
func (self DataInfo) Marshal(b []byte) (n int) { func (self DataInfo) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(DINF)) pio.PutU32BE(b[4:], uint32(DINF))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1230,7 +1230,7 @@ func (self *DataInfo) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -1259,7 +1259,7 @@ type DataRefer struct {
func (self DataRefer) Marshal(b []byte) (n int) { func (self DataRefer) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(DREF)) pio.PutU32BE(b[4:], uint32(DREF))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1313,7 +1313,7 @@ func (self *DataRefer) Unmarshal(b []byte, offset int) (n int, err error) {
return return
} }
switch tag { switch tag {
case URL : case URL:
{ {
atom := &DataReferUrl{} atom := &DataReferUrl{}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
@ -1341,8 +1341,8 @@ type DataReferUrl struct {
} }
func (self DataReferUrl) Marshal(b []byte) (n int) { func (self DataReferUrl) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(URL )) pio.PutU32BE(b[4:], uint32(URL))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1389,7 +1389,7 @@ type SoundMediaInfo struct {
func (self SoundMediaInfo) Marshal(b []byte) (n int) { func (self SoundMediaInfo) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(SMHD)) pio.PutU32BE(b[4:], uint32(SMHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1449,7 +1449,7 @@ type VideoMediaInfo struct {
func (self VideoMediaInfo) Marshal(b []byte) (n int) { func (self VideoMediaInfo) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(VMHD)) pio.PutU32BE(b[4:], uint32(VMHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1471,7 +1471,7 @@ func (self VideoMediaInfo) Len() (n int) {
n += 1 n += 1
n += 3 n += 3
n += 2 n += 2
n += 2*len(self.Opcolor[:]) n += 2 * len(self.Opcolor[:])
return return
} }
func (self *VideoMediaInfo) Unmarshal(b []byte, offset int) (n int, err error) { func (self *VideoMediaInfo) Unmarshal(b []byte, offset int) (n int, err error) {
@ -1522,7 +1522,7 @@ type SampleTable struct {
func (self SampleTable) Marshal(b []byte) (n int) { func (self SampleTable) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STBL)) pio.PutU32BE(b[4:], uint32(STBL))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1689,7 +1689,7 @@ type SampleDesc struct {
func (self SampleDesc) Marshal(b []byte) (n int) { func (self SampleDesc) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STSD)) pio.PutU32BE(b[4:], uint32(STSD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1773,7 +1773,7 @@ func (self *SampleDesc) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -1812,7 +1812,7 @@ type MP4ADesc struct {
func (self MP4ADesc) Marshal(b []byte) (n int) { func (self MP4ADesc) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MP4A)) pio.PutU32BE(b[4:], uint32(MP4A))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -1935,7 +1935,7 @@ func (self *MP4ADesc) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -1977,7 +1977,7 @@ type AVC1Desc struct {
func (self AVC1Desc) Marshal(b []byte) (n int) { func (self AVC1Desc) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(AVC1)) pio.PutU32BE(b[4:], uint32(AVC1))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2154,7 +2154,7 @@ func (self *AVC1Desc) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -2181,7 +2181,7 @@ type AVC1Conf struct {
func (self AVC1Conf) Marshal(b []byte) (n int) { func (self AVC1Conf) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(AVCC)) pio.PutU32BE(b[4:], uint32(AVCC))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2215,7 +2215,7 @@ type TimeToSample struct {
func (self TimeToSample) Marshal(b []byte) (n int) { func (self TimeToSample) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STTS)) pio.PutU32BE(b[4:], uint32(STTS))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2237,7 +2237,7 @@ func (self TimeToSample) Len() (n int) {
n += 1 n += 1
n += 3 n += 3
n += 4 n += 4
n += LenTimeToSampleEntry*len(self.Entries) n += LenTimeToSampleEntry * len(self.Entries)
return return
} }
func (self *TimeToSample) Unmarshal(b []byte, offset int) (n int, err error) { func (self *TimeToSample) Unmarshal(b []byte, offset int) (n int, err error) {
@ -2299,7 +2299,7 @@ type SampleToChunk struct {
func (self SampleToChunk) Marshal(b []byte) (n int) { func (self SampleToChunk) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STSC)) pio.PutU32BE(b[4:], uint32(STSC))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2321,7 +2321,7 @@ func (self SampleToChunk) Len() (n int) {
n += 1 n += 1
n += 3 n += 3
n += 4 n += 4
n += LenSampleToChunkEntry*len(self.Entries) n += LenSampleToChunkEntry * len(self.Entries)
return return
} }
func (self *SampleToChunk) Unmarshal(b []byte, offset int) (n int, err error) { func (self *SampleToChunk) Unmarshal(b []byte, offset int) (n int, err error) {
@ -2386,7 +2386,7 @@ type CompositionOffset struct {
func (self CompositionOffset) Marshal(b []byte) (n int) { func (self CompositionOffset) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(CTTS)) pio.PutU32BE(b[4:], uint32(CTTS))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2408,7 +2408,7 @@ func (self CompositionOffset) Len() (n int) {
n += 1 n += 1
n += 3 n += 3
n += 4 n += 4
n += LenCompositionOffsetEntry*len(self.Entries) n += LenCompositionOffsetEntry * len(self.Entries)
return return
} }
func (self *CompositionOffset) Unmarshal(b []byte, offset int) (n int, err error) { func (self *CompositionOffset) Unmarshal(b []byte, offset int) (n int, err error) {
@ -2470,7 +2470,7 @@ type SyncSample struct {
func (self SyncSample) Marshal(b []byte) (n int) { func (self SyncSample) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STSS)) pio.PutU32BE(b[4:], uint32(STSS))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2492,7 +2492,7 @@ func (self SyncSample) Len() (n int) {
n += 1 n += 1
n += 3 n += 3
n += 4 n += 4
n += 4*len(self.Entries) n += 4 * len(self.Entries)
return return
} }
func (self *SyncSample) Unmarshal(b []byte, offset int) (n int, err error) { func (self *SyncSample) Unmarshal(b []byte, offset int) (n int, err error) {
@ -2537,7 +2537,7 @@ type ChunkOffset struct {
func (self ChunkOffset) Marshal(b []byte) (n int) { func (self ChunkOffset) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STCO)) pio.PutU32BE(b[4:], uint32(STCO))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2559,7 +2559,7 @@ func (self ChunkOffset) Len() (n int) {
n += 1 n += 1
n += 3 n += 3
n += 4 n += 4
n += 4*len(self.Entries) n += 4 * len(self.Entries)
return return
} }
func (self *ChunkOffset) Unmarshal(b []byte, offset int) (n int, err error) { func (self *ChunkOffset) Unmarshal(b []byte, offset int) (n int, err error) {
@ -2604,7 +2604,7 @@ type MovieFrag struct {
func (self MovieFrag) Marshal(b []byte) (n int) { func (self MovieFrag) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MOOF)) pio.PutU32BE(b[4:], uint32(MOOF))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2664,7 +2664,7 @@ func (self *MovieFrag) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -2696,7 +2696,7 @@ type MovieFragHeader struct {
func (self MovieFragHeader) Marshal(b []byte) (n int) { func (self MovieFragHeader) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MFHD)) pio.PutU32BE(b[4:], uint32(MFHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2753,7 +2753,7 @@ type TrackFrag struct {
func (self TrackFrag) Marshal(b []byte) (n int) { func (self TrackFrag) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TRAF)) pio.PutU32BE(b[4:], uint32(TRAF))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2828,7 +2828,7 @@ func (self *TrackFrag) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -2862,7 +2862,7 @@ type MovieExtend struct {
func (self MovieExtend) Marshal(b []byte) (n int) { func (self MovieExtend) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(MVEX)) pio.PutU32BE(b[4:], uint32(MVEX))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -2907,7 +2907,7 @@ func (self *MovieExtend) Unmarshal(b []byte, offset int) (n int, err error) {
} }
default: default:
{ {
atom := &Dummy{Tag_: tag, Data: b[n:n+size]} atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
err = parseErr("", n+offset, err) err = parseErr("", n+offset, err)
return return
@ -2940,7 +2940,7 @@ type TrackExtend struct {
func (self TrackExtend) Marshal(b []byte) (n int) { func (self TrackExtend) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TREX)) pio.PutU32BE(b[4:], uint32(TREX))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -3033,7 +3033,7 @@ type SampleSize struct {
func (self SampleSize) Marshal(b []byte) (n int) { func (self SampleSize) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(STSZ)) pio.PutU32BE(b[4:], uint32(STSZ))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -3064,7 +3064,7 @@ func (self SampleSize) Len() (n int) {
return return
} }
n += 4 n += 4
n += 4*len(self.Entries) n += 4 * len(self.Entries)
return return
} }
func (self *SampleSize) Unmarshal(b []byte, offset int) (n int, err error) { func (self *SampleSize) Unmarshal(b []byte, offset int) (n int, err error) {
@ -3120,7 +3120,7 @@ type TrackFragRun struct {
func (self TrackFragRun) Marshal(b []byte) (n int) { func (self TrackFragRun) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TRUN)) pio.PutU32BE(b[4:], uint32(TRUN))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -3315,7 +3315,7 @@ type TrackFragHeader struct {
func (self TrackFragHeader) Marshal(b []byte) (n int) { func (self TrackFragHeader) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TFHD)) pio.PutU32BE(b[4:], uint32(TFHD))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }
@ -3467,7 +3467,7 @@ type TrackFragDecodeTime struct {
func (self TrackFragDecodeTime) Marshal(b []byte) (n int) { func (self TrackFragDecodeTime) Marshal(b []byte) (n int) {
pio.PutU32BE(b[4:], uint32(TFDT)) pio.PutU32BE(b[4:], uint32(TFDT))
n += self.marshal(b[8:])+8 n += self.marshal(b[8:]) + 8
pio.PutU32BE(b[0:], uint32(n)) pio.PutU32BE(b[0:], uint32(n))
return return
} }

View File

@ -1,14 +1,13 @@
package main package main
import ( import (
"strings"
"fmt" "fmt"
"os"
"go/ast" "go/ast"
"go/parser" "go/parser"
"go/token"
"go/printer" "go/printer"
"go/token"
"os"
"strings"
) )
func getexprs(e ast.Expr) string { func getexprs(e ast.Expr) string {
@ -67,19 +66,19 @@ func genatomdecl(origfn *ast.FuncDecl, origname, origtag string) (decls []ast.De
case "bytesleft": case "bytesleft":
typ = "[]byte" typ = "[]byte"
case "bytes": case "bytes":
typ = "["+name2+"]byte" typ = "[" + name2 + "]byte"
case "uint24": case "uint24":
typ = "uint32" typ = "uint32"
case "time64", "time32": case "time64", "time32":
typ = "time.Time" typ = "time.Time"
case "atom": case "atom":
typ = "*"+name2 typ = "*" + name2
case "atoms": case "atoms":
typ = "[]*"+name2 typ = "[]*" + name2
case "slice": case "slice":
typ = "[]"+name2 typ = "[]" + name2
case "array": case "array":
typ = "["+len3+"]"+name2 typ = "[" + len3 + "]" + name2
} }
fieldslist.List = append(fieldslist.List, &ast.Field{ fieldslist.List = append(fieldslist.List, &ast.Field{
@ -135,7 +134,7 @@ func typegetlen(typ string) (n int) {
func typegetlens(typ string) string { func typegetlens(typ string) string {
n := typegetlen(typ) n := typegetlen(typ)
if n == 0 { if n == 0 {
return "Len"+typ return "Len" + typ
} else { } else {
return fmt.Sprint(n) return fmt.Sprint(n)
} }
@ -187,7 +186,7 @@ func typegetputfn(typ string) (fn string) {
case "fixed16": case "fixed16":
fn = "PutFixed16" fn = "PutFixed16"
default: default:
fn = "Put"+typ fn = "Put" + typ
} }
return return
} }
@ -218,7 +217,7 @@ func typegetgetfn(typ string) (fn string) {
case "fixed16": case "fixed16":
fn = "GetFixed16" fn = "GetFixed16"
default: default:
fn = "Get"+typ fn = "Get" + typ
} }
return return
} }
@ -237,7 +236,7 @@ func addn(n int) (stmts []ast.Stmt) {
return addns(fmt.Sprint(n)) return addns(fmt.Sprint(n))
} }
func simplecall(fun string, args... string) *ast.ExprStmt { func simplecall(fun string, args ...string) *ast.ExprStmt {
_args := []ast.Expr{} _args := []ast.Expr{}
for _, s := range args { for _, s := range args {
_args = append(_args, ast.NewIdent(s)) _args = append(_args, ast.NewIdent(s))
@ -319,7 +318,7 @@ func getstructputgetlenfn(origfn *ast.FuncDecl, origname string) (decls []ast.De
getstmts = append(getstmts, &ast.ReturnStmt{}) getstmts = append(getstmts, &ast.ReturnStmt{})
decls = append(decls, &ast.FuncDecl{ decls = append(decls, &ast.FuncDecl{
Name: ast.NewIdent("Get"+origname), Name: ast.NewIdent("Get" + origname),
Type: &ast.FuncType{ Type: &ast.FuncType{
Params: &ast.FieldList{ Params: &ast.FieldList{
List: []*ast.Field{ List: []*ast.Field{
@ -336,7 +335,7 @@ func getstructputgetlenfn(origfn *ast.FuncDecl, origname string) (decls []ast.De
}) })
decls = append(decls, &ast.FuncDecl{ decls = append(decls, &ast.FuncDecl{
Name: ast.NewIdent("Put"+origname), Name: ast.NewIdent("Put" + origname),
Type: &ast.FuncType{ Type: &ast.FuncType{
Params: &ast.FieldList{ Params: &ast.FieldList{
List: []*ast.Field{ List: []*ast.Field{
@ -352,7 +351,7 @@ func getstructputgetlenfn(origfn *ast.FuncDecl, origname string) (decls []ast.De
Tok: token.CONST, Tok: token.CONST,
Specs: []ast.Spec{ Specs: []ast.Spec{
&ast.ValueSpec{ &ast.ValueSpec{
Names: []*ast.Ident{ast.NewIdent("Len"+origname)}, Names: []*ast.Ident{ast.NewIdent("Len" + origname)},
Values: []ast.Expr{ast.NewIdent(fmt.Sprint(totlen))}, Values: []ast.Expr{ast.NewIdent(fmt.Sprint(totlen))},
}, },
}, },
@ -431,7 +430,7 @@ func getatommarshalfn(origfn *ast.FuncDecl,
callmarshal := func(name string) (stmts []ast.Stmt) { callmarshal := func(name string) (stmts []ast.Stmt) {
callexpr := &ast.CallExpr{ callexpr := &ast.CallExpr{
Fun: ast.NewIdent(name+".Marshal"), Fun: ast.NewIdent(name + ".Marshal"),
Args: []ast.Expr{ast.NewIdent("b[n:]")}, Args: []ast.Expr{ast.NewIdent("b[n:]")},
} }
assign := &ast.AssignStmt{ assign := &ast.AssignStmt{
@ -459,7 +458,7 @@ func getatommarshalfn(origfn *ast.FuncDecl,
} }
calllenstruct := func(typ, name string) (stmts []ast.Stmt) { calllenstruct := func(typ, name string) (stmts []ast.Stmt) {
inc := typegetlens(typ)+"*len("+name+")" inc := typegetlens(typ) + "*len(" + name + ")"
stmts = append(stmts, &ast.AssignStmt{ stmts = append(stmts, &ast.AssignStmt{
Tok: token.ADD_ASSIGN, Tok: token.ADD_ASSIGN,
Lhs: []ast.Expr{ast.NewIdent("n")}, Lhs: []ast.Expr{ast.NewIdent("n")},
@ -470,7 +469,7 @@ func getatommarshalfn(origfn *ast.FuncDecl,
calllen := func(name string) (stmts []ast.Stmt) { calllen := func(name string) (stmts []ast.Stmt) {
callexpr := &ast.CallExpr{ callexpr := &ast.CallExpr{
Fun: ast.NewIdent(name+".Len"), Fun: ast.NewIdent(name + ".Len"),
Args: []ast.Expr{}, Args: []ast.Expr{},
} }
assign := &ast.AssignStmt{ assign := &ast.AssignStmt{
@ -574,7 +573,7 @@ func getatommarshalfn(origfn *ast.FuncDecl,
unmarshalatom := func(typ, init string) (stmts []ast.Stmt) { unmarshalatom := func(typ, init string) (stmts []ast.Stmt) {
return []ast.Stmt{ return []ast.Stmt{
&ast.AssignStmt{Tok: token.DEFINE, &ast.AssignStmt{Tok: token.DEFINE,
Lhs: []ast.Expr{ast.NewIdent("atom")}, Rhs: []ast.Expr{ast.NewIdent("&"+typ+"{"+init+"}")}, Lhs: []ast.Expr{ast.NewIdent("atom")}, Rhs: []ast.Expr{ast.NewIdent("&" + typ + "{" + init + "}")},
}, },
&ast.IfStmt{ &ast.IfStmt{
Init: &ast.AssignStmt{ Init: &ast.AssignStmt{
@ -591,10 +590,10 @@ func getatommarshalfn(origfn *ast.FuncDecl,
unmrashalatoms := func() (stmts []ast.Stmt) { unmrashalatoms := func() (stmts []ast.Stmt) {
blocks := []ast.Stmt{} blocks := []ast.Stmt{}
blocks = append(blocks, &ast.AssignStmt{ Tok: token.DEFINE, Lhs: []ast.Expr{ast.NewIdent("tag")}, blocks = append(blocks, &ast.AssignStmt{Tok: token.DEFINE, Lhs: []ast.Expr{ast.NewIdent("tag")},
Rhs: []ast.Expr{ast.NewIdent("Tag(pio.U32BE(b[n+4:]))")}, Rhs: []ast.Expr{ast.NewIdent("Tag(pio.U32BE(b[n+4:]))")},
}) })
blocks = append(blocks, &ast.AssignStmt{ Tok: token.DEFINE, Lhs: []ast.Expr{ast.NewIdent("size")}, blocks = append(blocks, &ast.AssignStmt{Tok: token.DEFINE, Lhs: []ast.Expr{ast.NewIdent("size")},
Rhs: []ast.Expr{ast.NewIdent("int(pio.U32BE(b[n:]))")}, Rhs: []ast.Expr{ast.NewIdent("int(pio.U32BE(b[n:]))")},
}) })
blocks = append(blocks, &ast.IfStmt{ blocks = append(blocks, &ast.IfStmt{
@ -614,7 +613,7 @@ func getatommarshalfn(origfn *ast.FuncDecl,
} }
for i, atom := range atomarrnames { for i, atom := range atomarrnames {
selfatom := "self."+atom selfatom := "self." + atom
cases = append(cases, &ast.CaseClause{ cases = append(cases, &ast.CaseClause{
List: []ast.Expr{ast.NewIdent(strings.ToUpper(struct2tag(atomarrtypes[i])))}, List: []ast.Expr{ast.NewIdent(strings.ToUpper(struct2tag(atomarrtypes[i])))},
Body: []ast.Stmt{&ast.BlockStmt{ Body: []ast.Stmt{&ast.BlockStmt{
@ -695,7 +694,7 @@ func getatommarshalfn(origfn *ast.FuncDecl,
Cond: &ast.BinaryExpr{ Cond: &ast.BinaryExpr{
X: ast.NewIdent("len(b)"), X: ast.NewIdent("len(b)"),
Op: token.LSS, Op: token.LSS,
Y: ast.NewIdent("n+"+inc), Y: ast.NewIdent("n+" + inc),
}, },
Body: &ast.BlockStmt{List: parseerrreturn(debug)}, Body: &ast.BlockStmt{List: parseerrreturn(debug)},
}) })
@ -710,16 +709,16 @@ func getatommarshalfn(origfn *ast.FuncDecl,
} }
checkstructlendo := func(typ, name, debug string, checkstructlendo := func(typ, name, debug string,
foreach func(string,[]ast.Stmt)[]ast.Stmt, foreach func(string, []ast.Stmt) []ast.Stmt,
) (stmts []ast.Stmt) { ) (stmts []ast.Stmt) {
inc := typegetlens(typ)+"*len("+name+")" inc := typegetlens(typ) + "*len(" + name + ")"
stmts = append(stmts, checkcurlen(inc, debug)...) stmts = append(stmts, checkcurlen(inc, debug)...)
stmts = append(stmts, foreach(name, append( stmts = append(stmts, foreach(name, append(
[]ast.Stmt{ []ast.Stmt{
&ast.AssignStmt{ &ast.AssignStmt{
Tok: token.ASSIGN, Tok: token.ASSIGN,
Lhs: []ast.Expr{ Lhs: []ast.Expr{
ast.NewIdent(name+"[i]"), ast.NewIdent(name + "[i]"),
}, },
Rhs: []ast.Expr{ Rhs: []ast.Expr{
&ast.CallExpr{ &ast.CallExpr{
@ -1054,4 +1053,3 @@ func main() {
genatoms(os.Args[2], os.Args[3]) genatoms(os.Args[2], os.Args[3])
} }
} }

View File

@ -434,4 +434,3 @@ func tfdt_TrackFragDecodeTime() {
} }
})) }))
} }

View File

@ -1,14 +1,13 @@
package mp4io package mp4io
import ( import (
"github.com/datarhei/joy4/utils/bits/pio"
"os"
"io"
"fmt" "fmt"
"time" "github.com/datarhei/joy4/utils/bits/pio"
"io"
"math" "math"
"os"
"strings" "strings"
"time"
) )
type ParseError struct { type ParseError struct {
@ -22,7 +21,7 @@ func (self *ParseError) Error() string {
for p := self; p != nil; p = p.prev { for p := self; p != nil; p = p.prev {
s = append(s, fmt.Sprintf("%s:%d", p.Debug, p.Offset)) s = append(s, fmt.Sprintf("%s:%d", p.Debug, p.Offset))
} }
return "mp4io: parse error: "+strings.Join(s, ",") return "mp4io: parse error: " + strings.Join(s, ",")
} }
func parseErr(debug string, offset int, prev error) (err error) { func parseErr(debug string, offset int, prev error) (err error) {
@ -33,37 +32,37 @@ func parseErr(debug string, offset int, prev error) (err error) {
func GetTime32(b []byte) (t time.Time) { func GetTime32(b []byte) (t time.Time) {
sec := pio.U32BE(b) sec := pio.U32BE(b)
t = time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC) t = time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC)
t = t.Add(time.Second*time.Duration(sec)) t = t.Add(time.Second * time.Duration(sec))
return return
} }
func PutTime32(b []byte, t time.Time) { func PutTime32(b []byte, t time.Time) {
dur := t.Sub(time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC)) dur := t.Sub(time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC))
sec := uint32(dur/time.Second) sec := uint32(dur / time.Second)
pio.PutU32BE(b, sec) pio.PutU32BE(b, sec)
} }
func GetTime64(b []byte) (t time.Time) { func GetTime64(b []byte) (t time.Time) {
sec := pio.U64BE(b) sec := pio.U64BE(b)
t = time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC) t = time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC)
t = t.Add(time.Second*time.Duration(sec)) t = t.Add(time.Second * time.Duration(sec))
return return
} }
func PutTime64(b []byte, t time.Time) { func PutTime64(b []byte, t time.Time) {
dur := t.Sub(time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC)) dur := t.Sub(time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC))
sec := uint64(dur/time.Second) sec := uint64(dur / time.Second)
pio.PutU64BE(b, sec) pio.PutU64BE(b, sec)
} }
func PutFixed16(b []byte, f float64) { func PutFixed16(b []byte, f float64) {
intpart, fracpart := math.Modf(f) intpart, fracpart := math.Modf(f)
b[0] = uint8(intpart) b[0] = uint8(intpart)
b[1] = uint8(fracpart*256.0) b[1] = uint8(fracpart * 256.0)
} }
func GetFixed16(b []byte) float64 { func GetFixed16(b []byte) float64 {
return float64(b[0])+float64(b[1])/256.0 return float64(b[0]) + float64(b[1])/256.0
} }
func PutFixed32(b []byte, f float64) { func PutFixed32(b []byte, f float64) {
@ -73,7 +72,7 @@ func PutFixed32(b []byte, f float64) {
} }
func GetFixed32(b []byte) float64 { func GetFixed32(b []byte) float64 {
return float64(pio.U16BE(b[0:2]))+float64(pio.U16BE(b[2:4]))/65536.0 return float64(pio.U16BE(b[0:2])) + float64(pio.U16BE(b[2:4]))/65536.0
} }
type Tag uint32 type Tag uint32
@ -89,11 +88,11 @@ func (self Tag) String() string {
return string(b[:]) return string(b[:])
} }
type Atom interface{ type Atom interface {
Pos() (int,int) Pos() (int, int)
Tag() Tag Tag() Tag
Marshal([]byte) int Marshal([]byte) int
Unmarshal([]byte, int) (int,error) Unmarshal([]byte, int) (int, error)
Len() int Len() int
Children() []Atom Children() []Atom
} }
@ -103,7 +102,7 @@ type AtomPos struct {
Size int Size int
} }
func (self AtomPos) Pos() (int,int) { func (self AtomPos) Pos() (int, int) {
return self.Offset, self.Size return self.Offset, self.Size
} }
@ -200,10 +199,10 @@ func (self ElemStreamDesc) Children() []Atom {
func (self ElemStreamDesc) fillLength(b []byte, length int) (n int) { func (self ElemStreamDesc) fillLength(b []byte, length int) (n int) {
for i := 3; i > 0; i-- { for i := 3; i > 0; i-- {
b[n] = uint8(length>>uint(7*i))&0x7f|0x80 b[n] = uint8(length>>uint(7*i))&0x7f | 0x80
n++ n++
} }
b[n] = uint8(length&0x7f) b[n] = uint8(length & 0x7f)
n++ n++
return return
} }
@ -220,7 +219,7 @@ func (self ElemStreamDesc) fillDescHdr(b []byte, tag uint8, datalen int) (n int)
} }
func (self ElemStreamDesc) lenESDescHdr() (n int) { func (self ElemStreamDesc) lenESDescHdr() (n int) {
return self.lenDescHdr()+3 return self.lenDescHdr() + 3
} }
func (self ElemStreamDesc) fillESDescHdr(b []byte, datalen int) (n int) { func (self ElemStreamDesc) fillESDescHdr(b []byte, datalen int) (n int) {
@ -233,7 +232,7 @@ func (self ElemStreamDesc) fillESDescHdr(b []byte, datalen int) (n int) {
} }
func (self ElemStreamDesc) lenDecConfigDescHdr() (n int) { func (self ElemStreamDesc) lenDecConfigDescHdr() (n int) {
return self.lenDescHdr()+2+3+4+4+self.lenDescHdr() return self.lenDescHdr() + 2 + 3 + 4 + 4 + self.lenDescHdr()
} }
func (self ElemStreamDesc) fillDecConfigDescHdr(b []byte, datalen int) (n int) { func (self ElemStreamDesc) fillDecConfigDescHdr(b []byte, datalen int) (n int) {
@ -256,7 +255,7 @@ func (self ElemStreamDesc) fillDecConfigDescHdr(b []byte, datalen int) (n int) {
} }
func (self ElemStreamDesc) Len() (n int) { func (self ElemStreamDesc) Len() (n int) {
return 8+4+self.lenESDescHdr()+self.lenDecConfigDescHdr()+len(self.DecConfig)+self.lenDescHdr()+1 return 8 + 4 + self.lenESDescHdr() + self.lenDecConfigDescHdr() + len(self.DecConfig) + self.lenDescHdr() + 1
} }
// Version(4) // Version(4)
@ -328,7 +327,7 @@ func (self *ElemStreamDesc) parseDesc(b []byte, offset int) (n int, err error) {
} }
case MP4DecConfigDescrTag: case MP4DecConfigDescrTag:
const size = 2+3+4+4 const size = 2 + 3 + 4 + 4
if len(b) < n+size { if len(b) < n+size {
err = parseErr("MP4DecSpecificDescrTag", offset+n, err) err = parseErr("MP4DecSpecificDescrTag", offset+n, err)
return return
@ -353,7 +352,7 @@ func (self *ElemStreamDesc) parseLength(b []byte, offset int) (n int, length int
} }
c := b[n] c := b[n]
n++ n++
length = (length<<7)|(int(c)&0x7f) length = (length << 7) | (int(c) & 0x7f)
if c&0x80 == 0 { if c&0x80 == 0 {
break break
} }
@ -500,4 +499,3 @@ func (self *Track) GetElemStreamDesc() (esds *ElemStreamDesc) {
esds, _ = atom.(*ElemStreamDesc) esds, _ = atom.(*ElemStreamDesc)
return return
} }

View File

@ -1,15 +1,15 @@
package mp4 package mp4
import ( import (
"bufio"
"fmt" "fmt"
"time"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/codec/aacparser" "github.com/datarhei/joy4/codec/aacparser"
"github.com/datarhei/joy4/codec/h264parser" "github.com/datarhei/joy4/codec/h264parser"
"github.com/datarhei/joy4/format/mp4/mp4io" "github.com/datarhei/joy4/format/mp4/mp4io"
"github.com/datarhei/joy4/utils/bits/pio" "github.com/datarhei/joy4/utils/bits/pio"
"io" "io"
"bufio" "time"
) )
type Muxer struct { type Muxer struct {
@ -54,7 +54,7 @@ func (self *Muxer) newStream(codec av.CodecData) (err error) {
stream.trackAtom = &mp4io.Track{ stream.trackAtom = &mp4io.Track{
Header: &mp4io.TrackHeader{ Header: &mp4io.TrackHeader{
TrackId: int32(len(self.streams)+1), TrackId: int32(len(self.streams) + 1),
Flags: 0x0003, // Track enabled | Track in movie Flags: 0x0003, // Track enabled | Track in movie
Duration: 0, // fill later Duration: 0, // fill later
Matrix: [9]int32{0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000}, Matrix: [9]int32{0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000},
@ -109,7 +109,7 @@ func (self *Stream) fillTrackAtom() (err error) {
Conf: &mp4io.AVC1Conf{Data: codec.AVCDecoderConfRecordBytes()}, Conf: &mp4io.AVC1Conf{Data: codec.AVCDecoderConfRecordBytes()},
} }
self.trackAtom.Media.Handler = &mp4io.HandlerRefer{ self.trackAtom.Media.Handler = &mp4io.HandlerRefer{
SubType: [4]byte{'v','i','d','e'}, SubType: [4]byte{'v', 'i', 'd', 'e'},
Name: []byte("Video Media Handler"), Name: []byte("Video Media Handler"),
} }
self.trackAtom.Media.Info.Video = &mp4io.VideoMediaInfo{ self.trackAtom.Media.Info.Video = &mp4io.VideoMediaInfo{
@ -132,7 +132,7 @@ func (self *Stream) fillTrackAtom() (err error) {
self.trackAtom.Header.Volume = 1 self.trackAtom.Header.Volume = 1
self.trackAtom.Header.AlternateGroup = 1 self.trackAtom.Header.AlternateGroup = 1
self.trackAtom.Media.Handler = &mp4io.HandlerRefer{ self.trackAtom.Media.Handler = &mp4io.HandlerRefer{
SubType: [4]byte{'s','o','u','n'}, SubType: [4]byte{'s', 'o', 'u', 'n'},
Name: []byte("Sound Handler"), Name: []byte("Sound Handler"),
} }
self.trackAtom.Media.Info.Sound = &mp4io.SoundMediaInfo{} self.trackAtom.Media.Info.Sound = &mp4io.SoundMediaInfo{}

View File

@ -42,17 +42,17 @@ type Stream struct {
} }
func timeToTs(tm time.Duration, timeScale int64) int64 { func timeToTs(tm time.Duration, timeScale int64) int64 {
return int64(tm*time.Duration(timeScale) / time.Second) return int64(tm * time.Duration(timeScale) / time.Second)
} }
func tsToTime(ts int64, timeScale int64) time.Duration { func tsToTime(ts int64, timeScale int64) time.Duration {
return time.Duration(ts)*time.Second / time.Duration(timeScale) return time.Duration(ts) * time.Second / time.Duration(timeScale)
} }
func (self *Stream) timeToTs(tm time.Duration) int64 { func (self *Stream) timeToTs(tm time.Duration) int64 {
return int64(tm*time.Duration(self.timeScale) / time.Second) return int64(tm * time.Duration(self.timeScale) / time.Second)
} }
func (self *Stream) tsToTime(ts int64) time.Duration { func (self *Stream) tsToTime(ts int64) time.Duration {
return time.Duration(ts)*time.Second / time.Duration(self.timeScale) return time.Duration(ts) * time.Second / time.Duration(self.timeScale)
} }

View File

@ -8,13 +8,13 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"github.com/datarhei/joy4/utils/bits/pio"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/avutil" "github.com/datarhei/joy4/av/avutil"
"github.com/datarhei/joy4/codec" "github.com/datarhei/joy4/codec"
"github.com/datarhei/joy4/codec/aacparser" "github.com/datarhei/joy4/codec/aacparser"
"github.com/datarhei/joy4/codec/h264parser" "github.com/datarhei/joy4/codec/h264parser"
"github.com/datarhei/joy4/format/rtsp/sdp" "github.com/datarhei/joy4/format/rtsp/sdp"
"github.com/datarhei/joy4/utils/bits/pio"
"io" "io"
"net" "net"
"net/textproto" "net/textproto"
@ -31,7 +31,7 @@ var DebugRtsp = false
var SkipErrRtpBlock = false var SkipErrRtpBlock = false
const ( const (
stageDescribeDone = iota+1 stageDescribeDone = iota + 1
stageSetupDone stageSetupDone
stageWaitCodecData stageWaitCodecData
stageCodecDataDone stageCodecDataDone
@ -121,7 +121,7 @@ func Dial(uri string) (self *Client, err error) {
} }
func (self *Client) allCodecDataReady() bool { func (self *Client) allCodecDataReady() bool {
for _, si:= range self.setupIdx { for _, si := range self.setupIdx {
stream := self.streams[si] stream := self.streams[si]
if stream.CodecData == nil { if stream.CodecData == nil {
return false return false
@ -268,7 +268,7 @@ func (self *Client) parseBlockHeader(h []byte) (length int, no int, valid bool)
timestamp -= stream.firsttimestamp timestamp -= stream.firsttimestamp
if timestamp < stream.timestamp { if timestamp < stream.timestamp {
return return
} else if timestamp - stream.timestamp > uint32(stream.timeScale()*60*60) { } else if timestamp-stream.timestamp > uint32(stream.timeScale()*60*60) {
return return
} }
} }
@ -373,7 +373,7 @@ func (self *Client) handle401(res *Response) (err error) {
func (self *Client) findRTSP() (block []byte, data []byte, err error) { func (self *Client) findRTSP() (block []byte, data []byte, err error) {
const ( const (
R = iota+1 R = iota + 1
T T
S S
Header Header
@ -383,7 +383,7 @@ func (self *Client) findRTSP() (block []byte, data []byte, err error) {
peek := _peek[0:0] peek := _peek[0:0]
stat := 0 stat := 0
for i := 0;; i++ { for i := 0; ; i++ {
var b byte var b byte
if b, err = self.brconn.ReadByte(); err != nil { if b, err = self.brconn.ReadByte(); err != nil {
return return
@ -434,7 +434,7 @@ func (self *Client) findRTSP() (block []byte, data []byte, err error) {
fmt.Println("rtsp: dollar at", i, len(peek)) fmt.Println("rtsp: dollar at", i, len(peek))
} }
if blocklen, _, ok := self.parseBlockHeader(peek); ok { if blocklen, _, ok := self.parseBlockHeader(peek); ok {
left := blocklen+4-len(peek) left := blocklen + 4 - len(peek)
block = append(peek, make([]byte, left)...) block = append(peek, make([]byte, left)...)
if _, err = io.ReadFull(self.brconn, block[len(peek):]); err != nil { if _, err = io.ReadFull(self.brconn, block[len(peek):]); err != nil {
return return
@ -451,7 +451,7 @@ func (self *Client) findRTSP() (block []byte, data []byte, err error) {
func (self *Client) readLFLF() (block []byte, data []byte, err error) { func (self *Client) readLFLF() (block []byte, data []byte, err error) {
const ( const (
LF = iota+1 LF = iota + 1
LFLF LFLF
) )
peek := []byte{} peek := []byte{}
@ -471,7 +471,7 @@ func (self *Client) readLFLF() (block []byte, data []byte, err error) {
stat = LF stat = LF
lpos = pos lpos = pos
} else if stat == LF { } else if stat == LF {
if pos - lpos <= 2 { if pos-lpos <= 2 {
stat = LFLF stat = LFLF
} else { } else {
lpos = pos lpos = pos
@ -485,9 +485,9 @@ func (self *Client) readLFLF() (block []byte, data []byte, err error) {
if stat == LFLF { if stat == LFLF {
data = peek data = peek
return return
} else if dollarpos != -1 && dollarpos - pos >= 12 { } else if dollarpos != -1 && dollarpos-pos >= 12 {
hdrlen := dollarpos-pos hdrlen := dollarpos - pos
start := len(peek)-hdrlen start := len(peek) - hdrlen
if blocklen, _, ok := self.parseBlockHeader(peek[start:]); ok { if blocklen, _, ok := self.parseBlockHeader(peek[start:]); ok {
block = append(peek[start:], make([]byte, blocklen+4-hdrlen)...) block = append(peek[start:], make([]byte, blocklen+4-hdrlen)...)
if _, err = io.ReadFull(self.brconn, block[hdrlen:]); err != nil { if _, err = io.ReadFull(self.brconn, block[hdrlen:]); err != nil {
@ -810,7 +810,7 @@ func (self *Stream) handleH264Payload(timestamp uint32, packet []byte) (err erro
return return
} }
naluType := packet[0]&0x1f naluType := packet[0] & 0x1f
/* /*
Table 7-1 NAL unit type codes Table 7-1 NAL unit type codes
@ -963,7 +963,7 @@ func (self *Stream) handleH264Payload(timestamp uint32, packet []byte) (err erro
*/ */
packet = packet[1:] packet = packet[1:]
for len(packet) >= 2 { for len(packet) >= 2 {
size := int(packet[0])<<8|int(packet[1]) size := int(packet[0])<<8 | int(packet[1])
if size+2 > len(packet) { if size+2 > len(packet) {
break break
} }
@ -1141,7 +1141,7 @@ func (self *Client) handleBlock(block []byte) (pkt av.Packet, ok bool, err error
return return
} }
i := blockno/2 i := blockno / 2
if i >= len(self.streams) { if i >= len(self.streams) {
err = fmt.Errorf("rtsp: block no=%d invalid", blockno) err = fmt.Errorf("rtsp: block no=%d invalid", blockno)
return return
@ -1171,10 +1171,10 @@ func (self *Client) handleBlock(block []byte) (pkt av.Packet, ok bool, err error
ok = true ok = true
pkt = stream.pkt pkt = stream.pkt
pkt.Time = time.Duration(stream.timestamp)*time.Second / time.Duration(stream.timeScale()) pkt.Time = time.Duration(stream.timestamp) * time.Second / time.Duration(stream.timeScale())
pkt.Idx = int8(self.setupMap[i]) pkt.Idx = int8(self.setupMap[i])
if pkt.Time < stream.lasttime || pkt.Time - stream.lasttime > time.Minute*30 { if pkt.Time < stream.lasttime || pkt.Time-stream.lasttime > time.Minute*30 {
err = fmt.Errorf("rtp: time invalid stream#%d time=%v lasttime=%v", pkt.Idx, pkt.Time, stream.lasttime) err = fmt.Errorf("rtp: time invalid stream#%d time=%v lasttime=%v", pkt.Idx, pkt.Time, stream.lasttime)
return return
} }
@ -1236,4 +1236,3 @@ func Handler(h *avutil.RegisterHandler) {
return return
} }
} }

View File

@ -26,4 +26,3 @@ type Stream struct {
lasttime time.Duration lasttime time.Duration
} }

View File

@ -3,13 +3,13 @@ package ts
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"time"
"github.com/datarhei/joy4/utils/bits/pio"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/format/ts/tsio"
"github.com/datarhei/joy4/codec/aacparser" "github.com/datarhei/joy4/codec/aacparser"
"github.com/datarhei/joy4/codec/h264parser" "github.com/datarhei/joy4/codec/h264parser"
"github.com/datarhei/joy4/format/ts/tsio"
"github.com/datarhei/joy4/utils/bits/pio"
"io" "io"
"time"
) )
type Demuxer struct { type Demuxer struct {
@ -101,7 +101,7 @@ func (self *Demuxer) initPMT(payload []byte) (err error) {
return return
} }
self.pmt = &tsio.PMT{} self.pmt = &tsio.PMT{}
if _, err = self.pmt.Unmarshal(payload[psihdrlen:psihdrlen+datalen]); err != nil { if _, err = self.pmt.Unmarshal(payload[psihdrlen : psihdrlen+datalen]); err != nil {
return return
} }
@ -156,7 +156,7 @@ func (self *Demuxer) readTSPacket() (err error) {
return return
} }
self.pat = &tsio.PAT{} self.pat = &tsio.PAT{}
if _, err = self.pat.Unmarshal(payload[psihdrlen:psihdrlen+datalen]); err != nil { if _, err = self.pat.Unmarshal(payload[psihdrlen : psihdrlen+datalen]); err != nil {
return return
} }
} }
@ -194,11 +194,11 @@ func (self *Stream) addPacket(payload []byte, timedelta time.Duration) {
pkt := av.Packet{ pkt := av.Packet{
Idx: int8(self.idx), Idx: int8(self.idx),
IsKeyFrame: self.iskeyframe, IsKeyFrame: self.iskeyframe,
Time: dts+timedelta, Time: dts + timedelta,
Data: payload, Data: payload,
} }
if pts != dts { if pts != dts {
pkt.CompositionTime = pts-dts pkt.CompositionTime = pts - dts
} }
demuxer.pkts = append(demuxer.pkts, pkt) demuxer.pkts = append(demuxer.pkts, pkt)
} }

View File

@ -1,9 +1,9 @@
package ts package ts
import ( import (
"io"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/av/avutil" "github.com/datarhei/joy4/av/avutil"
"io"
) )
func Handler(h *avutil.RegisterHandler) { func Handler(h *avutil.RegisterHandler) {
@ -23,4 +23,3 @@ func Handler(h *avutil.RegisterHandler) {
h.CodecTypes = CodecTypes h.CodecTypes = CodecTypes
} }

View File

@ -1,9 +1,9 @@
package ts package ts
import ( import (
"time"
"github.com/datarhei/joy4/av" "github.com/datarhei/joy4/av"
"github.com/datarhei/joy4/format/ts/tsio" "github.com/datarhei/joy4/format/ts/tsio"
"time"
) )
type Stream struct { type Stream struct {
@ -24,4 +24,3 @@ type Stream struct {
data []byte data []byte
datalen int datalen int
} }

View File

@ -52,4 +52,3 @@ func calcCRC32(crc uint32, data []byte) uint32 {
} }
return crc return crc
} }

View File

@ -1,11 +1,10 @@
package tsio package tsio
import ( import (
"io"
"time"
"fmt" "fmt"
"github.com/datarhei/joy4/utils/bits/pio" "github.com/datarhei/joy4/utils/bits/pio"
"io"
"time"
) )
const ( const (
@ -48,7 +47,7 @@ type PAT struct {
} }
func (self PAT) Len() (n int) { func (self PAT) Len() (n int) {
return len(self.Entries)*4 return len(self.Entries) * 4
} }
func (self PAT) Marshal(b []byte) (n int) { func (self PAT) Marshal(b []byte) (n int) {
@ -73,10 +72,10 @@ func (self *PAT) Unmarshal(b []byte) (n int, err error) {
entry.ProgramNumber = pio.U16BE(b[n:]) entry.ProgramNumber = pio.U16BE(b[n:])
n += 2 n += 2
if entry.ProgramNumber == 0 { if entry.ProgramNumber == 0 {
entry.NetworkPID = pio.U16BE(b[n:])&0x1fff entry.NetworkPID = pio.U16BE(b[n:]) & 0x1fff
n += 2 n += 2
} else { } else {
entry.ProgramMapPID = pio.U16BE(b[n:])&0x1fff entry.ProgramMapPID = pio.U16BE(b[n:]) & 0x1fff
n += 2 n += 2
} }
self.Entries = append(self.Entries, entry) self.Entries = append(self.Entries, entry)
@ -117,7 +116,7 @@ func (self PMT) Len() (n int) {
n += 2 n += 2
for _, desc := range self.ProgramDescriptors { for _, desc := range self.ProgramDescriptors {
n += 2+len(desc.Data) n += 2 + len(desc.Data)
} }
for _, info := range self.ElementaryStreamInfos { for _, info := range self.ElementaryStreamInfos {
@ -133,7 +132,7 @@ func (self PMT) Len() (n int) {
n += 2 n += 2
for _, desc := range info.Descriptors { for _, desc := range info.Descriptors {
n += 2+len(desc.Data) n += 2 + len(desc.Data)
} }
} }
@ -162,7 +161,7 @@ func (self PMT) Marshal(b []byte) (n int) {
n += 2 n += 2
pos := n pos := n
n += self.fillDescs(b[n:], self.ProgramDescriptors) n += self.fillDescs(b[n:], self.ProgramDescriptors)
desclen := n-pos desclen := n - pos
pio.PutU16BE(b[hold:], uint16(desclen)|0xf<<12) pio.PutU16BE(b[hold:], uint16(desclen)|0xf<<12)
for _, info := range self.ElementaryStreamInfos { for _, info := range self.ElementaryStreamInfos {
@ -178,7 +177,7 @@ func (self PMT) Marshal(b []byte) (n int) {
n += 2 n += 2
pos := n pos := n
n += self.fillDescs(b[n:], info.Descriptors) n += self.fillDescs(b[n:], info.Descriptors)
desclen := n-pos desclen := n - pos
pio.PutU16BE(b[hold:], uint16(desclen)|0x3c<<10) pio.PutU16BE(b[hold:], uint16(desclen)|0x3c<<10)
} }
@ -219,13 +218,13 @@ func (self *PMT) Unmarshal(b []byte) (n int, err error) {
// 111(3) // 111(3)
// PCRPID(13) // PCRPID(13)
self.PCRPID = pio.U16BE(b[0:2])&0x1fff self.PCRPID = pio.U16BE(b[0:2]) & 0x1fff
n += 2 n += 2
// Reserved(4)=0xf // Reserved(4)=0xf
// Reserved(2)=0x0 // Reserved(2)=0x0
// Program info length(10) // Program info length(10)
desclen := int(pio.U16BE(b[2:4])&0x3ff) desclen := int(pio.U16BE(b[2:4]) & 0x3ff)
n += 2 n += 2
if desclen > 0 { if desclen > 0 {
@ -233,7 +232,7 @@ func (self *PMT) Unmarshal(b []byte) (n int, err error) {
err = ErrParsePMT err = ErrParsePMT
return return
} }
if self.ProgramDescriptors, err = self.parseDescs(b[n:n+desclen]); err != nil { if self.ProgramDescriptors, err = self.parseDescs(b[n : n+desclen]); err != nil {
return return
} }
n += desclen n += desclen
@ -251,12 +250,12 @@ func (self *PMT) Unmarshal(b []byte) (n int, err error) {
// Reserved(3) // Reserved(3)
// Elementary PID(13) // Elementary PID(13)
info.ElementaryPID = pio.U16BE(b[n:])&0x1fff info.ElementaryPID = pio.U16BE(b[n:]) & 0x1fff
n += 2 n += 2
// Reserved(6) // Reserved(6)
// ES Info length(10) // ES Info length(10)
desclen := int(pio.U16BE(b[n:])&0x3ff) desclen := int(pio.U16BE(b[n:]) & 0x3ff)
n += 2 n += 2
if desclen > 0 { if desclen > 0 {
@ -264,7 +263,7 @@ func (self *PMT) Unmarshal(b []byte) (n int, err error) {
err = ErrParsePMT err = ErrParsePMT
return return
} }
if info.Descriptors, err = self.parseDescs(b[n:n+desclen]); err != nil { if info.Descriptors, err = self.parseDescs(b[n : n+desclen]); err != nil {
return return
} }
n += desclen n += desclen
@ -345,7 +344,7 @@ func FillPSI(h []byte, tableid uint8, tableext uint16, datalen int) (n int) {
n++ n++
// section_syntax_indicator(1)=1,private_bit(1)=0,reserved(2)=3,unused(2)=0,section_length(10) // section_syntax_indicator(1)=1,private_bit(1)=0,reserved(2)=3,unused(2)=0,section_length(10)
pio.PutU16BE(h[n:], uint16(0xa<<12 | 2+3+4+datalen)) pio.PutU16BE(h[n:], uint16(0xa<<12|2+3+4+datalen))
n += 2 n += 2
// Table ID extension(16) // Table ID extension(16)
@ -375,7 +374,7 @@ func FillPSI(h []byte, tableid uint8, tableext uint16, datalen int) (n int) {
func TimeToPCR(tm time.Duration) (pcr uint64) { func TimeToPCR(tm time.Duration) (pcr uint64) {
// base(33)+resverd(6)+ext(9) // base(33)+resverd(6)+ext(9)
ts := uint64(tm*PCR_HZ/time.Second) ts := uint64(tm * PCR_HZ / time.Second)
base := ts / 300 base := ts / 300
ext := ts % 300 ext := ts % 300
pcr = base<<15 | 0x3f<<9 | ext pcr = base<<15 | 0x3f<<9 | ext
@ -386,12 +385,12 @@ func PCRToTime(pcr uint64) (tm time.Duration) {
base := pcr >> 15 base := pcr >> 15
ext := pcr & 0x1ff ext := pcr & 0x1ff
ts := base*300 + ext ts := base*300 + ext
tm = time.Duration(ts)*time.Second/time.Duration(PCR_HZ) tm = time.Duration(ts) * time.Second / time.Duration(PCR_HZ)
return return
} }
func TimeToTs(tm time.Duration) (v uint64) { func TimeToTs(tm time.Duration) (v uint64) {
ts := uint64(tm*PTS_HZ/time.Second) ts := uint64(tm * PTS_HZ / time.Second)
// 0010 PTS 32..30 1 PTS 29..15 1 PTS 14..00 1 // 0010 PTS 32..30 1 PTS 29..15 1 PTS 14..00 1
v = ((ts>>30)&0x7)<<33 | ((ts>>15)&0x7fff)<<17 | (ts&0x7fff)<<1 | 0x100010001 v = ((ts>>30)&0x7)<<33 | ((ts>>15)&0x7fff)<<17 | (ts&0x7fff)<<1 | 0x100010001
return return
@ -399,8 +398,8 @@ func TimeToTs(tm time.Duration) (v uint64) {
func TsToTime(v uint64) (tm time.Duration) { func TsToTime(v uint64) (tm time.Duration) {
// 0010 PTS 32..30 1 PTS 29..15 1 PTS 14..00 1 // 0010 PTS 32..30 1 PTS 29..15 1 PTS 14..00 1
ts := (((v>>33)&0x7)<<30) | (((v>>17)&0x7fff) << 15) | ((v>>1)&0x7fff) ts := (((v >> 33) & 0x7) << 30) | (((v >> 17) & 0x7fff) << 15) | ((v >> 1) & 0x7fff)
tm = time.Duration(ts)*time.Second/time.Duration(PTS_HZ) tm = time.Duration(ts) * time.Second / time.Duration(PTS_HZ)
return return
} }
@ -417,11 +416,11 @@ func ParsePESHeader(h []byte) (hdrlen int, streamid uint8, datalen int, pts, dts
streamid = h[3] streamid = h[3]
flags := h[7] flags := h[7]
hdrlen = int(h[8])+9 hdrlen = int(h[8]) + 9
datalen = int(pio.U16BE(h[4:6])) datalen = int(pio.U16BE(h[4:6]))
if datalen > 0 { if datalen > 0 {
datalen -= int(h[8])+3 datalen -= int(h[8]) + 3
} }
const PTS = 1 << 7 const PTS = 1 << 7
@ -479,7 +478,7 @@ func FillPESHeader(h []byte, streamid uint8, datalen int, pts, dts time.Duration
} }
pio.PutU16BE(h[4:6], pktlen) pio.PutU16BE(h[4:6], pktlen)
h[6] = 2<<6|1 // resverd(6,2)=2,original_or_copy(0,1)=1 h[6] = 2<<6 | 1 // resverd(6,2)=2,original_or_copy(0,1)=1
h[7] = flags h[7] = flags
h[8] = uint8(n) h[8] = uint8(n)
@ -521,21 +520,21 @@ func (self *TSWriter) WritePackets(w io.Writer, datav [][]byte, pcr time.Duratio
writepos := 0 writepos := 0
for writepos < datavlen { for writepos < datavlen {
self.tshdr[1] = self.tshdr[1]&0x1f self.tshdr[1] = self.tshdr[1] & 0x1f
self.tshdr[3] = byte(self.ContinuityCounter)&0xf|0x30 self.tshdr[3] = byte(self.ContinuityCounter)&0xf | 0x30
self.tshdr[5] = 0 // flags self.tshdr[5] = 0 // flags
hdrlen := 6 hdrlen := 6
self.ContinuityCounter++ self.ContinuityCounter++
if writepos == 0 { if writepos == 0 {
self.tshdr[1] = 0x40|self.tshdr[1] // Payload Unit Start Indicator self.tshdr[1] = 0x40 | self.tshdr[1] // Payload Unit Start Indicator
if pcr != 0 { if pcr != 0 {
hdrlen += 6 hdrlen += 6
self.tshdr[5] = 0x10|self.tshdr[5] // PCR flag (Discontinuity indicator 0x80) self.tshdr[5] = 0x10 | self.tshdr[5] // PCR flag (Discontinuity indicator 0x80)
pio.PutU48BE(self.tshdr[6:12], TimeToPCR(pcr)) pio.PutU48BE(self.tshdr[6:12], TimeToPCR(pcr))
} }
if sync { if sync {
self.tshdr[5] = 0x40|self.tshdr[5] // Random Access indicator self.tshdr[5] = 0x40 | self.tshdr[5] // Random Access indicator
} }
} }
@ -551,7 +550,7 @@ func (self *TSWriter) WritePackets(w io.Writer, datav [][]byte, pcr time.Duratio
} }
n := pio.VecSliceTo(datav, writev, writepos, end) n := pio.VecSliceTo(datav, writev, writepos, end)
self.tshdr[4] = byte(hdrlen)-5 // length self.tshdr[4] = byte(hdrlen) - 5 // length
if _, err = w.Write(self.tshdr[:hdrlen]); err != nil { if _, err = w.Write(self.tshdr[:hdrlen]); err != nil {
return return
} }
@ -561,7 +560,7 @@ func (self *TSWriter) WritePackets(w io.Writer, datav [][]byte, pcr time.Duratio
} }
} }
if padtail > 0 { if padtail > 0 {
if _, err = w.Write(self.tshdr[188-padtail:188]); err != nil { if _, err = w.Write(self.tshdr[188-padtail : 188]); err != nil {
return return
} }
} }
@ -578,13 +577,12 @@ func ParseTSHeader(tshdr []byte) (pid uint16, start bool, iskeyframe bool, hdrle
err = fmt.Errorf("tshdr sync invalid") err = fmt.Errorf("tshdr sync invalid")
return return
} }
pid = uint16((tshdr[1]&0x1f))<<8|uint16(tshdr[2]) pid = uint16((tshdr[1]&0x1f))<<8 | uint16(tshdr[2])
start = tshdr[1]&0x40 != 0 start = tshdr[1]&0x40 != 0
hdrlen += 4 hdrlen += 4
if tshdr[3]&0x20 != 0 { if tshdr[3]&0x20 != 0 {
hdrlen += int(tshdr[4])+1 hdrlen += int(tshdr[4]) + 1
iskeyframe = tshdr[5]&0x40 != 0 iskeyframe = tshdr[5]&0x40 != 0
} }
return return
} }

View File

@ -20,4 +20,3 @@ func NewReaderSize(r io.ReadSeeker, size int) *Reader {
func (self *Reader) ReadAt(b []byte, off int64) (n int, err error) { func (self *Reader) ReadAt(b []byte, off int64) (n int, err error) {
return return
} }

View File

@ -1,5 +1,3 @@
package pio package pio
var RecommendBufioSize = 1024*64 var RecommendBufioSize = 1024 * 64

View File

@ -1,4 +1,3 @@
package pio package pio
func U8(b []byte) (i uint8) { func U8(b []byte) (i uint8) {
@ -7,85 +6,116 @@ func U8(b []byte) (i uint8) {
func U16BE(b []byte) (i uint16) { func U16BE(b []byte) (i uint16) {
i = uint16(b[0]) i = uint16(b[0])
i <<= 8; i |= uint16(b[1]) i <<= 8
i |= uint16(b[1])
return return
} }
func I16BE(b []byte) (i int16) { func I16BE(b []byte) (i int16) {
i = int16(b[0]) i = int16(b[0])
i <<= 8; i |= int16(b[1]) i <<= 8
i |= int16(b[1])
return return
} }
func I24BE(b []byte) (i int32) { func I24BE(b []byte) (i int32) {
i = int32(int8(b[0])) i = int32(int8(b[0]))
i <<= 8; i |= int32(b[1]) i <<= 8
i <<= 8; i |= int32(b[2]) i |= int32(b[1])
i <<= 8
i |= int32(b[2])
return return
} }
func U24BE(b []byte) (i uint32) { func U24BE(b []byte) (i uint32) {
i = uint32(b[0]) i = uint32(b[0])
i <<= 8; i |= uint32(b[1]) i <<= 8
i <<= 8; i |= uint32(b[2]) i |= uint32(b[1])
i <<= 8
i |= uint32(b[2])
return return
} }
func I32BE(b []byte) (i int32) { func I32BE(b []byte) (i int32) {
i = int32(int8(b[0])) i = int32(int8(b[0]))
i <<= 8; i |= int32(b[1]) i <<= 8
i <<= 8; i |= int32(b[2]) i |= int32(b[1])
i <<= 8; i |= int32(b[3]) i <<= 8
i |= int32(b[2])
i <<= 8
i |= int32(b[3])
return return
} }
func U32LE(b []byte) (i uint32) { func U32LE(b []byte) (i uint32) {
i = uint32(b[3]) i = uint32(b[3])
i <<= 8; i |= uint32(b[2]) i <<= 8
i <<= 8; i |= uint32(b[1]) i |= uint32(b[2])
i <<= 8; i |= uint32(b[0]) i <<= 8
i |= uint32(b[1])
i <<= 8
i |= uint32(b[0])
return return
} }
func U32BE(b []byte) (i uint32) { func U32BE(b []byte) (i uint32) {
i = uint32(b[0]) i = uint32(b[0])
i <<= 8; i |= uint32(b[1]) i <<= 8
i <<= 8; i |= uint32(b[2]) i |= uint32(b[1])
i <<= 8; i |= uint32(b[3]) i <<= 8
i |= uint32(b[2])
i <<= 8
i |= uint32(b[3])
return return
} }
func U40BE(b []byte) (i uint64) { func U40BE(b []byte) (i uint64) {
i = uint64(b[0]) i = uint64(b[0])
i <<= 8; i |= uint64(b[1]) i <<= 8
i <<= 8; i |= uint64(b[2]) i |= uint64(b[1])
i <<= 8; i |= uint64(b[3]) i <<= 8
i <<= 8; i |= uint64(b[4]) i |= uint64(b[2])
i <<= 8
i |= uint64(b[3])
i <<= 8
i |= uint64(b[4])
return return
} }
func U64BE(b []byte) (i uint64) { func U64BE(b []byte) (i uint64) {
i = uint64(b[0]) i = uint64(b[0])
i <<= 8; i |= uint64(b[1]) i <<= 8
i <<= 8; i |= uint64(b[2]) i |= uint64(b[1])
i <<= 8; i |= uint64(b[3]) i <<= 8
i <<= 8; i |= uint64(b[4]) i |= uint64(b[2])
i <<= 8; i |= uint64(b[5]) i <<= 8
i <<= 8; i |= uint64(b[6]) i |= uint64(b[3])
i <<= 8; i |= uint64(b[7]) i <<= 8
i |= uint64(b[4])
i <<= 8
i |= uint64(b[5])
i <<= 8
i |= uint64(b[6])
i <<= 8
i |= uint64(b[7])
return return
} }
func I64BE(b []byte) (i int64) { func I64BE(b []byte) (i int64) {
i = int64(int8(b[0])) i = int64(int8(b[0]))
i <<= 8; i |= int64(b[1]) i <<= 8
i <<= 8; i |= int64(b[2]) i |= int64(b[1])
i <<= 8; i |= int64(b[3]) i <<= 8
i <<= 8; i |= int64(b[4]) i |= int64(b[2])
i <<= 8; i |= int64(b[5]) i <<= 8
i <<= 8; i |= int64(b[6]) i |= int64(b[3])
i <<= 8; i |= int64(b[7]) i <<= 8
i |= int64(b[4])
i <<= 8
i |= int64(b[5])
i <<= 8
i |= int64(b[6])
i <<= 8
i |= int64(b[7])
return return
} }

View File

@ -38,12 +38,12 @@ func VecSliceTo(in [][]byte, out [][]byte, s int, e int) (n int) {
} }
for e != 0 && i < len(in) { for e != 0 && i < len(in) {
left := len(in[i])-off left := len(in[i]) - off
read := left read := left
if e > 0 && e < read { if e > 0 && e < read {
read = e read = e
} }
out[n] = in[i][off:off+read] out[n] = in[i][off : off+read]
n++ n++
left -= read left -= read
e -= read e -= read
@ -66,4 +66,3 @@ func VecSlice(in [][]byte, s int, e int) (out [][]byte) {
out = out[:n] out = out[:n]
return return
} }

View File

@ -1,4 +1,3 @@
package pio package pio
import ( import (
@ -6,7 +5,7 @@ import (
) )
func ExampleVec() { func ExampleVec() {
vec := [][]byte{[]byte{1,2,3}, []byte{4,5,6,7,8,9}, []byte{10,11,12,13}} vec := [][]byte{[]byte{1, 2, 3}, []byte{4, 5, 6, 7, 8, 9}, []byte{10, 11, 12, 13}}
println(VecLen(vec)) println(VecLen(vec))
vec = VecSlice(vec, 1, -1) vec = VecSlice(vec, 1, -1)

View File

@ -1,4 +1,3 @@
package pio package pio
func PutU8(b []byte, v uint8) { func PutU8(b []byte, v uint8) {
@ -6,84 +5,83 @@ func PutU8(b []byte, v uint8) {
} }
func PutI16BE(b []byte, v int16) { func PutI16BE(b []byte, v int16) {
b[0] = byte(v>>8) b[0] = byte(v >> 8)
b[1] = byte(v) b[1] = byte(v)
} }
func PutU16BE(b []byte, v uint16) { func PutU16BE(b []byte, v uint16) {
b[0] = byte(v>>8) b[0] = byte(v >> 8)
b[1] = byte(v) b[1] = byte(v)
} }
func PutI24BE(b []byte, v int32) { func PutI24BE(b []byte, v int32) {
b[0] = byte(v>>16) b[0] = byte(v >> 16)
b[1] = byte(v>>8) b[1] = byte(v >> 8)
b[2] = byte(v) b[2] = byte(v)
} }
func PutU24BE(b []byte, v uint32) { func PutU24BE(b []byte, v uint32) {
b[0] = byte(v>>16) b[0] = byte(v >> 16)
b[1] = byte(v>>8) b[1] = byte(v >> 8)
b[2] = byte(v) b[2] = byte(v)
} }
func PutI32BE(b []byte, v int32) { func PutI32BE(b []byte, v int32) {
b[0] = byte(v>>24) b[0] = byte(v >> 24)
b[1] = byte(v>>16) b[1] = byte(v >> 16)
b[2] = byte(v>>8) b[2] = byte(v >> 8)
b[3] = byte(v) b[3] = byte(v)
} }
func PutU32BE(b []byte, v uint32) { func PutU32BE(b []byte, v uint32) {
b[0] = byte(v>>24) b[0] = byte(v >> 24)
b[1] = byte(v>>16) b[1] = byte(v >> 16)
b[2] = byte(v>>8) b[2] = byte(v >> 8)
b[3] = byte(v) b[3] = byte(v)
} }
func PutU32LE(b []byte, v uint32) { func PutU32LE(b []byte, v uint32) {
b[3] = byte(v>>24) b[3] = byte(v >> 24)
b[2] = byte(v>>16) b[2] = byte(v >> 16)
b[1] = byte(v>>8) b[1] = byte(v >> 8)
b[0] = byte(v) b[0] = byte(v)
} }
func PutU40BE(b []byte, v uint64) { func PutU40BE(b []byte, v uint64) {
b[0] = byte(v>>32) b[0] = byte(v >> 32)
b[1] = byte(v>>24) b[1] = byte(v >> 24)
b[2] = byte(v>>16) b[2] = byte(v >> 16)
b[3] = byte(v>>8) b[3] = byte(v >> 8)
b[4] = byte(v) b[4] = byte(v)
} }
func PutU48BE(b []byte, v uint64) { func PutU48BE(b []byte, v uint64) {
b[0] = byte(v>>40) b[0] = byte(v >> 40)
b[1] = byte(v>>32) b[1] = byte(v >> 32)
b[2] = byte(v>>24) b[2] = byte(v >> 24)
b[3] = byte(v>>16) b[3] = byte(v >> 16)
b[4] = byte(v>>8) b[4] = byte(v >> 8)
b[5] = byte(v) b[5] = byte(v)
} }
func PutU64BE(b []byte, v uint64) { func PutU64BE(b []byte, v uint64) {
b[0] = byte(v>>56) b[0] = byte(v >> 56)
b[1] = byte(v>>48) b[1] = byte(v >> 48)
b[2] = byte(v>>40) b[2] = byte(v >> 40)
b[3] = byte(v>>32) b[3] = byte(v >> 32)
b[4] = byte(v>>24) b[4] = byte(v >> 24)
b[5] = byte(v>>16) b[5] = byte(v >> 16)
b[6] = byte(v>>8) b[6] = byte(v >> 8)
b[7] = byte(v) b[7] = byte(v)
} }
func PutI64BE(b []byte, v int64) { func PutI64BE(b []byte, v int64) {
b[0] = byte(v>>56) b[0] = byte(v >> 56)
b[1] = byte(v>>48) b[1] = byte(v >> 48)
b[2] = byte(v>>40) b[2] = byte(v >> 40)
b[3] = byte(v>>32) b[3] = byte(v >> 32)
b[4] = byte(v>>24) b[4] = byte(v >> 24)
b[5] = byte(v>>16) b[5] = byte(v >> 16)
b[6] = byte(v>>8) b[6] = byte(v >> 8)
b[7] = byte(v) b[7] = byte(v)
} }