@@ -93,54 +93,124 @@ class LIVEKIT_API SubscriptionThreadDispatcher {
9393 // / Stops all active readers and clears all registered callbacks.
9494 ~SubscriptionThreadDispatcher ();
9595
96- // / Register or replace an audio frame callback for a remote subscription.
96+ // / Register an audio frame callback for a remote subscription.
9797 // /
9898 // / The callback is keyed by remote participant identity plus @p track_name.
9999 // / If the matching remote audio track is already subscribed, @ref Room may
100100 // / immediately call @ref handleTrackSubscribed to start a reader.
101101 // /
102+ // / Registration only succeeds when no reader is currently active for the
103+ // / key. To replace a callback whose reader is already running, call
104+ // / @ref clearOnAudioFrameCallback first, then register again.
105+ // /
102106 // / @param participant_identity Identity of the remote participant.
103107 // / @param track_name Track name to match.
104108 // / @param callback Function invoked for each decoded audio frame.
105109 // / @param opts Options used when creating the backing
106110 // / @ref AudioStream.
107- void setOnAudioFrameCallback (const std::string& participant_identity, const std::string& track_name,
108- AudioFrameCallback callback, const AudioStream::Options& opts = {});
111+ // / @return @c true if the callback was registered; @c false if a reader is
112+ // / already active for the key (the registration is left unchanged).
113+ [[nodiscard]] bool trySetOnAudioFrameCallback (const std::string& participant_identity, const std::string& track_name,
114+ AudioFrameCallback callback, const AudioStream::Options& opts = {});
109115
110- // / Register or replace a video frame callback for a remote subscription.
116+ // / Register a video frame callback for a remote subscription.
111117 // /
112118 // / The callback is keyed by remote participant identity plus @p track_name.
113119 // / If the matching remote video track is already subscribed, @ref Room may
114120 // / immediately call @ref handleTrackSubscribed to start a reader.
115121 // /
122+ // / Registration only succeeds when no reader is currently active for the
123+ // / key. To replace a callback whose reader is already running, call
124+ // / @ref clearOnVideoFrameCallback first, then register again.
125+ // /
116126 // / @param participant_identity Identity of the remote participant.
117127 // / @param track_name Track name to match.
118128 // / @param callback Function invoked for each decoded video frame.
119129 // / @param opts Options used when creating the backing
120130 // / @ref VideoStream.
121- void setOnVideoFrameCallback (const std::string& participant_identity, const std::string& track_name,
122- VideoFrameCallback callback, const VideoStream::Options& opts = {});
131+ // / @return @c true if the callback was registered; @c false if a reader is
132+ // / already active for the key (the registration is left unchanged).
133+ [[nodiscard]] bool trySetOnVideoFrameCallback (const std::string& participant_identity, const std::string& track_name,
134+ VideoFrameCallback callback, const VideoStream::Options& opts = {});
123135
124- // / Register or replace a rich video frame event callback for a remote
125- // / subscription.
136+ // / Register a rich video frame event callback for a remote subscription.
126137 // /
127138 // / The callback is keyed by remote participant identity plus @p track_name.
128139 // / If the matching remote video track is already subscribed, @ref Room may
129140 // / immediately call @ref handleTrackSubscribed to start a reader.
130141 // /
142+ // / Registration only succeeds when no reader is currently active for the
143+ // / key. To replace a callback whose reader is already running, call
144+ // / @ref clearOnVideoFrameCallback first, then register again.
145+ // /
146+ // / @param participant_identity Identity of the remote participant.
147+ // / @param track_name Track name to match.
148+ // / @param callback Function invoked for each decoded video frame
149+ // / event, including optional metadata.
150+ // / @param opts Options used when creating the backing
151+ // / @ref VideoStream.
152+ // / @return @c true if the callback was registered; @c false if a reader is
153+ // / already active for the key (the registration is left unchanged).
154+ [[nodiscard]] bool trySetOnVideoFrameEventCallback (const std::string& participant_identity,
155+ const std::string& track_name, VideoFrameEventCallback callback,
156+ const VideoStream::Options& opts = {});
157+
158+ // / @deprecated Use trySetOnAudioFrameCallback() instead.
159+ // /
160+ // / Forwards to @ref trySetOnAudioFrameCallback and discards the result.
161+ // / Replacing an active callback is not supported through this overload; call
162+ // / @ref clearOnAudioFrameCallback first, then @ref trySetOnAudioFrameCallback.
163+ // /
164+ // / @param participant_identity Identity of the remote participant.
165+ // / @param track_name Track name to match.
166+ // / @param callback Function invoked for each decoded audio frame.
167+ // / @param opts Options used when creating the backing
168+ // / @ref AudioStream.
169+ [[deprecated(
170+ " SubscriptionThreadDispatcher::setOnAudioFrameCallback is deprecated; use trySetOnAudioFrameCallback instead" )]]
171+ void setOnAudioFrameCallback (const std::string& participant_identity, const std::string& track_name,
172+ AudioFrameCallback callback, const AudioStream::Options& opts = {});
173+
174+ // / @deprecated Use trySetOnVideoFrameCallback() instead.
175+ // /
176+ // / Forwards to @ref trySetOnVideoFrameCallback and discards the result.
177+ // / Replacing an active callback is not supported through this overload; call
178+ // / @ref clearOnVideoFrameCallback first, then @ref trySetOnVideoFrameCallback.
179+ // /
180+ // / @param participant_identity Identity of the remote participant.
181+ // / @param track_name Track name to match.
182+ // / @param callback Function invoked for each decoded video frame.
183+ // / @param opts Options used when creating the backing
184+ // / @ref VideoStream.
185+ [[deprecated(
186+ " SubscriptionThreadDispatcher::setOnVideoFrameCallback is deprecated; use trySetOnVideoFrameCallback instead" )]]
187+ void setOnVideoFrameCallback (const std::string& participant_identity, const std::string& track_name,
188+ VideoFrameCallback callback, const VideoStream::Options& opts = {});
189+
190+ // / @deprecated Use trySetOnVideoFrameEventCallback() instead.
191+ // /
192+ // / Forwards to @ref trySetOnVideoFrameEventCallback and discards the result.
193+ // / Replacing an active callback is not supported through this overload; call
194+ // / @ref clearOnVideoFrameCallback first, then
195+ // / @ref trySetOnVideoFrameEventCallback.
196+ // /
131197 // / @param participant_identity Identity of the remote participant.
132198 // / @param track_name Track name to match.
133199 // / @param callback Function invoked for each decoded video frame
134200 // / event, including optional metadata.
135201 // / @param opts Options used when creating the backing
136202 // / @ref VideoStream.
203+ [[deprecated(
204+ " SubscriptionThreadDispatcher::setOnVideoFrameEventCallback is deprecated; use "
205+ " trySetOnVideoFrameEventCallback instead" )]]
137206 void setOnVideoFrameEventCallback (const std::string& participant_identity, const std::string& track_name,
138207 VideoFrameEventCallback callback, const VideoStream::Options& opts = {});
139208
140209 // / Remove an audio callback registration and stop any active reader.
141210 // /
142211 // / If an audio reader thread is active for the given key, its stream is
143- // / closed and the thread is joined before this call returns.
212+ // / closed and the thread is joined before this call returns. Call this
213+ // / before @ref trySetOnAudioFrameCallback to replace an active callback.
144214 // /
145215 // / @param participant_identity Identity of the remote participant.
146216 // / @param track_name Track name to clear.
@@ -149,7 +219,9 @@ class LIVEKIT_API SubscriptionThreadDispatcher {
149219 // / Remove a video callback registration and stop any active reader.
150220 // /
151221 // / If a video reader thread is active for the given key, its stream is
152- // / closed and the thread is joined before this call returns.
222+ // / closed and the thread is joined before this call returns. Call this
223+ // / before @ref trySetOnVideoFrameCallback (or
224+ // / @ref trySetOnVideoFrameEventCallback) to replace an active callback.
153225 // /
154226 // / @param participant_identity Identity of the remote participant.
155227 // / @param track_name Track name to clear.
0 commit comments