mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Fix a crash in ma_data_source_seek_pcm_frames().
This commit is contained in:
+53
-3
@@ -57509,6 +57509,56 @@ static ma_result ma_data_source_resolve_current(ma_data_source* pDataSource, ma_
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ma_result ma_data_source_read_pcm_frames_from_backend(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
|
||||||
|
{
|
||||||
|
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
|
||||||
|
|
||||||
|
MA_ASSERT(pDataSourceBase != NULL);
|
||||||
|
MA_ASSERT(pDataSourceBase->vtable != NULL);
|
||||||
|
MA_ASSERT(pDataSourceBase->vtable->onRead != NULL);
|
||||||
|
MA_ASSERT(pFramesRead != NULL);
|
||||||
|
|
||||||
|
if (pFramesOut != NULL) {
|
||||||
|
return pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, pFramesRead);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
No output buffer. Probably seeking forward. Read and discard. Can probably optimize this in terms of
|
||||||
|
onSeek and onGetCursor, but need to keep in mind that the data source may not implement these functions.
|
||||||
|
*/
|
||||||
|
ma_result result;
|
||||||
|
ma_uint64 framesRead;
|
||||||
|
ma_format format;
|
||||||
|
ma_uint32 channels;
|
||||||
|
ma_uint64 discardBufferCapInFrames;
|
||||||
|
ma_uint8 pDiscardBuffer[4096];
|
||||||
|
|
||||||
|
result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL, NULL, 0);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
discardBufferCapInFrames = sizeof(pDiscardBuffer) / ma_get_bytes_per_frame(format, channels);
|
||||||
|
|
||||||
|
framesRead = 0;
|
||||||
|
while (framesRead < frameCount) {
|
||||||
|
ma_uint64 framesReadThisIteration = 0;
|
||||||
|
ma_uint64 framesToRead = frameCount - framesRead;
|
||||||
|
if (framesToRead > discardBufferCapInFrames) {
|
||||||
|
framesToRead = discardBufferCapInFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = pDataSourceBase->vtable->onRead(pDataSourceBase, pDiscardBuffer, framesToRead, &framesReadThisIteration);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
framesRead += framesReadThisIteration;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
|
static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
|
||||||
{
|
{
|
||||||
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
|
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
|
||||||
@@ -57528,7 +57578,7 @@ static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDa
|
|||||||
|
|
||||||
if ((pDataSourceBase->vtable->flags & MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT) != 0 || (pDataSourceBase->rangeEndInFrames == ~((ma_uint64)0) && (pDataSourceBase->loopEndInFrames == ~((ma_uint64)0) || loop == MA_FALSE))) {
|
if ((pDataSourceBase->vtable->flags & MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT) != 0 || (pDataSourceBase->rangeEndInFrames == ~((ma_uint64)0) && (pDataSourceBase->loopEndInFrames == ~((ma_uint64)0) || loop == MA_FALSE))) {
|
||||||
/* Either the data source is self-managing the range, or no range is set - just read like normal. The data source itself will tell us when the end is reached. */
|
/* Either the data source is self-managing the range, or no range is set - just read like normal. The data source itself will tell us when the end is reached. */
|
||||||
result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
|
result = ma_data_source_read_pcm_frames_from_backend(pDataSource, pFramesOut, frameCount, &framesRead);
|
||||||
} else {
|
} else {
|
||||||
/* Need to clamp to within the range. */
|
/* Need to clamp to within the range. */
|
||||||
ma_uint64 relativeCursor;
|
ma_uint64 relativeCursor;
|
||||||
@@ -57537,7 +57587,7 @@ static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDa
|
|||||||
result = ma_data_source_get_cursor_in_pcm_frames(pDataSourceBase, &relativeCursor);
|
result = ma_data_source_get_cursor_in_pcm_frames(pDataSourceBase, &relativeCursor);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
/* Failed to retrieve the cursor. Cannot read within a range or loop points. Just read like normal - this may happen for things like noise data sources where it doesn't really matter. */
|
/* Failed to retrieve the cursor. Cannot read within a range or loop points. Just read like normal - this may happen for things like noise data sources where it doesn't really matter. */
|
||||||
result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
|
result = ma_data_source_read_pcm_frames_from_backend(pDataSource, pFramesOut, frameCount, &framesRead);
|
||||||
} else {
|
} else {
|
||||||
ma_uint64 rangeBeg;
|
ma_uint64 rangeBeg;
|
||||||
ma_uint64 rangeEnd;
|
ma_uint64 rangeEnd;
|
||||||
@@ -57565,7 +57615,7 @@ static ma_result ma_data_source_read_pcm_frames_within_range(ma_data_source* pDa
|
|||||||
MA_AT_END so the higher level function can know about it.
|
MA_AT_END so the higher level function can know about it.
|
||||||
*/
|
*/
|
||||||
if (frameCount > 0) {
|
if (frameCount > 0) {
|
||||||
result = pDataSourceBase->vtable->onRead(pDataSourceBase, pFramesOut, frameCount, &framesRead);
|
result = ma_data_source_read_pcm_frames_from_backend(pDataSource, pFramesOut, frameCount, &framesRead);
|
||||||
} else {
|
} else {
|
||||||
result = MA_AT_END; /* The cursor is sitting on the end of the range which means we're at the end. */
|
result = MA_AT_END; /* The cursor is sitting on the end of the range which means we're at the end. */
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user