Luke
Luke

Reputation: 5971

Call to IMemAllocator->GetBuffer blocks at second call

In my custom output pin I call IMemAllocator->GetBuffer to obtain a new sample and copy the data into it:

HRESULT MCMyOutputPin::Deliver(IMediaSample* sample)
{
    HRESULT hr = NO_ERROR;
    myLogger->LogDebug("In Outputpin Deliver", L"D:\\TEMP\\yc.log");
    if (sample->GetActualDataLength() > 0)
    {
        IMediaSample *outsample;



        hr = m_pAllocator->GetBuffer(&outsample, NULL, NULL, NULL);

        BYTE* sampleBuffer = NULL;
        BYTE*  newBuffer = NULL;
        sample->GetPointer(&sampleBuffer);
        UINT32 ulDataLen = sample->GetSize();
        outsample->GetPointer(&newBuffer);
        ZeroMemory(newBuffer, ulDataLen);
        CopyMemory(newBuffer, sampleBuffer, ulDataLen);
        outsample->SetActualDataLength(ulDataLen);

        m_pInputPin->Receive(outsample);






    }

    return hr;
}

The problem is that the call to GetBuffer blocks at the second call. According to some research i have done this cann happen if the buffer size is to small. So i tried doubling it.

HRESULT MCMyOutputPin::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProps)
{
    myLogger->LogDebug("On DecideBufferSIze", L"D:\\TEMP\\yc.log");
    ALLOCATOR_PROPERTIES    act;
    HRESULT                 hr;

    // by default we do something like this...
    pProps->cbAlign     = 1;
    pProps->cBuffers = 1;
    long buffersize = this->CurrentMediaType().lSampleSize;
    pProps->cbBuffer = buffersize * 2;
    pProps->cbPrefix    = 0;

    hr = pAlloc->SetProperties(pProps, &act);
    if (FAILED(hr)) return hr;

    // make sure the allocator is OK with it.
    if ((pProps->cBuffers > act.cBuffers)  ||
        (pProps->cbBuffer > act.cbBuffer) ||
        (pProps->cbAlign > act.cbAlign)) 
        return E_FAIL;

    return NOERROR;
}

That didn't help. I probably just have forgotten something. As it is the second call i probably should clean up something after a call to GetBuffer but i don't know what.

Upvotes: 1

Views: 224

Answers (1)

Roman Ryltsov
Roman Ryltsov

Reputation: 69716

Memory allocators manage fixed number of media samples. When all media samples are given away, GetBuffer blocks until some media sample gets back availalble.

In you particular case, you have ONE media sample in the allocator and you do not do properly release the COM interface, hence it never gets back availalble, and you get infinite lock.

   m_pInputPin->Receive(outsample);
   outsample->Release(); // <<--- Here is the missing thing

Upvotes: 2

Related Questions