首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何消除DirectShow滤波器链中的1秒延迟?(使用Delphi和DSPACK)

如何消除DirectShow滤波器链中的1秒延迟?(使用Delphi和DSPACK)
EN

Stack Overflow用户
提问于 2011-10-24 20:15:42
回答 1查看 2.9K关注 0票数 5

我有一个Delphi 6 Pro应用程序,它使用DSPACK组件库从系统的首选音频输入设备发送音频到Skype。我使用一个TSampleGrabber组件来点击过滤器图形链,然后发送音频缓冲区到Skype。问题是,我一秒钟只收到一次音频。换句话说,针对OnBuffer实例的TSampleGrabber ()事件每秒钟只触发一次,缓冲区参数中包含完整秒的数据。我需要知道如何修改我的过滤器图形链,以便它以比每秒一次更快的间隔从输入设备抓取数据。如果可能的话,我想每隔50毫秒或至少每100毫秒做一次。

我的过滤器图形链由一个TFilter组成,它被映射到系统顶部的首选音频输入设备。我将该过滤器的输出引脚附加到分配给TFilter的“WAV”输入引脚上,这样我就可以获得PCM格式的样本。然后,我将“WAV”过滤器的输出引脚附加到TSampleGrabber实例的输入引脚上。要使TSampleGrabber OnBuffer()事件以更快的间隔触发,需要更改什么?

UPDATE:基于Roman的答案,我实现了一个解决方案,如下所示。一个音符。他的链接使我找到了以下有助于解决方案的博客文章:

http://sid6581.wordpress.com/2006/10/09/minimizing-audio-capture-latency-in-directshow/

代码语言:javascript
复制
// Variable declaration for output pin to manipulate.
var
    intfCapturePin: IPin;

...............


    // Put this code after you have initialized your audio capture device
    //  TFilter instance *and* set it's wave audio format.  My variable for
    //  this is FFiltAudCap.  I believe you need to set the buffer size before
    //  connecting up the pins of the Filters.  The media type was
    //  retrieved earlier (theMediaType) when I initialized the audio
    //  input device Filter so you will need to do similarly.

    // Get a reference to the desired output pin for the audio capture device.
    with FFiltAudCap as IBaseFilter do
        CheckDSError(findPin(StringToOleStr('Capture'), intfCapturePin));

    if not Assigned(intfCapturePin) then
        raise Exception.Create('Unable to find the audio input device''s Capture output pin.');

    // Set the capture device buffer to 50 ms worth of audio data to
    //  reduce latency.  NOTE: This will fail if the device does not
    //  support the latency you desire so make sure you watch out for that.
    setBufferLatency(intfCapturePin as IAMBufferNegotiation, 50, theMediaType);

..................

// The setBufferLatency() procedure.
procedure setBufferLatency(
                // A buffer negotiation interface pointer.
                intfBufNegotiate: IAMBufferNegotiation;
                // The desired latency in milliseconds.
                bufLatencyMS: WORD;
                // The media type the audio stream is set to.
                theMediaType: TMediaType);
var
    allocProp: _AllocatorProperties;
    wfex: TWaveFormatEx;
begin
    if not Assigned(intfBufNegotiate) then
        raise Exception.Create('The buffer negotiation interface object is unassigned.');

    // Calculate the number of bytes per second using the wave
    // format belonging to the given Media Type.
    wfex := getWaveFormat(theMediaType);

    if wfex.nAvgBytesPerSec = 0 then
        raise Exception.Create('The average bytes per second value for the given Media Type is 0.');

    allocProp.cbAlign := -1;  // -1 means "no preference".
    // Calculate the size of the buffer needed to get the desired
    //  latency in milliseconds given the average bytes per second
    //  of the Media Type's audio format.
    allocProp.cbBuffer := Trunc(wfex.nAvgBytesPerSec * (bufLatencyMS / 1000));
    allocProp.cbPrefix := -1;
    allocProp.cBuffers := -1;

    // Try to set the buffer size to the desired.
    CheckDSError(intfBufNegotiate.SuggestAllocatorProperties(allocProp));
end;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-10-24 20:53:45

我认为您需要微调音频捕获过滤器,以捕获您想要的缓冲区,即足够短,以使整个延迟小。

音频捕获过滤器在输出引脚上公开IAMBufferNegotiation接口,SuggestAllocatorProperties允许您指定缓冲区配置。

更多信息见:Configuring Windows Media Audio Encoder DMO to reduce delay

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7881420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档