1
0
Fork 0
qsdecoder/base_alllocator.cpp

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);
}