I have a multithreaded DirectShow app that uses sockets to transfer audio to and from Skype. It is written in Delphi 6 using the DSPACK component suite. The socket components used to trade audio data with Skype are from the ICS socket library. The ICS components use non-blocking sockets that use a Windows message loop to do their work instead of using blocking sockets like the Indy or Synapse components do. I have each socket on its own real-time critical worker thread. In a Stack Overflow post I made about ICS sockets and background threads a comment was made about switching to Indy to avoid the Windows "event queue bottleneck":
Can someone tell me what that is and what steps I need to take to prevent/avoid that problem?
Note, I have two ICS sockets handling the bidirectional (duplex) connection for audio with Skype. One for sending audio to Skype and another for receiving audio from Skype. I have my audio buffers set to a size that equals 100 milliseconds of audio data. Therefore data is sent 10 times a second to Skype, and conversely, is received 10 times a second from Skype. Each socket has its own thread set to real-time critical priority to do its work.
The reason for my question is this. The app now works reasonably well. Before I fixed a number of bugs I would see incrementally increasing delays in the audio send and receive streams. Now I can run for several minutes without any delays audible in the audio streams, but after that, and the time of inception is extremely variable, some small delays start to creep in. I have noticed the following symptoms:
- If I have a large number of OutputDebugString() messages, the delays happen after only 20-30 seconds, and get exponentially worse after that (quickly degrade). Removing the OutputDebugString() messages alleviates the problem:
- Switching from my app back to the Delphi IDE causes a delay to be injected into the audio streams. Apparently, something about the switch gums up the works and code I have that monitors how long a critical section is held pops out a warning message that one of the critical sections was held for a long amount of time (longer than 100 milliseconds which is obviously a problem).
Note: The two threads I use to send command messages strings to Skype and receive status and result message strings from Skype also are GetMessage() based because interfacing with Skype is done synchronously with the Windows SendMessage() API call using WM_COPYDATA messages.
Given the frequency of audio delivery, how likely is it that the problems are due to a Windows "event queue bottleneck", or is it more likely an inefficiency in my thread synchronization scheme?