未按时调用AudioSink.OnSamples()和MediaStreamSource.GetSampleAsync()

时间:2011-10-05 23:34:07

标签: silverlight mediaelement

我有一个Silverlight应用程序,它使用重写的AudioSink.OnSamples()来录制声音,而MediaStreamSource.GetSampleAsync()则用来播放声音。

例如:

protected override void GetSampleAsync(MediaStreamType mediaStreamType)
{
    try
    {
        logger.LogSampleRequested();
        var memoryStream = AudioController == null ? new MemoryStream() : AudioController.GetNextAudioFrame();
        timestamp += AudioConstants.MillisecondsPerFrame * TimeSpan.TicksPerMillisecond;
        var sample = new MediaStreamSample(
            mediaStreamDescription,
            memoryStream,
            0,
            memoryStream.Length,
            timestamp, // (DateTime.Now - startTime).Ticks, // Testing shows that incrementing a long with a good-enough value is ~100x faster than calculating the ticks each time.
            emptySampleDict);
        ReportGetSampleCompleted(sample);
    }
    catch (Exception ex)
    {
        ClientLogger.LogDebugMessage(ex.ToString);
    }
}

这两种方法通常应该每20毫秒调用一次,而在大多数机器上,这正是发生的事情。但是,在某些机器上,它们不是每20毫秒调用一次,而是接近22-24毫秒。这很麻烦,但通过一些适当的缓冲,音频仍然或多或少可用。更大的问题是,在某些情况下,例如当CPU运行接近其极限时,呼叫之间的间隔会增加到30-35毫秒。

所以:

(1)还有其他人看过这个吗?

(2)有没有人有任何建议的解决方法?

(3)有没有人有解决这个问题的技巧?

1 个答案:

答案 0 :(得分:0)

对于它的价值,经过多次调查,解决这个问题的基本方法就是不要使用尽可能多的CPU。在我们的例子中,这意味着要跟踪CPU利用率,并在CPU开始持续运行80%或更高时切换到没有使用尽可能多的CPU(G711与Speex)的编解码器。