@@ -72,23 +72,37 @@ class AAudioStreamCollection {
7272 }
7373
7474 /* *
75- * Get a shared pointer to the stream. This is typically called from a callback thread.
75+ * Get a shared pointer to the stream and its parent (if wrapped by FilterAudioStream).
76+ * This is typically called from a callback thread.
77+ *
78+ * The shared pointers are valid only if the stream is opened with shared pointer and is not closed.
7679 *
7780 * @param stream raw pointer to the stream.
78- * @return a pair of a boolean and a shared pointer to the stream. The boolean indicates
79- * if the stream is present in the collection. The shared pointer is valid only if
80- * the stream is opened with shared pointer and is not closed.
81+ * @return tuple:
82+ * - bool: indicates if the stream is present in the collection.
83+ * - shared_ptr to the stream.
84+ * - shared_ptr to the parent stream if wrapped by FilterAudioStream, nullptr otherwise.
8185 */
82- std::pair<bool , std::shared_ptr<oboe::AudioStream>> getStream (AudioStreamAAudio* stream) {
86+ std::tuple<bool ,
87+ std::shared_ptr<oboe::AudioStream>,
88+ std::shared_ptr<oboe::AudioStream>>
89+ getStream (AudioStreamAAudio* stream) {
8390 if (stream == nullptr ) {
84- return {false , nullptr };
91+ return {false , nullptr , nullptr };
8592 }
8693 std::lock_guard<std::mutex> lock (mLock );
8794 if (mStreams .find (stream) != mStreams .end ()) {
8895 auto sharedStream = stream->lockWeakThis ();
89- return {true , sharedStream};
96+
97+ // If wrapped by FilterAudioStream, the parent must remain alive because
98+ // callbacks are routed through it.
99+ std::shared_ptr<AudioStream> sharedParentStream;
100+ if (sharedStream && sharedStream->hasParentStream ()) {
101+ sharedParentStream = sharedStream->getParentStream ()->lockWeakThis ();
102+ }
103+ return {true , sharedStream, sharedParentStream};
90104 }
91- return {false , nullptr };
105+ return {false , nullptr , nullptr };
92106 }
93107
94108private:
@@ -107,7 +121,7 @@ static aaudio_data_callback_result_t oboe_aaudio_data_callback_proc(
107121 int32_t numFrames) {
108122
109123 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(userData);
110- auto [isStreamAlive, sharedStream] =
124+ auto [isStreamAlive, sharedStream, sharedParentStream ] =
111125 AAudioStreamCollection::getInstance ().getStream (oboeStream);
112126 if (!isStreamAlive) {
113127 // Note that the stream is removed from the collection when close is called. However,
@@ -132,7 +146,7 @@ static int32_t oboe_aaudio_partial_data_callback_proc(
132146 void *audioData,
133147 int32_t numFrames) {
134148 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(userData);
135- auto [isStreamAlive, sharedStream] =
149+ auto [isStreamAlive, sharedStream, sharedParentStream ] =
136150 AAudioStreamCollection::getInstance ().getStream (oboeStream);
137151 if (!isStreamAlive) {
138152 // Note that the stream is removed from the collection when close is called. However,
@@ -183,9 +197,10 @@ static void oboe_aaudio_error_thread_proc(AudioStreamAAudio *oboeStream,
183197
184198// Callback thread for shared pointers.
185199static void oboe_aaudio_error_thread_proc_shared (std::shared_ptr<AudioStream> sharedStream,
200+ std::shared_ptr<AudioStream> sharedParentStream,
186201 Result error) {
187202 LOGD (" %s(,%d) - entering >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" , __func__, error);
188- // Hold the shared pointer while we use the raw pointer.
203+ // Hold the shared pointer(s) while we use the raw pointer.
189204 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(sharedStream.get ());
190205 oboe_aaudio_error_thread_proc_common (oboeStream, error);
191206 LOGD (" %s() - exiting <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" , __func__);
@@ -206,7 +221,8 @@ static void oboe_aaudio_presentation_thread_proc(AudioStreamAAudio *oboeStream)
206221
207222// Callback thread for shared pointers
208223static void oboe_aaudio_presentation_end_thread_proc_shared (
209- std::shared_ptr<AudioStream> sharedStream) {
224+ std::shared_ptr<AudioStream> sharedStream,
225+ std::shared_ptr<AudioStream> sharedParentStream) {
210226 LOGD (" %s() - entering >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" , __func__);
211227 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(sharedStream.get ());
212228 oboe_aaudio_presentation_thread_proc_common (oboeStream);
@@ -231,7 +247,9 @@ static void oboe_aaudio_routing_changed_thread_proc(
231247
232248// Callback thread for shared pointers
233249static void oboe_aaudio_routing_changed_thread_proc_shared (
234- std::shared_ptr<AudioStream> sharedStream, std::vector<int32_t > deviceIds) {
250+ std::shared_ptr<AudioStream> sharedStream,
251+ std::shared_ptr<AudioStream> sharedParentStream,
252+ std::vector<int32_t > deviceIds) {
235253 LOGD (" %s() - entering >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" , __func__);
236254 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(sharedStream.get ());
237255 oboe_aaudio_routing_changed_thread_proc_common (oboeStream, deviceIds.data (),
@@ -278,7 +296,7 @@ void AudioStreamAAudio::internalErrorCallback(
278296 }
279297
280298 // Prevents deletion of the stream if the app is using AudioStreamBuilder::openStream(shared_ptr)
281- auto [isStreamAlive, sharedStream] =
299+ auto [isStreamAlive, sharedStream, sharedParentStream ] =
282300 AAudioStreamCollection::getInstance ().getStream (oboeStream);
283301 if (!isStreamAlive) {
284302 // The stream is already closed. No need to call error callback.
@@ -295,7 +313,8 @@ void AudioStreamAAudio::internalErrorCallback(
295313 LOGW (" %s() stream already closed or closing" , __func__); // might happen if there are bugs
296314 } else if (sharedStream) {
297315 // Handle error on a separate thread using shared pointer.
298- std::thread t (oboe_aaudio_error_thread_proc_shared, sharedStream, oboeResult);
316+ std::thread t (oboe_aaudio_error_thread_proc_shared, sharedStream, sharedParentStream,
317+ oboeResult);
299318 t.detach ();
300319 } else {
301320 // Handle error on a separate thread.
@@ -1089,7 +1108,7 @@ void AudioStreamAAudio::internalPresentationEndCallback(AAudioStream *stream, vo
10891108 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(userData);
10901109
10911110 // Prevents deletion of the stream if the app is using AudioStreamBuilder::openStream(shared_ptr)
1092- auto [isStreamAlive, sharedStream] =
1111+ auto [isStreamAlive, sharedStream, sharedParentStream ] =
10931112 AAudioStreamCollection::getInstance ().getStream (oboeStream);
10941113 if (!isStreamAlive) {
10951114 // Client has closed the stream, no need to call the presentation end callback here.
@@ -1100,7 +1119,8 @@ void AudioStreamAAudio::internalPresentationEndCallback(AAudioStream *stream, vo
11001119 LOGW (" %s() stream already closed or closing" , __func__); // might happen if there are bugs
11011120 } else if (sharedStream) {
11021121 // Handle error on a separate thread using shared pointer.
1103- std::thread t (oboe_aaudio_presentation_end_thread_proc_shared, sharedStream);
1122+ std::thread t (oboe_aaudio_presentation_end_thread_proc_shared, sharedStream,
1123+ sharedParentStream);
11041124 t.detach ();
11051125 } else {
11061126 // Handle error on a separate thread.
@@ -1114,7 +1134,7 @@ void AudioStreamAAudio::internalRoutingChangedCallback(
11141134 AudioStreamAAudio *oboeStream = reinterpret_cast <AudioStreamAAudio*>(userData);
11151135
11161136 // Prevents deletion of the stream if the app is using AudioStreamBuilder::openStream(shared_ptr)
1117- auto [isStreamAlive, sharedStream] =
1137+ auto [isStreamAlive, sharedStream, sharedParentStream ] =
11181138 AAudioStreamCollection::getInstance ().getStream (oboeStream);
11191139 if (!isStreamAlive) {
11201140 // Client has closed the stream, no need to call the routing changed callback here.
@@ -1130,7 +1150,7 @@ void AudioStreamAAudio::internalRoutingChangedCallback(
11301150 if (oboeStream->getRoutingCallback () != nullptr ) {
11311151 // Handle routing change on a separate thread using shared pointer.
11321152 std::thread t (oboe_aaudio_routing_changed_thread_proc_shared, sharedStream,
1133- deviceIdsCopy);
1153+ sharedParentStream, deviceIdsCopy);
11341154 t.detach ();
11351155 }
11361156 } else {
0 commit comments