HRESULT MFAAC::Encoder::EnsureCapacity(ComPtr<IMFSample> &sample, DWORD length)
{
    HRESULT hr;
    ComPtr<IMFMediaBuffer> buffer;
    DWORD currentLength;

    if (!sample) {
        HRC(CreateEmptySample(sample, buffer, length));
    } else {
        HRC(sample->GetBufferByIndex(0, &buffer));
    }

    HRC(buffer->GetMaxLength(&currentLength));
    if (currentLength < length) {
        HRC(sample->RemoveAllBuffers());
        HRC(MFCreateMemoryBuffer(length, &buffer));
        HRC(sample->AddBuffer(buffer));
    } else {
        buffer->SetCurrentLength(0);
    }

    packetBuffer.reserve(length);

    return S_OK;

fail:
    return hr;
}
HRESULT CBufferPacket::FromMFSample(IMFSample *pSample, IBufferPacket **ppBufferPacket)
{
    if (pSample == nullptr || ppBufferPacket == nullptr)
    {
        return E_INVALIDARG;
    }

    ComPtr<IBufferPacket> spPacket;
    DWORD cBuffers = 0;
    HRESULT hr = CBufferPacket::CreateInstance(&spPacket);

    if (SUCCEEDED(hr))
    {
        hr = pSample->GetBufferCount(&cBuffers);
    }

    if (SUCCEEDED(hr))
    {
        for (DWORD nIndex = 0; nIndex < cBuffers; ++nIndex)
        {
            ComPtr<IMFMediaBuffer> spMediaBuffer;
            ComPtr<IMediaBufferWrapper> spBufferWrapper;
            
            // Get buffer from the sample
            hr = pSample->GetBufferByIndex(nIndex, &spMediaBuffer);
            if (FAILED(hr))
            {
                break;
            }

            // Create buffer wrapper
            hr = CreateMediaBufferWrapper(spMediaBuffer.Get(), &spBufferWrapper);
            if (FAILED(hr))
            {
                break;
            }

            // Add buffer to the package
            hr = spPacket->AddBuffer(spBufferWrapper.Get());
            if (FAILED(hr))
            {
                break;
            }
        }
    }

    if (SUCCEEDED(hr))
    {
        *ppBufferPacket = spPacket.Detach();
    }

    TRACEHR_RET(hr);
}
HRESULT MFAAC::Encoder::CreateEmptySample(ComPtr<IMFSample> &sample,
        ComPtr<IMFMediaBuffer> &buffer, DWORD length)
{
    HRESULT hr;

    HRC(MFCreateSample(&sample));
    HRC(MFCreateMemoryBuffer(length, &buffer));
    HRC(sample->AddBuffer(buffer.Get()));
    return S_OK;

fail:
    return hr;
}