Skip to content

feat: add optional reused frame callbacks for zero-copy observers#65

Open
wnnce wants to merge 1 commit into
AgoraIO-Extensions:mainfrom
wnnce:feature/frame-reused
Open

feat: add optional reused frame callbacks for zero-copy observers#65
wnnce wants to merge 1 commit into
AgoraIO-Extensions:mainfrom
wnnce:feature/frame-reused

Conversation

@wnnce
Copy link
Copy Markdown

@wnnce wnnce commented Apr 13, 2026

Summary

This PR adds opt-in reused observer callbacks for RTC raw video, encoded video, and selected
audio frame callbacks.

The goal is to reduce per-frame allocations in high-frequency observer paths. The existing
observer callbacks keep their current copy-based behavior. The new callbacks expose SDK-owned
buffers through unsafe.Slice and let callers decide when and how to copy into their own
memory.

What Changed

New observer callbacks

  • VideoFrameObserver.OnReusedFrame
  • VideoEncodedFrameObserver.OnReusedEncodedVideoFrame
  • AudioFrameObserver.OnReusedRecordAudioFrame
  • AudioFrameObserver.OnReusedPlaybackAudioFrame
  • AudioFrameObserver.OnReusedMixedAudioFrame
  • AudioFrameObserver.OnReusedEarMonitoringAudioFrame

Callback behavior

  • Existing callbacks are unchanged and still return copied Go-owned buffers.
  • New reused callbacks expose temporary zero-copy views of SDK-owned buffers.
  • Reused callbacks are prioritized when both reused and legacy callbacks are set.
  • OnPlaybackAudioFrameBeforeMixing is intentionally unchanged.

Examples

Added dedicated examples for the new APIs:

  • go_sdk/examples/send_recv_yuv_reused
  • go_sdk/examples/recv_h264_reused
  • go_sdk/examples/recv_pcm_reused

These examples demonstrate the intended usage pattern:
copy inside the callback if the data must outlive the callback.

API Contract

The reused callbacks expose SDK-owned memory and therefore have stricter lifetime rules:

  • the frame buffer is only valid during the callback
  • callers must copy the data inside the callback before storing it or passing it to another
    goroutine
  • buffers must be treated as read-only

This keeps the zero-copy optimization isolated to explicit opt-in APIs without changing the
safety guarantees of the existing callbacks.

Compatibility

This change is backward compatible.

  • Existing callback names and behavior are preserved.
  • Existing applications do not need to change anything.
  • Only applications that explicitly adopt OnReused... callbacks opt into the new memory
    contract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant