fixed the synchronized-audio corruption

This commit is contained in:
Dmitry Sergeev
2026-09-01 01:04:40 +03:00
parent 19e2e076e9
commit e830da4a32
5 changed files with 153 additions and 642 deletions
+4 -22
View File
@@ -13,8 +13,7 @@ import (
)
const (
DefaultSyncReadTimeout = 200 * time.Millisecond
DefaultSyncBatchDuration = 10 * time.Millisecond
DefaultSyncReadTimeout = 200 * time.Millisecond
)
var ErrNativeSyncDifferentDomains = errors.New(
@@ -22,15 +21,13 @@ var ErrNativeSyncDifferentDomains = errors.New(
)
type SyncFactory struct {
ReadTimeout time.Duration
BatchDuration time.Duration
open func(string, string, string) (localSyncSource, error)
ReadTimeout time.Duration
open func(string, string, string) (localSyncSource, error)
}
type localSyncSource interface {
NextSync(
context.Context,
uint64,
time.Duration,
) (source.Frame, source.AudioFrame, error)
@@ -41,7 +38,6 @@ type localSyncSource interface {
type syncReader struct {
source localSyncSource
readTimeout time.Duration
audioBatch uint64
rateNumerator int64
rateDenominator int64
}
@@ -118,25 +114,11 @@ func (f SyncFactory) OpenSync(
if readTimeout <= 0 {
readTimeout = DefaultSyncReadTimeout
}
batchDuration := f.BatchDuration
if batchDuration <= 0 {
batchDuration = DefaultSyncBatchDuration
}
audioRate := src.AudioRate()
batch, err := audioBatchSize(audioRate.Num, audioRate.Den, batchDuration)
if err != nil {
_ = src.Close()
return nil, &source.SourceError{
Op: "calculate sync audio batch",
Kind: source.ErrorKindInvalidConfig,
Err: err,
}
}
return &syncReader{
source: src,
readTimeout: readTimeout,
audioBatch: batch,
rateNumerator: audioRate.Num,
rateDenominator: audioRate.Den,
}, nil
@@ -145,7 +127,7 @@ func (f SyncFactory) OpenSync(
func (r *syncReader) ReadSync(
ctx context.Context,
) (playback.SyncFrame, error) {
video, audio, err := r.source.NextSync(ctx, r.audioBatch, r.readTimeout)
video, audio, err := r.source.NextSync(ctx, r.readTimeout)
if err != nil {
return playback.SyncFrame{}, err
}
+5 -23
View File
@@ -17,7 +17,6 @@ type fakeLocalSyncSource struct {
audio source.AudioFrame
readErr error
rate mxl.Rational
batch uint64
timeout time.Duration
closed bool
closeError error
@@ -25,10 +24,8 @@ type fakeLocalSyncSource struct {
func (s *fakeLocalSyncSource) NextSync(
_ context.Context,
batch uint64,
timeout time.Duration,
) (source.Frame, source.AudioFrame, error) {
s.batch = batch
s.timeout = timeout
return s.video, s.audio, s.readErr
}
@@ -79,23 +76,8 @@ func TestSyncFactoryUsesDefaultsAndForwardsFeeds(t *testing.T) {
t.Fatalf("open args = %q %q %q", domain, videoUUID, audioUUID)
}
got := reader.(*syncReader)
if got.readTimeout != DefaultSyncReadTimeout || got.audioBatch != 480 {
t.Fatalf("reader timeout=%s batch=%d, want %s and 480", got.readTimeout, got.audioBatch, DefaultSyncReadTimeout)
}
}
func TestSyncFactoryClosesSourceForInvalidAudioRate(t *testing.T) {
fake := &fakeLocalSyncSource{rate: mxl.Rational{}}
factory := SyncFactory{open: func(string, string, string) (localSyncSource, error) {
return fake, nil
}}
video, audio := syncFeedConfigs()
reader, err := factory.OpenSync(context.Background(), video, audio)
if reader != nil {
t.Fatal("OpenSync() reader is not nil")
}
if !errors.Is(err, ErrInvalidAudioBatch) || !fake.closed {
t.Fatalf("OpenSync() error=%v closed=%t", err, fake.closed)
if got.readTimeout != DefaultSyncReadTimeout {
t.Fatalf("reader timeout=%s, want %s", got.readTimeout, DefaultSyncReadTimeout)
}
}
@@ -108,7 +90,7 @@ func TestSyncReaderConvertsPairWithoutCopying(t *testing.T) {
rate: mxl.Rational{Num: 48_000, Den: 1},
}
reader := &syncReader{
source: fake, readTimeout: 7 * time.Millisecond, audioBatch: 12,
source: fake, readTimeout: 7 * time.Millisecond,
rateNumerator: 48_000, rateDenominator: 1,
}
@@ -116,8 +98,8 @@ func TestSyncReaderConvertsPairWithoutCopying(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if fake.batch != 12 || fake.timeout != 7*time.Millisecond {
t.Fatalf("NextSync() batch=%d timeout=%s", fake.batch, fake.timeout)
if fake.timeout != 7*time.Millisecond {
t.Fatalf("NextSync() timeout=%s", fake.timeout)
}
if frame.Video.Index != 10 || frame.Audio.Index != 40 || frame.Audio.SampleRateNumerator != 48_000 {
t.Fatalf("frame = %+v", frame)