1515
1616#define FRAME_SIZE_8000 320 /* 1000x0.02 (20ms)= 160 x(16bit= 2 bytes) 320 frame size*/
1717
18+ // Persistent buffers for stream_frame to avoid per-frame heap allocations
19+ struct StreamBuffers {
20+ std::vector<uint8_t > flush_buffer;
21+ std::vector<spx_int16_t > resample_buffer;
22+ std::vector<uint8_t > data_buf;
23+
24+ StreamBuffers () {
25+ flush_buffer.reserve (SWITCH_RECOMMENDED_BUFFER_SIZE);
26+ resample_buffer.reserve (SWITCH_RECOMMENDED_BUFFER_SIZE / sizeof (spx_int16_t ));
27+ data_buf.resize (SWITCH_RECOMMENDED_BUFFER_SIZE);
28+ }
29+ };
30+
1831class AudioStreamer {
1932public:
2033
@@ -526,6 +539,7 @@ namespace {
526539 tls_cafile, tls_keyfile, tls_certfile, tls_disable_hostname_validation, sampling, disable_audiofiles);
527540
528541 tech_pvt->pAudioStreamer = static_cast <void *>(as);
542+ tech_pvt->stream_buffers = static_cast <void *>(new StreamBuffers ());
529543
530544 switch_mutex_init (&tech_pvt->mutex , SWITCH_MUTEX_NESTED, pool);
531545
@@ -567,6 +581,11 @@ namespace {
567581 delete as;
568582 tech_pvt->pAudioStreamer = nullptr ;
569583 }
584+ if (tech_pvt->stream_buffers ) {
585+ auto * sb = static_cast <StreamBuffers*>(tech_pvt->stream_buffers );
586+ delete sb;
587+ tech_pvt->stream_buffers = nullptr ;
588+ }
570589 }
571590
572591 void finish (private_t * tech_pvt) {
@@ -936,23 +955,21 @@ extern "C" {
936955 return SWITCH_TRUE;
937956 }
938957
939- // Pre-allocate reusable buffers to avoid repeated allocations
940- std::vector<uint8_t > flush_buffer;
941- std::vector<spx_int16_t > resample_buffer;
958+ // Get persistent buffers (allocated once per session, reused across all frames)
959+ auto *bufs = static_cast <StreamBuffers*>(tech_pvt->stream_buffers );
942960
943961 auto flush_sbuffer = [&]() {
944962 switch_size_t inuse = switch_buffer_inuse (tech_pvt->sbuffer );
945963 if (inuse > 0 ) {
946- flush_buffer.resize (inuse);
947- switch_buffer_read (tech_pvt->sbuffer , flush_buffer.data (), inuse);
964+ bufs-> flush_buffer .resize (inuse);
965+ switch_buffer_read (tech_pvt->sbuffer , bufs-> flush_buffer .data (), inuse);
948966 switch_buffer_zero (tech_pvt->sbuffer );
949- pAudioStreamer->writeAudioDelta (flush_buffer.data (), inuse);
967+ pAudioStreamer->writeAudioDelta (bufs-> flush_buffer .data (), inuse);
950968 }
951969 };
952970
953- std::vector<uint8_t > data_buf (SWITCH_RECOMMENDED_BUFFER_SIZE);
954971 switch_frame_t frame{};
955- frame.data = data_buf.data ();
972+ frame.data = bufs-> data_buf .data ();
956973 frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
957974
958975 while (switch_core_media_bug_read (bug, &frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
@@ -1003,23 +1020,23 @@ extern "C" {
10031020 }
10041021 }
10051022
1006- resample_buffer.resize (out_len * tech_pvt->channels );
1023+ bufs-> resample_buffer .resize (out_len * tech_pvt->channels );
10071024
10081025 if (tech_pvt->channels == 1 ) {
10091026 speex_resampler_process_int (
10101027 tech_pvt->resampler ,
10111028 0 ,
10121029 static_cast <const spx_int16_t *>(frame.data ),
10131030 &in_len,
1014- resample_buffer.data (),
1031+ bufs-> resample_buffer .data (),
10151032 &out_len
10161033 );
10171034 } else {
10181035 speex_resampler_process_interleaved_int (
10191036 tech_pvt->resampler ,
10201037 static_cast <const spx_int16_t *>(frame.data ),
10211038 &in_len,
1022- resample_buffer.data (),
1039+ bufs-> resample_buffer .data (),
10231040 &out_len
10241041 );
10251042 }
@@ -1028,7 +1045,7 @@ extern "C" {
10281045 if (bytes_written > 0 ) {
10291046 // For 20ms packets, send immediately without buffering
10301047 if (tech_pvt->rtp_packets == 1 ) {
1031- pAudioStreamer->writeAudioDelta (reinterpret_cast <uint8_t *>(resample_buffer.data ()), bytes_written);
1048+ pAudioStreamer->writeAudioDelta (reinterpret_cast <uint8_t *>(bufs-> resample_buffer .data ()), bytes_written);
10321049 } else {
10331050 // Check if buffer has enough space before writing
10341051 switch_size_t free_space = switch_buffer_freespace (tech_pvt->sbuffer );
@@ -1039,7 +1056,7 @@ extern "C" {
10391056 if (bytes_written <= free_space) {
10401057 switch_buffer_write (
10411058 tech_pvt->sbuffer ,
1042- reinterpret_cast <const uint8_t *>(resample_buffer.data ()),
1059+ reinterpret_cast <const uint8_t *>(bufs-> resample_buffer .data ()),
10431060 bytes_written
10441061 );
10451062 if (switch_buffer_freespace (tech_pvt->sbuffer ) == 0 ) {
0 commit comments