v0.42:
- D3D11 decode + VPP. Windows 8 only feature. May not work on switchable graphics solutions. - Fixed some minor issues with VPP (time stamp interpolation). - Fixed AVC1 frame constructor. No longer will it process AnnexB streams. This should fix TV streaming. It doesn't support fragmented streams (NALs that span more than 1 packet). - Made legal license identical across my files. - Some code cosmetics too. - Looks stable for both win8 and win7. git-svn-id: svn://svn.code.sf.net/p/qsdecoder/code/trunk/IntelQuickSyncDecoder@87 dfccccb7-dd81-40b7-a334-5a7ba89c2b1d
This commit is contained in:
parent
16f7888f92
commit
56dff413a1
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -65,7 +65,7 @@ CQuickSync::CQuickSync() :
|
|||
)
|
||||
{
|
||||
MSDK_TRACE("QsDecoder: Constructor\n");
|
||||
strcpy(m_CodecName, "Intel\xae QuickSync Decoder");
|
||||
strcpy_s(m_CodecName, "Intel\xae QuickSync Decoder");
|
||||
|
||||
mfxStatus sts = MFX_ERR_NONE;
|
||||
|
||||
|
@ -194,7 +194,10 @@ HRESULT CQuickSync::HandleSubType(const AM_MEDIA_TYPE* mtIn, FOURCC fourCC, mfxV
|
|||
return VFW_E_INVALIDMEDIATYPE;
|
||||
|
||||
videoParams.mfx.CodecId = MFX_CODEC_AVC;
|
||||
// Always use CAVCFrameConstructor, allows handling/fixing stream error
|
||||
// Note: CAVCFrameConstructor can handle both H264 stream types but it can't handle fragment streams (e.g. live TV)
|
||||
// pFrameConstructor = ((fourCC == FOURCC_avc1) || (fourCC == FOURCC_AVC1) || (fourCC == FOURCC_CCV1)) ?
|
||||
// new CAVCFrameConstructor :
|
||||
// new CFrameConstructor;
|
||||
pFrameConstructor = new CAVCFrameConstructor;
|
||||
}
|
||||
else
|
||||
|
@ -1243,6 +1246,7 @@ HRESULT CQuickSync::ProcessDecodedFrame(mfxFrameSurface1* pOutSurface)
|
|||
// Reset failed...
|
||||
if (sts < 0)
|
||||
{
|
||||
MSDK_TRACE("QsDecoder: Error VPP reset failed!\n")
|
||||
// Change config to disable VPP from being created for this video
|
||||
if (sts != MFX_ERR_NOT_INITIALIZED)
|
||||
{
|
||||
|
@ -1270,21 +1274,8 @@ HRESULT CQuickSync::ProcessDecodedFrame(mfxFrameSurface1* pOutSurface)
|
|||
// Run VPP
|
||||
sts = m_pVPP->Process(pInSurface, pOutSurface);
|
||||
|
||||
// Check time stamp, interpolate newly created frames
|
||||
if (sts >= 0 || MFX_ERR_MORE_SURFACE == sts)
|
||||
{
|
||||
if (m_Config.bVppEnableDITimeStampsInterpolation)
|
||||
{
|
||||
REFERENCE_TIME rtNewStart = (MFX_ERR_MORE_SURFACE == sts) ? rtPrevStart : m_TimeManager.GetLastTimeStamp();
|
||||
if (pOutSurface->Data.TimeStamp == MFX_TIME_STAMP_INVALID && m_Config.bVppEnableFullRateDI && pOutSurface->Info.FrameRateExtN > 0)
|
||||
{
|
||||
rtNewStart += (REFERENCE_TIME)(0.5 + 1e7 * (double)pOutSurface->Info.FrameRateExtD / (double)pOutSurface->Info.FrameRateExtN);
|
||||
pOutSurface->Data.TimeStamp = m_TimeManager.ConvertReferenceTime2MFXTime(rtNewStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
// VPP failed
|
||||
else
|
||||
if (MSDK_FAILED(sts) && sts != MFX_ERR_MORE_SURFACE)
|
||||
{
|
||||
MSDK_TRACE("QsDecoder: VPP->Process failed with error %i\n", (int)sts);
|
||||
pOutSurface = pInSurface;
|
||||
|
@ -1293,6 +1284,17 @@ HRESULT CQuickSync::ProcessDecodedFrame(mfxFrameSurface1* pOutSurface)
|
|||
}
|
||||
}
|
||||
|
||||
// Check time stamp, interpolate newly created frames
|
||||
if (MFX_ERR_MORE_SURFACE == sts && m_Config.bVppEnableDITimeStampsInterpolation)
|
||||
{
|
||||
if (pOutSurface->Data.TimeStamp == MFX_TIME_STAMP_INVALID && m_Config.bVppEnableFullRateDI && pOutSurface->Info.FrameRateExtN > 0)
|
||||
{
|
||||
REFERENCE_TIME rtNewStart = (MFX_ERR_MORE_SURFACE == sts) ? rtPrevStart : m_TimeManager.GetLastTimeStamp();
|
||||
rtNewStart += (REFERENCE_TIME)(0.5 + 1e7 * (double)pOutSurface->Info.FrameRateExtD / (double)pOutSurface->Info.FrameRateExtN);
|
||||
pOutSurface->Data.TimeStamp = m_TimeManager.ConvertReferenceTime2MFXTime(rtNewStart);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this flag is not very reliable - don't take any action because of it
|
||||
if (pOutSurface->Data.Corrupted)
|
||||
{
|
||||
|
@ -1402,7 +1404,8 @@ void CQuickSync::UpdateAspectRatio(mfxFrameSurface1* pSurface, QsFrameData& fram
|
|||
void CQuickSync::FlushVPP()
|
||||
{
|
||||
MSDK_CHECK_POINTER_NO_RET(m_pVPP);
|
||||
|
||||
REFERENCE_TIME rtPrevStart = m_TimeManager.GetLastTimeStamp();
|
||||
int count = 0;
|
||||
while (!m_bNeedToFlush)
|
||||
{
|
||||
mfxFrameSurface1* pOutSurface = m_pVPP->FlushFrame();
|
||||
|
@ -1413,6 +1416,17 @@ void CQuickSync::FlushVPP()
|
|||
break;
|
||||
}
|
||||
|
||||
// Check time stamp, interpolate newly created frames
|
||||
if (m_Config.bVppEnableDITimeStampsInterpolation)
|
||||
{
|
||||
if (pOutSurface->Data.TimeStamp == MFX_TIME_STAMP_INVALID && m_Config.bVppEnableFullRateDI && pOutSurface->Info.FrameRateExtN > 0)
|
||||
{
|
||||
REFERENCE_TIME rtNewStart = rtPrevStart;
|
||||
rtNewStart += (REFERENCE_TIME)(0.5 + (double)(++count) * 1e7 * (double)pOutSurface->Info.FrameRateExtD / (double)pOutSurface->Info.FrameRateExtN);
|
||||
pOutSurface->Data.TimeStamp = m_TimeManager.ConvertReferenceTime2MFXTime(rtNewStart);
|
||||
}
|
||||
}
|
||||
|
||||
// If input frame was meant to be discarded then we still want to VPP to work -
|
||||
// minimize VPP initialization artifacts
|
||||
DeliverSurface(pOutSurface);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -595,6 +595,7 @@ mfxStatus CQuickSyncDecoder::CreateAllocator()
|
|||
// HW device must be initialized early - within session init.
|
||||
// If a call to DecodeHeader was called before session->SetHandle, SetHandle would fail.
|
||||
ASSERT(m_HwDevice);
|
||||
MSDK_CHECK_POINTER(m_HwDevice, MFX_ERR_NULL_PTR);
|
||||
|
||||
D3D11AllocatorParams* p = new D3D11AllocatorParams;
|
||||
p->pDevice = (ID3D11Device*)m_HwDevice->GetHandle(MFX_HANDLE_D3D11_DEVICE);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -36,7 +36,7 @@
|
|||
#define MIN_REQUIRED_API_VER_MAJOR 1
|
||||
|
||||
// VS2012 provides AVX and AVX2 intrinsics
|
||||
#if _MSC_VER >= 1700
|
||||
#if 0// _MSC_VER >= 1700 // AVX2 copy is not faster than SSE2, it's slower. Copy function is left for reference only.
|
||||
# define AVX_ENABLED
|
||||
# define AVX2_ENABLED
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
@ -98,10 +98,10 @@ protected:
|
|||
// compare responses by actual frame size, alignment (w and h) is up to application
|
||||
UniqueResponse(const mfxFrameAllocResponse & response, mfxU16 cropw, mfxU16 croph, mfxU16 type)
|
||||
: mfxFrameAllocResponse(response)
|
||||
, m_type(type)
|
||||
, m_refCount(1)
|
||||
, m_cropw(cropw)
|
||||
, m_croph(croph)
|
||||
, m_refCount(1)
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
//compare by resolution
|
||||
|
|
|
@ -160,7 +160,7 @@ mfxStatus D3D11FrameAllocator::LockFrame(mfxMemId mid, mfxFrameData *ptr)
|
|||
hRes = m_pDeviceContext->Map(sr.GetStaging(), 0, mapType, mapFlags, &lockedRect);
|
||||
if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes)
|
||||
{
|
||||
printf("ERROR: m_pDeviceContext->Map = 0x%X\n", hRes);
|
||||
MSDK_TRACE("ERROR: m_pDeviceContext->Map = 0x%lX\n", hRes);
|
||||
}
|
||||
}
|
||||
while (DXGI_ERROR_WAS_STILL_DRAWING == hRes);
|
||||
|
@ -388,7 +388,7 @@ mfxStatus D3D11FrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrame
|
|||
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
printf("CreateTexture2D(%d) failed, hr = \n", i, hRes);
|
||||
MSDK_TRACE("CreateTexture2D(%d) failed, hr = 0x%lX\n", (int)i, hRes);
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
newTexture.textures.push_back(pTexture2D);
|
||||
|
@ -406,7 +406,7 @@ mfxStatus D3D11FrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrame
|
|||
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
printf("Create staging texture(%d) failed hr = \n", i, hRes);
|
||||
MSDK_TRACE("Create staging texture(%d) failed hr = 0x%lX\n", (int)i, hRes);
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
newTexture.stagingTexture.push_back(pTexture2D);
|
||||
|
|
|
@ -98,8 +98,13 @@ protected:
|
|||
HANDLE m_handle;
|
||||
};
|
||||
|
||||
D3DFrameAllocator::D3DFrameAllocator()
|
||||
: m_decoderService(0), m_processorService(0), m_hDecoder(0), m_hProcessor(0), m_manager(0), m_surfaceUsage(0)
|
||||
D3DFrameAllocator::D3DFrameAllocator() :
|
||||
m_manager(0),
|
||||
m_decoderService(0),
|
||||
m_processorService(0),
|
||||
m_hDecoder(0),
|
||||
m_hProcessor(0),
|
||||
m_surfaceUsage(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
36
d3d_device.h
36
d3d_device.h
|
@ -1,12 +1,30 @@
|
|||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011 - 2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -548,25 +548,28 @@ mfxStatus CAVCFrameConstructor::ConstructHeaders(VIDEOINFOHEADER2* vih,
|
|||
|
||||
mfxStatus CAVCFrameConstructor::ConstructFrame(IMediaSample* pSample, mfxBitstream* pBS)
|
||||
{
|
||||
mfxU32 nDataSize = 0;
|
||||
// AnnexB style stream - just copy the buffer as is.
|
||||
if (0 == m_NalSize)
|
||||
{
|
||||
return CFrameConstructor::ConstructFrame(pSample, pBS);
|
||||
}
|
||||
|
||||
mfxU8* pDataBuffer = NULL;
|
||||
CH264Nalu itStartCode;
|
||||
size_t nNalDataLen;
|
||||
const mfxU8* pNalDataBuff;
|
||||
m_TempBuffer.clear();
|
||||
MSDK_CHECK_POINTER(pSample, MFX_ERR_NULL_PTR);
|
||||
MSDK_CHECK_POINTER(pBS, MFX_ERR_NULL_PTR);
|
||||
|
||||
UpdateTimeStamp(pSample, pBS);
|
||||
|
||||
nDataSize = pSample->GetActualDataLength();
|
||||
|
||||
mfxU32 nDataSize = pSample->GetActualDataLength();
|
||||
MSDK_CHECK_ERROR(nDataSize, 0, MFX_ERR_MORE_DATA);
|
||||
m_TempBuffer.reserve(nDataSize * 3 / 2);
|
||||
|
||||
pSample->GetPointer(&pDataBuffer);
|
||||
MSDK_CHECK_POINTER(pDataBuffer, MFX_ERR_NULL_PTR);
|
||||
|
||||
itStartCode.SetBuffer(pDataBuffer, nDataSize, m_NalSize); // Nal size = 4
|
||||
MSDK_CHECK_POINTER(pDataBuffer, MFX_ERR_NULL_PTR);
|
||||
m_TempBuffer.clear();
|
||||
m_TempBuffer.reserve(nDataSize);
|
||||
|
||||
CH264Nalu itStartCode;
|
||||
itStartCode.SetBuffer(pDataBuffer, nDataSize, m_NalSize); // Nal size = 4 (usually); declared in extra data (ConstructHeaders)
|
||||
|
||||
// Iterate over the NALUs and convert them to have start codes.
|
||||
while (itStartCode.ReadNext())
|
||||
|
@ -580,8 +583,8 @@ mfxStatus CAVCFrameConstructor::ConstructFrame(IMediaSample* pSample, mfxBitstre
|
|||
if (!IS_VALID_NALU(naluType))
|
||||
continue;
|
||||
|
||||
nNalDataLen = itStartCode.GetDataLength();
|
||||
pNalDataBuff = itStartCode.GetDataBuffer();
|
||||
size_t nNalDataLen = itStartCode.GetDataLength();
|
||||
const BYTE* pNalDataBuff = itStartCode.GetDataBuffer();
|
||||
|
||||
ASSERT(nNalDataLen > 0); // Shouldn't fail!
|
||||
if (nNalDataLen > 0)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, INTEL CORPORATION
|
||||
* Copyright (c) 2013, INTEL CORPORATION
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -77,7 +77,7 @@ class CAVCFrameConstructor : public CFrameConstructor
|
|||
public:
|
||||
CAVCFrameConstructor();
|
||||
~CAVCFrameConstructor();
|
||||
virtual mfxStatus ConstructFrame(IMediaSample* pSample, mfxBitstream* pBS);
|
||||
mfxStatus ConstructFrame(IMediaSample* pSample, mfxBitstream* pBS);
|
||||
mfxStatus ConstructHeaders(VIDEOINFOHEADER2* vih,
|
||||
const GUID& guidFormat,
|
||||
size_t nMtSize,
|
||||
|
@ -87,5 +87,5 @@ private:
|
|||
mfxU32 m_NalSize;
|
||||
mfxU32 m_HeaderNalSize;
|
||||
mfxU8 m_H264StartCode[4];
|
||||
std::vector<mfxU8> m_TempBuffer;
|
||||
std::vector<mfxU8> m_TempBuffer; // used for building the output stream
|
||||
};
|
||||
|
|
36
hw_device.h
36
hw_device.h
|
@ -1,12 +1,30 @@
|
|||
/* ****************************************************************************** *\
|
||||
|
||||
INTEL CORPORATION PROPRIETARY INFORMATION
|
||||
This software is supplied under the terms of a license agreement or nondisclosure
|
||||
agreement with Intel Corporation and may not be copied or disclosed except in
|
||||
accordance with the terms of that agreement
|
||||
Copyright(c) 2011 - 2012 Intel Corporation. All Rights Reserved.
|
||||
|
||||
\* ****************************************************************************** */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
Loading…
Reference in New Issue