Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 分配器_PROPERTIES::cBuffers中有多少缓冲区足够?_Winapi_Video_Directshow - Fatal编程技术网

Winapi 分配器_PROPERTIES::cBuffers中有多少缓冲区足够?

Winapi 分配器_PROPERTIES::cBuffers中有多少缓冲区足够?,winapi,video,directshow,Winapi,Video,Directshow,我正在开发一个自定义视频转换过滤器,它是从CtrTransformFilter派生的。在DirectShow术语中,它不会做任何不寻常的事情,例如媒体样本的额外内部缓冲、输出样本的排队或动态格式更改 graphedit中包含两个端到端连接的my filters实例的图形(第一个的输出连接到第二个的输入)在按下play时挂起。该图肯定不在::Transform方法覆盖内。第二个过滤器实例未直接连接到视频渲染器 如果在两个滤光片之间插入颜色转换器,则不会出现问题。如果我将请求的缓冲区数量(分配器_P

我正在开发一个自定义视频转换过滤器,它是从CtrTransformFilter派生的。在DirectShow术语中,它不会做任何不寻常的事情,例如媒体样本的额外内部缓冲、输出样本的排队或动态格式更改

graphedit中包含两个端到端连接的my filters实例的图形(第一个的输出连接到第二个的输入)在按下play时挂起。该图肯定不在::Transform方法覆盖内。第二个过滤器实例未直接连接到视频渲染器

如果在两个滤光片之间插入颜色转换器,则不会出现问题。如果我将请求的缓冲区数量(分配器_PROPERTIES::cBuffers)从1增加到3,那么问题就消失了。下面是原始的DecideBufferSize覆盖,它与许多其他示例DirectShow筛选器代码类似

在DirectShow筛选器(转换或其他)中设置请求的缓冲区数量的可靠策略是什么?对于现代需求,请求一个缓冲区的代码是否已过时?我的问题是缓冲区太少还是缓冲区数量的增加掩盖了另一个问题

    HRESULT MyFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
    AM_MEDIA_TYPE mt;
    HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
    if (FAILED(hr)) {
        return hr;
    }

    BITMAPINFOHEADER * const pbmi = GetBitmapInfoHeader(mt);
    pProp->cbBuffer = DIBSIZE(*pbmi);
    if (pProp->cbAlign == 0) {
        pProp->cbAlign = 1;
    } 
    if (pProp->cBuffers == 0) {
        pProp->cBuffers = 3;
    }
    // Release the format block.
    FreeMediaType(mt);

    // Set allocator properties.
    ALLOCATOR_PROPERTIES Actual;
    hr = pAlloc->SetProperties(pProp, &Actual);
    if (FAILED(hr)) {
        return hr;
    }
    // Even when it succeeds, check the actual result.
    if (pProp->cbBuffer > Actual.cbBuffer) {
        return E_FAIL;
    }
    return S_OK;
}

对于缓冲区的数量没有特定的策略,不过您应该明确地知道,固定数量的缓冲区是控制采样率的方法。当所有缓冲区都在使用时,对另一个缓冲区的请求将阻止执行,直到该缓冲区可用为止

也就是说,如果您的代码出于某种目的持有缓冲区引用,那么您应该分配相应的数量,这样您就不会锁定自己。例如,您在内部保留最后一个媒体样本引用,例如,为了能够重新发送它,而您仍然希望能够传递其他媒体样本,因此分配器上至少需要两个缓冲区

输出引脚通常负责选择和设置分配器,输入端可能需要检查和更新属性,如果/当它被通知要使用哪个分配器时。在共享分配器时,在就地转换过滤器上,您可能需要进行额外的检查,以确保满足要求

  • DMO包装过滤器
    使用(至少有时)仅具有一个缓冲区的分配器,并且仍然处于良好状态
  • 对于音频,您通常会有更多的缓冲区,因为您将数据排队等待播放
  • 如果代码中存在引用泄漏,并且未发布媒体示例指针,则流媒体可能会因此而锁定