stats window

This commit is contained in:
Dmitry Sergeev
2026-09-01 22:59:09 +03:00
parent ca25bf88a7
commit a8d277ee3d
13 changed files with 524 additions and 80 deletions
+68 -34
View File
@@ -11,6 +11,7 @@ import (
)
type flowDef struct {
Label string `json:"label"`
FrameWidth int `json:"frame_width"`
FrameHeight int `json:"frame_height"`
MediaType string `json:"media_type"`
@@ -21,14 +22,31 @@ type flowDef struct {
} `json:"grain_rate"`
}
func flowLabel(inst *mxl.Instance, flowID string) string {
definition, err := inst.FlowDef(flowID)
if err != nil {
return ""
}
var metadata struct {
Label string `json:"label"`
}
if json.Unmarshal([]byte(definition), &metadata) != nil {
return ""
}
return metadata.Label
}
type Frame struct {
Index uint64
Width uint32
Height uint32
Stride uint32
Size uint32
Invalid bool
Payload []byte
Index uint64
Width uint32
Height uint32
Stride uint32
Size uint32
Invalid bool
Label string
FrameRateNumerator int64
FrameRateDenominator int64
Payload []byte
}
type Source struct {
@@ -40,6 +58,7 @@ type Source struct {
stride uint32
width uint32
height uint32
label string
idx uint64
}
@@ -109,6 +128,7 @@ func Open(domain, flowID string) (*Source, error) {
stride: info.Config.Discrete.SliceSizes[0],
width: uint32(fd.FrameWidth),
height: uint32(fd.FrameHeight),
label: fd.Label,
idx: idx,
}, nil
}
@@ -157,13 +177,16 @@ func (s *Source) ReadOnceCtx(
switch {
case err == nil:
frame := Frame{
Index: g.Index,
Width: s.width,
Height: s.height,
Stride: s.stride,
Size: g.GrainSize,
Invalid: g.Invalid(),
Payload: g.Payload,
Index: g.Index,
Width: s.width,
Height: s.height,
Stride: s.stride,
Size: g.GrainSize,
Invalid: g.Invalid(),
Label: s.label,
FrameRateNumerator: s.rate.Num,
FrameRateDenominator: s.rate.Den,
Payload: g.Payload,
}
s.idx++
return frame, nil
@@ -222,12 +245,14 @@ type AudioSource struct {
rate mxl.Rational
chans uint64
idx uint64
label string
}
type AudioFrame struct {
Index uint64
SampleCount uint64
Channels uint64
Label string
Samples [][]byte // per-channel byte slices (F32, deinterleaved)
}
@@ -293,6 +318,7 @@ func OpenAudio(domain, flowID string) (*AudioSource, error) {
rate: rate,
chans: channels,
idx: idx,
label: flowLabel(inst, flowID),
}, nil
}
@@ -326,6 +352,7 @@ func (s *AudioSource) ReadAudioOnceCtx(
Index: s.idx,
SampleCount: batch,
Channels: s.chans,
Label: s.label,
Samples: samples,
}
s.idx += batch
@@ -401,15 +428,16 @@ func (s *AudioSource) Rate() mxl.Rational { return s.rate }
func (s *AudioSource) Channels() uint64 { return s.chans }
type SyncSource struct {
inst *mxl.Instance
vr *mxl.Reader
ar *mxl.Reader
group *mxl.SyncGroup
rate mxl.Rational // video rate
aRate mxl.Rational
chans uint64
idx uint64
width, height, stride uint32
inst *mxl.Instance
vr *mxl.Reader
ar *mxl.Reader
group *mxl.SyncGroup
rate mxl.Rational // video rate
aRate mxl.Rational
chans uint64
idx uint64
width, height, stride uint32
videoLabel, audioLabel string
}
// OpenSameDomainSync opens a native MXL synchronization group.
@@ -577,17 +605,19 @@ func OpenSameDomainSync(domain, videoFlow, audioFlow string) (*SyncSource, error
}
return &SyncSource{
inst: inst,
vr: vr,
ar: ar,
group: group,
rate: vRate,
aRate: aRate,
chans: channels,
idx: idx,
width: uint32(fd.FrameWidth),
height: uint32(fd.FrameHeight),
stride: vInfo.Config.Discrete.SliceSizes[0],
inst: inst,
vr: vr,
ar: ar,
group: group,
rate: vRate,
aRate: aRate,
chans: channels,
idx: idx,
width: uint32(fd.FrameWidth),
height: uint32(fd.FrameHeight),
stride: vInfo.Config.Discrete.SliceSizes[0],
videoLabel: fd.Label,
audioLabel: flowLabel(inst, audioFlow),
}, nil
}
@@ -665,6 +695,9 @@ func (s *SyncSource) NextSync(ctx context.Context, timeout time.Duration) (Frame
Index: g.Index, Width: s.width, Height: s.height,
Stride: s.stride, Size: g.GrainSize,
Invalid: g.Invalid(), Payload: g.Payload,
Label: s.videoLabel,
FrameRateNumerator: s.rate.Num,
FrameRateDenominator: s.rate.Den,
}
s.idx++
@@ -680,6 +713,7 @@ func (s *SyncSource) NextSync(ctx context.Context, timeout time.Duration) (Frame
aFrame := AudioFrame{
Index: aIdx, SampleCount: audioBatch,
Channels: s.chans, Samples: samples,
Label: s.audioLabel,
}
return vFrame, aFrame, nil
case errors.Is(err, mxl.ErrTimeout), errors.Is(err, mxl.ErrOutOfRangeEarly), errors.Is(err, mxl.ErrOutOfRangeLate):