292 lines
8.7 KiB
C++
292 lines
8.7 KiB
C++
/*
|
|
* Copyright (c) 2013, INTEL CORPORATION
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation and/or
|
|
* other materials provided with the distribution.
|
|
* Neither the name of INTEL CORPORATION nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software without specific
|
|
* prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "QuickSync_defs.h"
|
|
#include "base_allocator.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
// MFXFrameAllocator
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
MFXFrameAllocator::MFXFrameAllocator()
|
|
{
|
|
MSDK_ZERO_MEMORY(reserved, sizeof(reserved));
|
|
pthis = this;
|
|
Alloc = Alloc_;
|
|
Lock = Lock_;
|
|
Free = Free_;
|
|
Unlock = Unlock_;
|
|
GetHDL = GetHDL_;
|
|
}
|
|
|
|
MFXFrameAllocator::~MFXFrameAllocator()
|
|
{
|
|
}
|
|
|
|
mfxStatus MFXFrameAllocator::Alloc_(mfxHDL pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
|
|
|
return self.AllocFrames(request, response);
|
|
}
|
|
|
|
mfxStatus MFXFrameAllocator::Lock_(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
|
|
|
return self.LockFrame(mid, ptr);
|
|
}
|
|
|
|
mfxStatus MFXFrameAllocator::Unlock_(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
|
|
|
return self.UnlockFrame(mid, ptr);
|
|
}
|
|
|
|
mfxStatus MFXFrameAllocator::Free_(mfxHDL pthis, mfxFrameAllocResponse *response)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
|
|
|
return self.FreeFrames(response);
|
|
}
|
|
|
|
mfxStatus MFXFrameAllocator::GetHDL_(mfxHDL pthis, mfxMemId mid, mfxHDL *handle)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXFrameAllocator& self = *(MFXFrameAllocator *)pthis;
|
|
|
|
return self.GetFrameHDL(mid, handle);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
// BaseFrameAllocator
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
BaseFrameAllocator::BaseFrameAllocator()
|
|
{
|
|
}
|
|
|
|
BaseFrameAllocator::~BaseFrameAllocator()
|
|
{
|
|
}
|
|
|
|
mfxStatus BaseFrameAllocator::CheckRequestType(mfxFrameAllocRequest* request)
|
|
{
|
|
if (0 == request)
|
|
return MFX_ERR_NULL_PTR;
|
|
|
|
// check that Media SDK component is specified in request
|
|
if ((request->Type & MEMTYPE_FROM_MASK) != 0)
|
|
return MFX_ERR_NONE;
|
|
else
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
|
|
mfxStatus BaseFrameAllocator::AllocFrames(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response)
|
|
{
|
|
if (0 == request || 0 == response || 0 == request->NumFrameSuggested)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
if (MSDK_FAILED(CheckRequestType(request)))
|
|
return MFX_ERR_UNSUPPORTED;
|
|
|
|
mfxStatus sts = MFX_ERR_NONE;
|
|
|
|
if ( (request->Type & MFX_MEMTYPE_EXTERNAL_FRAME) && (request->Type & MFX_MEMTYPE_FROM_DECODE) )
|
|
{
|
|
// external decoder allocations
|
|
std::list<UniqueResponse>::iterator it =
|
|
std::find_if( m_ExtResponses.begin()
|
|
, m_ExtResponses.end()
|
|
, UniqueResponse (*response, request->Info.CropW, request->Info.CropH, 0));
|
|
|
|
if (it != m_ExtResponses.end())
|
|
{
|
|
// check if enough frames were allocated
|
|
if (request->NumFrameMin > it->NumFrameActual)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
it->m_refCount++;
|
|
// return existing response
|
|
*response = (mfxFrameAllocResponse&)*it;
|
|
}
|
|
else
|
|
{
|
|
sts = AllocImpl(request, response);
|
|
if (MSDK_SUCCEEDED(sts))
|
|
{
|
|
m_ExtResponses.push_back(UniqueResponse(*response, request->Info.CropW, request->Info.CropH, request->Type & MEMTYPE_FROM_MASK));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// internal allocations
|
|
|
|
// reserve space before allocation to avoid memory leak
|
|
m_responses.push_back(mfxFrameAllocResponse());
|
|
|
|
sts = AllocImpl(request, response);
|
|
if (MSDK_SUCCEEDED(sts))
|
|
{
|
|
m_responses.back() = *response;
|
|
}
|
|
else
|
|
{
|
|
m_responses.pop_back();
|
|
}
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus BaseFrameAllocator::FreeFrames(mfxFrameAllocResponse *response)
|
|
{
|
|
if (response == 0)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
mfxStatus sts = MFX_ERR_NONE;
|
|
|
|
// check whether response is an external decoder response
|
|
std::list<UniqueResponse>::iterator i =
|
|
std::find_if( m_ExtResponses.begin(), m_ExtResponses.end(), std::bind1st(IsSame(), *response));
|
|
|
|
if (i != m_ExtResponses.end())
|
|
{
|
|
if ((--i->m_refCount) == 0)
|
|
{
|
|
sts = ReleaseResponse(response);
|
|
m_ExtResponses.erase(i);
|
|
}
|
|
return sts;
|
|
}
|
|
|
|
// if not found so far, then search in internal responses
|
|
std::list<mfxFrameAllocResponse>::iterator i2 =
|
|
std::find_if(m_responses.begin(), m_responses.end(), std::bind1st(IsSame(), *response));
|
|
|
|
if (i2 != m_responses.end())
|
|
{
|
|
sts = ReleaseResponse(response);
|
|
m_responses.erase(i2);
|
|
return sts;
|
|
}
|
|
|
|
// not found anywhere, report an error
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
}
|
|
|
|
mfxStatus BaseFrameAllocator::Close()
|
|
{
|
|
std::list<UniqueResponse> ::iterator i;
|
|
for (i = m_ExtResponses.begin(); i!= m_ExtResponses.end(); i++)
|
|
{
|
|
ReleaseResponse(&*i);
|
|
}
|
|
m_ExtResponses.clear();
|
|
|
|
std::list<mfxFrameAllocResponse> ::iterator i2;
|
|
for (i2 = m_responses.begin(); i2!= m_responses.end(); i2++)
|
|
{
|
|
ReleaseResponse(&*i2);
|
|
}
|
|
|
|
return MFX_ERR_NONE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
// MFXBufferAllocator
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
MFXBufferAllocator::MFXBufferAllocator()
|
|
{
|
|
pthis = this;
|
|
Alloc = Alloc_;
|
|
Lock = Lock_;
|
|
Free = Free_;
|
|
Unlock = Unlock_;
|
|
}
|
|
|
|
MFXBufferAllocator::~MFXBufferAllocator()
|
|
{
|
|
}
|
|
|
|
mfxStatus MFXBufferAllocator::Alloc_(mfxHDL pthis, mfxU32 nbytes, mfxU16 type, mfxMemId *mid)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
|
|
|
return self.AllocBuffer(nbytes, type, mid);
|
|
}
|
|
|
|
mfxStatus MFXBufferAllocator::Lock_(mfxHDL pthis, mfxMemId mid, mfxU8 **ptr)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
|
|
|
return self.LockBuffer(mid, ptr);
|
|
}
|
|
|
|
mfxStatus MFXBufferAllocator::Unlock_(mfxHDL pthis, mfxMemId mid)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
|
|
|
return self.UnlockBuffer(mid);
|
|
}
|
|
|
|
mfxStatus MFXBufferAllocator::Free_(mfxHDL pthis, mfxMemId mid)
|
|
{
|
|
if (0 == pthis)
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
|
|
MFXBufferAllocator& self = *(MFXBufferAllocator *)pthis;
|
|
|
|
return self.FreeBuffer(mid);
|
|
}
|
|
|