1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-22 16:45:58 +01:00

Use packet timestamps when saving to disk.

This commit is contained in:
Juliusz Chroboczek 2020-06-08 23:09:23 +02:00
parent f9edde6526
commit 191624130a

41
disk.go
View file

@ -78,11 +78,13 @@ func (client *diskClient) pushConn(conn upConnection, tracks []upTrack, label st
type diskConn struct { type diskConn struct {
directory string directory string
label string label string
hasVideo bool
mu sync.Mutex mu sync.Mutex
file *os.File file *os.File
remote upConnection remote upConnection
tracks []*diskTrack tracks []*diskTrack
reference int // the track used as a time reference
width, height uint32 width, height uint32
} }
@ -126,7 +128,7 @@ func (conn *diskConn) Close() error {
} }
func openDiskFile(directory, label string) (*os.File, error) { func openDiskFile(directory, label string) (*os.File, error) {
filename := time.Now().Format("2006-01-02T15:04:05") filename := time.Now().Format("2006-01-02T15:04:05.000")
if label != "" { if label != "" {
filename = filename + "-" + label filename = filename + "-" + label
} }
@ -157,7 +159,9 @@ type diskTrack struct {
writer webm.BlockWriteCloser writer webm.BlockWriteCloser
builder *samplebuilder.SampleBuilder builder *samplebuilder.SampleBuilder
timestamp uint32
// bit 32 is a boolean indicating that the origin is valid
origin uint64
} }
func newDiskConn(directory, label string, up upConnection, remoteTracks []upTrack) (*diskConn, error) { func newDiskConn(directory, label string, up upConnection, remoteTracks []upTrack) (*diskConn, error) {
@ -167,18 +171,17 @@ func newDiskConn(directory, label string, up upConnection, remoteTracks []upTrac
tracks: make([]*diskTrack, 0, len(remoteTracks)), tracks: make([]*diskTrack, 0, len(remoteTracks)),
remote: up, remote: up,
} }
video := false
for _, remote := range remoteTracks { for _, remote := range remoteTracks {
var builder *samplebuilder.SampleBuilder var builder *samplebuilder.SampleBuilder
switch remote.Codec().Name { switch remote.Codec().Name {
case webrtc.Opus: case webrtc.Opus:
builder = samplebuilder.New(16, &codecs.OpusPacket{}) builder = samplebuilder.New(16, &codecs.OpusPacket{})
case webrtc.VP8: case webrtc.VP8:
if video { if conn.hasVideo {
return nil, errors.New("multiple video tracks not supported") return nil, errors.New("multiple video tracks not supported")
} }
builder = samplebuilder.New(32, &codecs.VP8Packet{}) builder = samplebuilder.New(32, &codecs.VP8Packet{})
video = true conn.hasVideo = true
} }
track := &diskTrack{ track := &diskTrack{
remote: remote, remote: remote,
@ -189,13 +192,6 @@ func newDiskConn(directory, label string, up upConnection, remoteTracks []upTrac
remote.addLocal(track) remote.addLocal(track)
} }
if !video {
err := conn.initWriter(0, 0)
if err != nil {
return nil, err
}
}
err := up.addLocal(&conn) err := up.addLocal(&conn)
if err != nil { if err != nil {
return nil, err return nil, err
@ -237,13 +233,11 @@ func (t *diskTrack) WriteRTP(packet *rtp.Packet) error {
t.builder.Push(p) t.builder.Push(p)
for { for {
sample := t.builder.Pop() sample, ts := t.builder.PopWithTimestamp()
if sample == nil { if sample == nil {
return nil return nil
} }
t.timestamp += sample.Samples
keyframe := true keyframe := true
switch t.remote.Codec().Name { switch t.remote.Codec().Name {
@ -258,7 +252,17 @@ func (t *diskTrack) WriteRTP(packet *rtp.Packet) error {
return err return err
} }
} }
default:
if t.writer == nil {
if !t.conn.hasVideo {
err := t.conn.initWriter(0, 0)
if err != nil {
return err
} }
}
}
}
if t.writer == nil { if t.writer == nil {
if !keyframe { if !keyframe {
return ErrKeyframeNeeded return ErrKeyframeNeeded
@ -266,7 +270,12 @@ func (t *diskTrack) WriteRTP(packet *rtp.Packet) error {
return nil return nil
} }
tm := t.timestamp / (t.remote.Codec().ClockRate / 1000) if t.origin == 0 {
t.origin = uint64(ts) | (1 << 32)
}
ts -= uint32(t.origin)
tm := ts / (t.remote.Codec().ClockRate / 1000)
_, err := t.writer.Write(keyframe, int64(tm), sample.Data) _, err := t.writer.Write(keyframe, int64(tm), sample.Data)
if err != nil { if err != nil {
return err return err