@@ -123,6 +123,8 @@ func TestBroadcastCaptureReplaysDecoderPrimerToLateSink(t *testing.T) {
123123 waitCh : make (chan struct {}),
124124 }
125125 broadcast := NewBroadcastCaptureWithFrameRate (capture , 30 )
126+ replayPTS := time .Unix (110 , 0 )
127+ broadcast .now = func () time.Time { return replayPTS }
126128 runDone := make (chan error , 1 )
127129 go func () { runDone <- broadcast .Run () }()
128130
@@ -140,6 +142,34 @@ func TestBroadcastCaptureReplaysDecoderPrimerToLateSink(t *testing.T) {
140142
141143 sink := broadcast .AddSink ()
142144 defer sink .Close ()
145+ replayDone := make (chan struct {
146+ frame VideoAccessUnit
147+ err error
148+ }, 1 )
149+ go func () {
150+ frame , err := sink .ReadVideoAccessUnit ()
151+ replayDone <- struct {
152+ frame VideoAccessUnit
153+ err error
154+ }{frame : frame , err : err }
155+ }()
156+ var replayed VideoAccessUnit
157+ select {
158+ case result := <- replayDone :
159+ if result .err != nil {
160+ t .Fatalf ("read replayed decoder primer: %v" , result .err )
161+ }
162+ replayed = result .frame
163+ case <- time .After (time .Second ):
164+ t .Fatal ("cached decoder primer was not available immediately" )
165+ }
166+ if ! bytes .Equal (replayed .AnnexB , primer .AnnexB ) {
167+ t .Fatalf ("first late-sink frame = %x, want cached decoder primer %x" , replayed .AnnexB , primer .AnnexB )
168+ }
169+ if ! replayed .PTS .Equal (replayPTS ) {
170+ t .Fatalf ("replayed primer PTS = %v, want attachment PTS %v" , replayed .PTS , replayPTS )
171+ }
172+
143173 boundary := VideoAccessUnit {
144174 AnnexB : []byte {0 , 0 , 0 , 1 , 0x61 , 0x40 },
145175 PTS : primer .PTS .Add (10 * time .Second ),
@@ -153,16 +183,6 @@ func TestBroadcastCaptureReplaysDecoderPrimerToLateSink(t *testing.T) {
153183 frames <- live
154184 close (frames )
155185
156- replayed , err := sink .ReadVideoAccessUnit ()
157- if err != nil {
158- t .Fatalf ("read replayed decoder primer: %v" , err )
159- }
160- if ! bytes .Equal (replayed .AnnexB , primer .AnnexB ) {
161- t .Fatalf ("first late-sink frame = %x, want cached decoder primer %x" , replayed .AnnexB , primer .AnnexB )
162- }
163- if wantPTS := live .PTS .Add (- time .Second / 30 ); ! replayed .PTS .Equal (wantPTS ) {
164- t .Fatalf ("replayed primer PTS = %v, want one frame before live PTS %v" , replayed .PTS , wantPTS )
165- }
166186 next , err := sink .ReadVideoAccessUnit ()
167187 if err != nil {
168188 t .Fatalf ("read live frame after decoder primer: %v" , err )
@@ -175,6 +195,49 @@ func TestBroadcastCaptureReplaysDecoderPrimerToLateSink(t *testing.T) {
175195 }
176196}
177197
198+ func TestBroadcastCapturePrimerSnapshotSurvivesRefresh (t * testing.T ) {
199+ frames := make (chan VideoAccessUnit )
200+ reads := make (chan struct {}, 4 )
201+ capture := & ScreenCapture {
202+ frames : & signaledVideoAccessUnitReader {frames : frames , reads : reads },
203+ waitCh : make (chan struct {}),
204+ }
205+ broadcast := NewBroadcastCapture (capture )
206+ broadcast .now = func () time.Time { return time .Unix (120 , 0 ) }
207+ runDone := make (chan error , 1 )
208+ go func () { runDone <- broadcast .Run () }()
209+
210+ first := VideoAccessUnit {AnnexB : []byte {
211+ 0 , 0 , 0 , 1 , 0x67 , 0x42 ,
212+ 0 , 0 , 0 , 1 , 0x68 , 0xce ,
213+ 0 , 0 , 0 , 1 , 0x65 , 0xaa ,
214+ }}
215+ second := VideoAccessUnit {AnnexB : []byte {
216+ 0 , 0 , 0 , 1 , 0x67 , 0x64 ,
217+ 0 , 0 , 0 , 1 , 0x68 , 0xee ,
218+ 0 , 0 , 0 , 1 , 0x65 , 0xbb ,
219+ }}
220+ <- reads
221+ frames <- first
222+ <- reads
223+ sink := broadcast .AddSink ()
224+ defer sink .Close ()
225+ frames <- second
226+ <- reads
227+
228+ got , err := sink .ReadVideoAccessUnit ()
229+ if err != nil {
230+ t .Fatalf ("read primer snapshot: %v" , err )
231+ }
232+ if ! bytes .Equal (got .AnnexB , first .AnnexB ) {
233+ t .Fatalf ("primer snapshot = %x, want %x" , got .AnnexB , first .AnnexB )
234+ }
235+ close (frames )
236+ if err := <- runDone ; ! errors .Is (err , io .EOF ) {
237+ t .Fatalf ("broadcast run = %v, want EOF" , err )
238+ }
239+ }
240+
178241func TestBroadcastSinkBackpressuresWithOnePendingAccessUnit (t * testing.T ) {
179242 sink := newBroadcastSinkWithPolicy (nil , true )
180243 base := time .Now ()
0 commit comments