sipsorcery-org / SIPSorceryMedia.FFmpeg

GNU Lesser General Public License v2.1
31 stars 24 forks source link

Fixed a segfault/access violation in FFmpegAudioSource #76

Open mykolav opened 3 weeks ago

mykolav commented 3 weeks ago

FFmpegAudioSource's output buffer overflows if ffmpeg.swr_convert is upsampling the source audio, resulting in a segmentation fault/access violation.

When calculating the size in bytes of the output buffer to be passed to ffmpeg.swr_convert, AudioDecoder_OnAudioFrame assumes the number of output samples is less than or equal to the number of input samples. This assumption doesn't hold if FFmpegAudioDecoder is configured with a clock rate higher than the source audio sampling rate.

For example, OpusAudioEncoder (from SIPSorceryMedia.SDL2/test/CheckCodec) expects 48K PCM as its input. This implies the clock rate of FFmpegAudioDecoder is also set to 48K. If the source audio sampling rate is lower—44.1K, 7.875K, etc.—ffmpeg.swr_convert will try to upsample the source audio and write past the output buffer's boundary, causing a segmentation fault/access violation.

Additionally, ffmpeg.swr_convert expects the output buffer's size in samples, so let's make sure we pass it the size in samples instead of bytes.

Here is a small reproducible sample. This is almost an exact copy of the code from sipsorcery/examples/WebRTCExamples/WebRTCMp4Source. The only difference is FFmpegFileSource is initialized with OpusAudioEncoder instead of the default AudioEncoder:

new FFmpegFileSource(
            Path.Combine(@"..\..\..\", MP4_PATH),
            repeat: true,
            audioEncoder: new OpusAudioEncoder());