@@ -150,35 +150,19 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
150
150
}
151
151
// wait for the 'readDataTask' task to exit
152
152
_readDataTaskMutex.lock ();
153
- _readDataTaskMutex.unlock ();
154
153
155
- if (_pcmData )
154
+ if (_state == State::READY )
156
155
{
157
- if (_state == State::READY)
158
- {
159
- if (_alBufferId != INVALID_AL_BUFFER_ID && alIsBuffer (_alBufferId))
160
- {
161
- ALOGV (" ~AudioCache(id=%u), delete buffer: %u" , _id, _alBufferId);
162
- alDeleteBuffers (1 , &_alBufferId);
163
- _alBufferId = INVALID_AL_BUFFER_ID;
164
- }
165
- }
166
- else
156
+ if (_alBufferId != INVALID_AL_BUFFER_ID && alIsBuffer (_alBufferId))
167
157
{
168
- ALOGW (" AudioCache (%p), id=%u, buffer isn't ready, state=%d" , this , _id, _state);
158
+ ALOGV (" ~AudioCache(id=%u), delete buffer: %u" , _id, _alBufferId);
159
+ alDeleteBuffers (1 , &_alBufferId);
160
+ _alBufferId = INVALID_AL_BUFFER_ID;
169
161
}
170
-
171
- // fixed #17494: CrashIfClientProvidedBogusAudioBufferList
172
- // We're using 'alBufferDataStaticProc' for speeding up
173
- // the performance of playing audio without preload, but we need to manage the memory by ourself carefully.
174
- // It's probably that '_pcmData' is freed before OpenAL finishes the audio render task,
175
- // then 'CrashIfClientProvidedBogusAudioBufferList' may be triggered.
176
- // 'cpp-tests/NewAudioEngineTest/AudioSwitchStateTest' can reproduce this issue without the following fix.
177
- // The workaround is delaying 200ms to free pcm data.
178
- char * data = _pcmData;
179
- setTimeout (0.2 , [data](){
180
- free (data);
181
- });
162
+ }
163
+ else
164
+ {
165
+ ALOGW (" AudioCache (%p), id=%u, buffer isn't ready, state=%d" , this , _id, _state);
182
166
}
183
167
184
168
if (_queBufferFrames > 0 )
@@ -189,6 +173,7 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
189
173
}
190
174
}
191
175
ALOGVV (" ~AudioCache() %p, id=%u, end" , this , _id);
176
+ _readDataTaskMutex.unlock ();
192
177
}
193
178
194
179
void AudioCache::readDataTask (unsigned int selfId)
@@ -200,6 +185,7 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
200
185
_state = State::LOADING;
201
186
202
187
AudioDecoder decoder;
188
+ char * l_pcmData = NULL ;
203
189
do
204
190
{
205
191
if (!decoder.open (_fileFullPath.c_str ()))
@@ -259,37 +245,25 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
259
245
// Reset to frame 0
260
246
BREAK_IF_ERR_LOG (!decoder.seek (0 ), " AudioDecoder::seek(0) failed!" );
261
247
262
- _pcmData = (char *)malloc (dataSize);
263
- memset (_pcmData, 0x00 , dataSize);
248
+ l_pcmData = (char *)malloc (dataSize);
249
+ memset (l_pcmData, 0x00 , dataSize);
250
+ ALOGV (" id=%u l_pcmData alloc: %p" , selfId, l_pcmData);
264
251
265
252
if (adjustFrames > 0 )
266
253
{
267
- memcpy (_pcmData + (dataSize - adjustFrameBuf.size ()), adjustFrameBuf.data (), adjustFrameBuf.size ());
268
- }
269
-
270
- alGenBuffers (1 , &_alBufferId);
271
- auto alError = alGetError ();
272
- if (alError != AL_NO_ERROR) {
273
- ALOGE (" %s: attaching audio to buffer fail: %x" , __PRETTY_FUNCTION__, alError);
274
- break ;
254
+ memcpy (l_pcmData + (dataSize - adjustFrameBuf.size ()), adjustFrameBuf.data (), adjustFrameBuf.size ());
275
255
}
276
256
277
257
if (*_isDestroyed)
278
258
break ;
279
259
280
- alBufferDataStaticProc (_alBufferId, _format, _pcmData, (ALsizei)dataSize, (ALsizei)sampleRate);
281
-
282
- framesRead = decoder.readFixedFrames (std::min (framesToReadOnce, remainingFrames), _pcmData + _framesRead * bytesPerFrame);
260
+ framesRead = decoder.readFixedFrames (std::min (framesToReadOnce, remainingFrames), l_pcmData + _framesRead * bytesPerFrame);
283
261
_framesRead += framesRead;
284
262
remainingFrames -= framesRead;
285
263
286
264
if (*_isDestroyed)
287
265
break ;
288
266
289
- _state = State::READY;
290
-
291
- invokingPlayCallbacks ();
292
-
293
267
uint32_t frames = 0 ;
294
268
while (!*_isDestroyed && _framesRead < originalTotalFrames)
295
269
{
@@ -298,7 +272,7 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
298
272
{
299
273
frames = originalTotalFrames - _framesRead;
300
274
}
301
- framesRead = decoder.read (frames, _pcmData + _framesRead * bytesPerFrame);
275
+ framesRead = decoder.read (frames, l_pcmData + _framesRead * bytesPerFrame);
302
276
if (framesRead == 0 )
303
277
break ;
304
278
_framesRead += framesRead;
@@ -307,11 +281,24 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
307
281
308
282
if (_framesRead < originalTotalFrames)
309
283
{
310
- memset (_pcmData + _framesRead * bytesPerFrame, 0x00 , (totalFrames - _framesRead) * bytesPerFrame);
284
+ memset (l_pcmData + _framesRead * bytesPerFrame, 0x00 , (totalFrames - _framesRead) * bytesPerFrame);
311
285
}
312
- ALOGV (" pcm buffer was loaded successfully, total frames: %u, total read frames: %u, adjust frames: %u, remainingFrames: %u" , totalFrames, _framesRead, adjustFrames, remainingFrames);
313
286
287
+ ALOGV (" pcm buffer was loaded successfully, total frames: %u, total read frames: %u, adjust frames: %u, remainingFrames: %u" , totalFrames, _framesRead, adjustFrames, remainingFrames);
314
288
_framesRead += adjustFrames;
289
+
290
+ alGenBuffers (1 , &_alBufferId);
291
+ auto alError = alGetError ();
292
+ if (alError != AL_NO_ERROR) {
293
+ ALOGE (" %s: attaching audio to buffer fail: %x" , __PRETTY_FUNCTION__, alError);
294
+ break ;
295
+ }
296
+ ALOGV (" id=%u generated alGenBuffers: %u for l_pcmData: %p" , selfId, _alBufferId, l_pcmData);
297
+ ALOGV (" id=%u l_pcmData alBufferData: %p" , selfId, l_pcmData);
298
+ alBufferData (_alBufferId, _format, l_pcmData, (ALsizei)dataSize, (ALsizei)sampleRate);
299
+ _state = State::READY;
300
+ invokingPlayCallbacks ();
301
+
315
302
}
316
303
else
317
304
{
@@ -333,6 +320,9 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
333
320
334
321
} while (false );
335
322
323
+ if (l_pcmData != NULL )
324
+ free (l_pcmData);
325
+
336
326
decoder.close ();
337
327
338
328
// FIXME: Why to invoke play callback first? Should it be after 'load' callback?
@@ -345,7 +335,7 @@ static void setTimeout(double seconds, const std::function<void()>& cb)
345
335
_state = State::FAILED;
346
336
if (_alBufferId != INVALID_AL_BUFFER_ID && alIsBuffer (_alBufferId))
347
337
{
348
- ALOGV (" readDataTask failed, delete buffer: %u" , _alBufferId);
338
+ ALOGV (" id=%u readDataTask failed, delete buffer: %u" , selfId , _alBufferId);
349
339
alDeleteBuffers (1 , &_alBufferId);
350
340
_alBufferId = INVALID_AL_BUFFER_ID;
351
341
}
0 commit comments