Question

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.

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top