@@ -96,6 +96,7 @@ type BroadcastSink struct {
9696 maxFrameQueueDuration time.Duration
9797 backpressure bool
9898 blockedProducers int // number waiting for queue handoff; guarded by mu
99+ awaitingRandomAccess bool
99100
100101 inputClosed bool // the source ended; drain queue, then return EOF
101102 closed bool // explicitly removed; discard queue and return EOF
@@ -166,6 +167,7 @@ func (bc *BroadcastCapture) AddSink() *BroadcastSink {
166167 s .primer = bc .primer
167168 if len (s .primer .AnnexB ) > 0 {
168169 s .primer .PTS = bc .now ()
170+ s .awaitingRandomAccess = true
169171 }
170172 bc .sinks = append (bc .sinks , s )
171173 bc .mu .Unlock ()
@@ -195,6 +197,7 @@ func (bc *BroadcastCapture) AddBackpressuredSink() (*BroadcastSink, error) {
195197 s .primer = bc .primer
196198 if len (s .primer .AnnexB ) > 0 {
197199 s .primer .PTS = bc .now ()
200+ s .awaitingRandomAccess = true
198201 }
199202 bc .sinks = append (bc .sinks , s )
200203 bc .mu .Unlock ()
@@ -343,6 +346,25 @@ func isDecoderPrimer(annexB []byte) bool {
343346 return h264SPS && h264PPS && h264IDR || hevcVPS && hevcSPS && hevcPPS && hevcIRAP
344347}
345348
349+ func isRandomAccessUnit (annexB []byte ) bool {
350+ for _ , nal := range splitAnnexBAccessUnit (annexB ) {
351+ raw := stripStartCode (nal )
352+ if len (raw ) == 0 {
353+ continue
354+ }
355+ if raw [0 ]& 0x1f == 5 {
356+ return true
357+ }
358+ if len (raw ) >= 2 {
359+ nalType := hevcNALType (raw )
360+ if nalType >= 16 && nalType <= 23 {
361+ return true
362+ }
363+ }
364+ }
365+ return false
366+ }
367+
346368// finish stops accepting sinks, lets existing sinks drain, and only then
347369// publishes BroadcastCapture completion.
348370func (bc * BroadcastCapture ) finish (err error ) {
@@ -456,6 +478,12 @@ func (s *BroadcastSink) enqueueFrame(frame VideoAccessUnit) error {
456478 if s .closed || s .inputClosed {
457479 return io .ErrClosedPipe
458480 }
481+ if s .awaitingRandomAccess {
482+ if ! isRandomAccessUnit (frame .AnnexB ) {
483+ return nil
484+ }
485+ s .awaitingRandomAccess = false
486+ }
459487 if len (s .frameQueue ) == 0 && len (frame .AnnexB ) > s .maxQueuedBytes {
460488 return errBroadcastSinkBacklog
461489 }
0 commit comments