📄 umc_h264_nal_spl.cpp
字号:
/*
//
// 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) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_H264_VIDEO_DECODER)
#include "umc_structures.h"
#include "umc_h264_nal_spl.h"
#include "umc_automatic_mutex.h"
#include "umc_h264_bitstream.h"/* DEBUG: extra header */
#include "umc_h264_slice_decoding.h"
#include "umc_h264_task_supplier.h"
namespace UMC
{
inline
bool IsItAllowedCode(Ipp32s iCode)
{
if ((NAL_UT_SLICE <= (iCode & NAL_UNITTYPE_BITS)) &&
(NAL_UT_PPS >= (iCode & NAL_UNITTYPE_BITS)) &&
(NAL_UT_SEI != (iCode & NAL_UNITTYPE_BITS)) ||
(NAL_UT_SPS_EX == (iCode & NAL_UNITTYPE_BITS)) ||
(NAL_UT_AUXILIARY == (iCode & NAL_UNITTYPE_BITS)) )
return true;
return false;
} // bool IsItAllowedCode(Ipp32s iCode)
inline
bool IsHeaderCode(Ipp32s iCode)
{
return (NAL_UT_SPS == (iCode & NAL_UNITTYPE_BITS)) ||
(NAL_UT_SPS_EX == (iCode & NAL_UNITTYPE_BITS)) ||
(NAL_UT_PPS == (iCode & NAL_UNITTYPE_BITS));
}
inline
bool IsVLCCode(Ipp32s iCode)
{
return (NAL_UT_SLICE <= (iCode & NAL_UNITTYPE_BITS)) &&
(NAL_UT_IDR_SLICE >= (iCode & NAL_UNITTYPE_BITS)) ||
(NAL_UT_AUXILIARY == (iCode & NAL_UNITTYPE_BITS));
}
static
Ipp32s FindStartCode(Ipp8u * (&pb), size_t &nSize)
{
// there is no data
if ((Ipp32s) nSize < 4)
return 0;
// find start code
while ((4 <= nSize) && ((0 != pb[0]) ||
(0 != pb[1]) ||
(1 != pb[2])))
{
pb += 1;
nSize -= 1;
}
if (4 <= nSize)
return ((pb[0] << 24) | (pb[1] << 16) | (pb[2] << 8) | (pb[3]));
return 0;
} // Ipp32s FindStartCode(Ipp8u * (&pb), size_t &nSize)
class StartCodeIterator : public StartCodeIteratorBase
{
public:
virtual Ipp32s Init(MediaData * pSource)
{
StartCodeIteratorBase::Init(pSource);
Ipp32s iCode = FindStartCode(m_pSource, m_nSourceSize);
return iCode;
}
virtual Ipp32s GetNext()
{
m_pSource += 3;
m_nSourceSize -= 3;
Ipp32s iCode = FindStartCode(m_pSource, m_nSourceSize);
return iCode;
}
};
class SwapperBase
{
public:
virtual ~SwapperBase() {}
virtual
void SwapMemory(Ipp8u *pDestination, size_t &nDstSize, Ipp8u *pSource, size_t nSrcSize) = 0;
virtual void CopyBitStream(Ipp8u *pDestination, Ipp8u *pSource, size_t nSrcSize) = 0;
};
class Swapper : public SwapperBase
{
public:
virtual void SwapMemory(Ipp8u *pDestination, size_t &nDstSize, Ipp8u *pSource, size_t nSrcSize)
{
extern void SwapMemoryAndRemovePreventingBytes(void *pDst, size_t &nDstSize, void *pSrc, size_t nSrcSize);
SwapMemoryAndRemovePreventingBytes(pDestination, nDstSize, pSource, nSrcSize);
}
virtual void CopyBitStream(Ipp8u *pDestination, Ipp8u *pSource, size_t nSrcSize)
{
memcpy(pDestination, pSource, nSrcSize);
}
};
/*************************************************************************************/
// MP4 stuff
/*************************************************************************************/
static
inline Ipp32s GetValue16(Ipp8u * buf)
{
return ((*buf) << 8) | *(buf + 1);
}
static
inline Ipp32s GetValue24(Ipp8u * buf)
{
return ((*buf) << 16) | (*(buf + 1) << 8) | *(buf + 2);
}
static
inline Ipp32s GetValue32(Ipp8u * buf)
{
return ((*buf) << 24) | (*(buf + 1) << 16) | (*(buf + 2) << 8) | *(buf + 3);
}
static inline Ipp32s GetLenght(Ipp32s len_bytes_count, Ipp8u * buf)
{
Ipp32s lenght = 0;
switch (len_bytes_count)
{
case 1: // 1 byte
lenght = *buf;
break;
case 2: // 2 bytes
lenght = GetValue16(buf);
break;
case 3: // 3 bytes
lenght = GetValue24(buf);
break;
case 4: // 4 bytes
lenght = GetValue32(buf);
break;
}
return lenght;
} // Ipp32s GetLenght(Ipp32s len_bytes_count, Ipp8u * buf)
class StartCodeIteratorMP4 : public StartCodeIteratorBase
{
public:
void SetLenInBytes(Ipp32s lenInBytes)
{
m_lenInBytes = lenInBytes;
}
virtual Ipp32s Init(MediaData * pSource)
{
StartCodeIteratorBase::Init(pSource);
m_nSourceBaseSize = pSource->GetDataSize();
m_pSourceBase = m_pSource = (Ipp8u *) pSource->GetDataPointer();
m_fullSize = pSource->GetDataSize();
m_nSourceSize = 0;
Ipp32s iCode = *(m_pSource + m_lenInBytes);
return iCode;
}
/*size_t GetCurrentOffset()
{
return m_nSourceSize;
}*/
virtual Ipp32s GetNext()
{
Ipp32s lenght = GetLenght(m_lenInBytes, m_pSource);
m_pSource += lenght + m_lenInBytes;
m_nSourceSize += lenght + m_lenInBytes;
if (m_nSourceSize >= m_fullSize)
return 0;
Ipp32s iCode = *(m_pSource + m_lenInBytes);
return iCode;
}
private:
size_t m_fullSize;
Ipp32s m_lenInBytes;
};
class SwapperForMP4 : public SwapperBase
{
public:
SwapperForMP4(Ipp32s lengthSize = 0)
: m_lengthSize(lengthSize)
{
}
void SetTrackLenghtSize(Ipp32s lengthSize)
{
m_lengthSize = lengthSize;
}
virtual
void SwapMemory(Ipp8u *pDestination, size_t &nDstSize, Ipp8u *pSource, size_t nSrcSize)
{
BuildNALUnit(pDestination, nDstSize, pSource, nSrcSize, m_lengthSize);
}
virtual void CopyBitStream(Ipp8u *pDestination, Ipp8u *pSource, size_t nSrcSize)
{
static Ipp8u start_code_prefix[] = {0, 0, 0, 1};
memcpy(pDestination, start_code_prefix, 4);
memcpy(pDestination + 4, pSource + m_lengthSize, nSrcSize - m_lengthSize);
}
private:
Ipp32s m_lengthSize;
};
NALUnitSplitter::NALUnitSplitter(H264_Heap * heap)
: m_pHeap(heap)
, m_pSupplier(0)
, m_bWaitForIDR(true)
, m_pSwapper(0)
, m_pMem(0)
, m_pMemCopy(0)
, m_pStartCodeIter(0)
, m_IsSaveCopy(false)
{
m_MediaData.SetExData(&m_MediaDataEx);
}
NALUnitSplitter::~NALUnitSplitter()
{
Release();
}
void NALUnitSplitter::Init()
{
Release();
m_bWaitForIDR = true;
m_pSwapper = new Swapper();
m_pStartCodeIter = new StartCodeIterator();
}
void NALUnitSplitter::Reset()
{
Commit();
m_bWaitForIDR = true;
}
void NALUnitSplitter::Release()
{
delete m_pSwapper;
m_pSwapper = 0;
delete m_pStartCodeIter;
m_pStartCodeIter = 0;
}
void NALUnitSplitter::Commit()
{
m_pHeap->Free(m_pMem);
m_pHeap->Free(m_pMemCopy);
m_pMem = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -