OSS: Optimize memory allocations during device initialization.

This commit is contained in:
David Reid
2026-01-14 16:31:29 +10:00
parent 2a2eb5bae4
commit 90aa390a08
+59 -40
View File
@@ -38978,8 +38978,7 @@ typedef struct ma_device_state_oss
{ {
int fdPlayback; int fdPlayback;
int fdCapture; int fdCapture;
void* pIntermediaryBufferPlayback; void* pIntermediaryBuffer;
void* pIntermediaryBufferCapture;
} ma_device_state_oss; } ma_device_state_oss;
static ma_context_state_oss* ma_context_get_backend_state__oss(ma_context* pContext) static ma_context_state_oss* ma_context_get_backend_state__oss(ma_context* pContext)
@@ -39512,7 +39511,7 @@ static ma_result ma_context_enumerate_devices__oss(ma_context* pContext, ma_enum
#endif #endif
} }
static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_config_oss* pDeviceConfigOSS, ma_device_descriptor* pDescriptor, ma_device_type deviceType, int* pFD, void** ppIntermediaryBuffer) static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_config_oss* pDeviceConfigOSS, ma_device_descriptor* pDescriptor, ma_device_type deviceType, int* pFD)
{ {
ma_result result; ma_result result;
int ossResult; int ossResult;
@@ -39523,12 +39522,10 @@ static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_conf
int ossChannels; int ossChannels;
int ossSampleRate; int ossSampleRate;
int ossFragment; int ossFragment;
void* pIntermediaryBuffer;
MA_ASSERT(pDevice != NULL); MA_ASSERT(pDevice != NULL);
MA_ASSERT(pDeviceConfigOSS != NULL); MA_ASSERT(pDeviceConfigOSS != NULL);
MA_ASSERT(pFD != NULL); MA_ASSERT(pFD != NULL);
MA_ASSERT(ppIntermediaryBuffer != NULL);
MA_ASSERT(deviceType != ma_device_type_duplex); MA_ASSERT(deviceType != ma_device_type_duplex);
pDeviceID = pDescriptor->pDeviceID; pDeviceID = pDescriptor->pDeviceID;
@@ -39623,25 +39620,35 @@ static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_conf
return MA_FORMAT_NOT_SUPPORTED; return MA_FORMAT_NOT_SUPPORTED;
} }
pIntermediaryBuffer = ma_malloc(ma_get_bytes_per_frame(pDescriptor->format, pDescriptor->channels) * pDescriptor->periodSizeInFrames, ma_device_get_allocation_callbacks(pDevice));
if (pIntermediaryBuffer == NULL) {
close(fd);
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to allocate memory for intermediary buffer.");
return MA_OUT_OF_MEMORY;
}
*pFD = fd; *pFD = fd;
*ppIntermediaryBuffer = pIntermediaryBuffer;
return MA_SUCCESS; return MA_SUCCESS;
} }
static void ma_device_uninit_internal__oss(ma_device* pDevice, ma_device_state_oss* pDeviceStateOSS)
{
ma_device_type deviceType = ma_device_get_type(pDevice);
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
close(pDeviceStateOSS->fdCapture);
}
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
close(pDeviceStateOSS->fdPlayback);
}
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
}
static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBackendConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture, void** ppDeviceState) static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBackendConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture, void** ppDeviceState)
{ {
ma_device_state_oss* pDeviceStateOSS; ma_device_state_oss* pDeviceStateOSS;
const ma_device_config_oss* pDeviceConfigOSS = (const ma_device_config_oss*)pDeviceBackendConfig; const ma_device_config_oss* pDeviceConfigOSS = (const ma_device_config_oss*)pDeviceBackendConfig;
ma_device_config_oss defaultConfigOSS; ma_device_config_oss defaultConfigOSS;
ma_device_type deviceType = ma_device_get_type(pDevice); ma_device_type deviceType = ma_device_get_type(pDevice);
ma_uint32 intermediaryBufferSizeCapture = 0;
ma_uint32 intermediaryBufferSizePlayback = 0;
ma_uint32 intermediaryBufferAllocationSize = 0;
if (pDeviceConfigOSS == NULL) { if (pDeviceConfigOSS == NULL) {
defaultConfigOSS = ma_device_config_oss_init(); defaultConfigOSS = ma_device_config_oss_init();
@@ -39658,28 +39665,53 @@ static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBack
} }
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) { if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorCapture, ma_device_type_capture, &pDeviceStateOSS->fdCapture, &pDeviceStateOSS->pIntermediaryBufferCapture); ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorCapture, ma_device_type_capture, &pDeviceStateOSS->fdCapture);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device."); ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device.");
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
return result; return result;
} }
intermediaryBufferSizeCapture = ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels) * pDescriptorCapture->periodSizeInFrames;
} }
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) { if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorPlayback, ma_device_type_playback, &pDeviceStateOSS->fdPlayback, &pDeviceStateOSS->pIntermediaryBufferPlayback); ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorPlayback, ma_device_type_playback, &pDeviceStateOSS->fdPlayback);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
if (deviceType == ma_device_type_duplex) {
close(pDeviceStateOSS->fdCapture);
ma_free(pDeviceStateOSS->pIntermediaryBufferCapture, ma_device_get_allocation_callbacks(pDevice));
}
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device."); ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device.");
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
return result; return result;
} }
intermediaryBufferSizePlayback = ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels) * pDescriptorPlayback->periodSizeInFrames;
} }
/*
We need an intermediary buffer. Since the capture and playback sides are never used simultaneously we can make
this the size of the maximum of the two. We can attach this to the end of the device state allocation.
*/
intermediaryBufferAllocationSize = ma_align_64(ma_max(intermediaryBufferSizeCapture, intermediaryBufferSizePlayback));
{
size_t deviceStateAllocationSizeNew;
ma_device_state_oss* pDeviceStateOSSNew;
deviceStateAllocationSizeNew = 0;
deviceStateAllocationSizeNew += ma_align_64(sizeof(*pDeviceStateOSS));
deviceStateAllocationSizeNew += ma_align_64(intermediaryBufferAllocationSize);
pDeviceStateOSSNew = (ma_device_state_oss*)ma_realloc(pDeviceStateOSS, deviceStateAllocationSizeNew, ma_device_get_allocation_callbacks(pDevice));
if (pDeviceStateOSSNew == NULL) {
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
return MA_OUT_OF_MEMORY;
}
pDeviceStateOSS = pDeviceStateOSSNew;
}
pDeviceStateOSS->pIntermediaryBuffer = ma_offset_ptr(pDeviceStateOSS, ma_align_64(sizeof(*pDeviceStateOSS)));
*ppDeviceState = pDeviceStateOSS; *ppDeviceState = pDeviceStateOSS;
return MA_SUCCESS; return MA_SUCCESS;
@@ -39688,20 +39720,7 @@ static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBack
static void ma_device_uninit__oss(ma_device* pDevice) static void ma_device_uninit__oss(ma_device* pDevice)
{ {
ma_device_state_oss* pDeviceStateOSS = ma_device_get_backend_state__oss(pDevice); ma_device_state_oss* pDeviceStateOSS = ma_device_get_backend_state__oss(pDevice);
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
MA_ASSERT(pDevice != NULL);
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
close(pDeviceStateOSS->fdCapture);
ma_free(pDeviceStateOSS->pIntermediaryBufferCapture, ma_device_get_allocation_callbacks(pDevice));
}
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
close(pDeviceStateOSS->fdPlayback);
ma_free(pDeviceStateOSS->pIntermediaryBufferPlayback, ma_device_get_allocation_callbacks(pDevice));
}
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
} }
@@ -39873,20 +39892,20 @@ static ma_result ma_device_step__oss(ma_device* pDevice, ma_blocking_mode blocki
if (FD_ISSET(pDeviceStateOSS->fdCapture, &fdsRead)) { if (FD_ISSET(pDeviceStateOSS->fdCapture, &fdsRead)) {
ma_uint32 framesRead; ma_uint32 framesRead;
result = ma_device_read__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferCapture, pDevice->capture.internalPeriodSizeInFrames, &framesRead); result = ma_device_read__oss(pDevice, pDeviceStateOSS->pIntermediaryBuffer, pDevice->capture.internalPeriodSizeInFrames, &framesRead);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
} }
ma_device_handle_backend_data_callback(pDevice, NULL, pDeviceStateOSS->pIntermediaryBufferCapture, framesRead); ma_device_handle_backend_data_callback(pDevice, NULL, pDeviceStateOSS->pIntermediaryBuffer, framesRead);
} }
} }
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) { if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
if (FD_ISSET(pDeviceStateOSS->fdPlayback, &fdsWrite)) { if (FD_ISSET(pDeviceStateOSS->fdPlayback, &fdsWrite)) {
ma_device_handle_backend_data_callback(pDevice, pDeviceStateOSS->pIntermediaryBufferPlayback, NULL, pDevice->playback.internalPeriodSizeInFrames); ma_device_handle_backend_data_callback(pDevice, pDeviceStateOSS->pIntermediaryBuffer, NULL, pDevice->playback.internalPeriodSizeInFrames);
result = ma_device_write__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferPlayback, pDevice->playback.internalPeriodSizeInFrames, NULL); result = ma_device_write__oss(pDevice, pDeviceStateOSS->pIntermediaryBuffer, pDevice->playback.internalPeriodSizeInFrames, NULL);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
} }