📄 umc_h264_nal_spl.cpp
字号:
m_pMemCopy = 0;
m_MediaDataEx.count = 0;
}
void NALUnitSplitter::DropMemory()
{
m_pMem = 0;
m_pMemCopy = 0;
m_MediaDataEx.count = 0;
}
Ipp32s NALUnitSplitter::CheckNalUnitType(MediaData * pSource)
{
if (!pSource)
return 0;
return m_pStartCodeIter->Init(pSource) & NAL_UNITTYPE_BITS; // find first start code
}
H264MemoryPiece * NALUnitSplitter::GetNalUnits(MediaData * pSource, MediaDataEx *&out, H264MemoryPiece ** pMemCopy)
{
out = &m_MediaData;
MediaDataEx::_MediaDataEx* pMediaDataEx = &m_MediaDataEx;
if (m_pMemCopy)
*pMemCopy = m_pMemCopy;
if (!pSource)
return m_pMem;
if (m_pMem)
return m_pMem;
#define MAX_TEMPORAL_SWAP_BUFFER_SIZE 32
static Ipp8u temporalSwapBuf[2*MAX_TEMPORAL_SWAP_BUFFER_SIZE];
Ipp8u * const pOriginal = (Ipp8u *) pSource->GetDataPointer();
size_t nOriginalSize = pSource->GetDataSize();
Ipp32s iCode = m_pStartCodeIter->Init(pSource); // find first start code
if (iCode == 0)
{
pMediaDataEx->count = 0;
pSource->MoveDataPointer(nOriginalSize);
return 0;
}
pMediaDataEx->values[0] = iCode & NAL_UNITTYPE_BITS;
size_t firstOffset = m_pStartCodeIter->GetCurrentOffset();
iCode = m_pStartCodeIter->GetNext();
if (iCode)
nOriginalSize = m_pStartCodeIter->GetCurrentOffset() - firstOffset;
else
nOriginalSize -= firstOffset;
pSource->MoveDataPointer(nOriginalSize + firstOffset);
size_t nDstSize = nOriginalSize;
if (m_IsSaveCopy && pMemCopy)
{
*pMemCopy = m_pHeap->Allocate(nDstSize + 8);
memset((*pMemCopy)->GetPointer() + nDstSize, 0, 8);
m_pSwapper->CopyBitStream((*pMemCopy)->GetPointer(), pOriginal + firstOffset,
nOriginalSize);
(*pMemCopy)->SetDataSize(nOriginalSize);
m_pMemCopy = *pMemCopy;
}
H264MemoryPiece *pMem = m_pHeap->Allocate(nDstSize + 8);
memset(pMem->GetPointer() + nDstSize, 0, 8);
m_pSwapper->SwapMemory(pMem->GetPointer(),
nDstSize,
pOriginal + firstOffset,
nOriginalSize);
pMediaDataEx->offsets[0] = 0;
pMediaDataEx->offsets[1] = nDstSize;
pMediaDataEx->count = 1;
pMem->SetDataSize(nDstSize);
m_pMem = pMem;
return pMem;
}
size_t BuildNALUnit(Ipp8u * write_buf, size_t &nDstSize, Ipp8u * buf, size_t lenght, Ipp32s lengthSize)
{
static Ipp8u start_code_prefix[] = {0, 0, 0, 1};
size_t len = NALUnitSplitterMP4::D_START_CODE_LENGHT;
SwapMemoryAndRemovePreventingBytes(write_buf, len, &start_code_prefix, len);
len = GetLenght(lengthSize, buf);
buf += lengthSize;
if (lenght)
{
lenght = IPP_MIN(lenght, len);
write_buf += NALUnitSplitterMP4::D_START_CODE_LENGHT;
SwapMemoryAndRemovePreventingBytes(write_buf, len, buf, lenght);
nDstSize = (len + NALUnitSplitterMP4::D_START_CODE_LENGHT);
return lenght;
}
else
{
lenght = (len + lengthSize);
write_buf += NALUnitSplitterMP4::D_START_CODE_LENGHT;
SwapMemoryAndRemovePreventingBytes(write_buf, len, buf, len);
nDstSize = (len + NALUnitSplitterMP4::D_START_CODE_LENGHT);
return lenght;
}
} // Ipp32s BuildNALUnit
NALUnitSplitterMP4::NALUnitSplitterMP4(H264_Heap * heap)
: NALUnitSplitter(heap)
, m_isHeaderReaded(false)
{
}
void NALUnitSplitterMP4::Init()
{
Release();
m_bWaitForIDR = true;
m_pSwapper = new SwapperForMP4();
m_pStartCodeIter = new StartCodeIteratorMP4();
m_isHeaderReaded = false;
}
void NALUnitSplitterMP4::Reset()
{
NALUnitSplitter::Reset();
}
Ipp32s NALUnitSplitterMP4::CheckNalUnitType(MediaData * pSource)
{
if (!pSource)
return 0;
if (m_isHeaderReaded)
{
return *((Ipp8u*)pSource->GetDataPointer() + (avcRecord.lengthSizeMinusOne + 1)) & NAL_UNITTYPE_BITS;
}
return NAL_UT_SPS;
}
void NALUnitSplitterMP4::ReadHeader(MediaData * pSource)
{
MediaDataEx::_MediaDataEx* pMediaEx = &m_MediaDataEx;
Ipp8u *p = (Ipp8u *) pSource->GetDataPointer();
avcRecord.configurationVersion = *p;
//VM_ASSERT(avc_record.configurationVersion != 1);
p++;
avcRecord.AVCProfileIndication = *p;
p++;
avcRecord.profile_compatibility = *p;
p++;
avcRecord.AVCLevelIndication = *p;
p++;
avcRecord.lengthSizeMinusOne = *p;
avcRecord.lengthSizeMinusOne <<= 6;
avcRecord.lengthSizeMinusOne >>= 6; // remove reserved bits
p++;
avcRecord.numOfSequenceParameterSets = *p;
avcRecord.numOfSequenceParameterSets <<= 3;
avcRecord.numOfSequenceParameterSets >>= 3;// remove reserved bits
p++;
// calculate lenght of memory
// read sequence par sets
Ipp8u * temp = p;
Ipp32s i;
size_t result_lenght = 0;
Ipp32s nNALUnitsCount = 0;
for (i = 0; i < avcRecord.numOfSequenceParameterSets; i++)
{
Ipp32s lenght = GetValue16(temp);
Ipp32s iCode = *(temp + D_BYTES_FOR_HEADER_LENGHT);
pMediaEx->offsets[nNALUnitsCount] = (Ipp32u) result_lenght;
pMediaEx->values[nNALUnitsCount] = iCode & NAL_UNITTYPE_BITS;
nNALUnitsCount++;
temp += lenght + D_BYTES_FOR_HEADER_LENGHT;
result_lenght += lenght + D_START_CODE_LENGHT;
}
if (result_lenght > pSource->GetDataSize() + avcRecord.numOfSequenceParameterSets*2 + 3)
{
pSource->SetDataSize(0);
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
avcRecord.numOfPictureParameterSets = *temp;
temp++;
for (i = 0; i < avcRecord.numOfPictureParameterSets; i++)
{
Ipp32s lenght = GetValue16(temp);
Ipp32s iCode = *(temp + D_BYTES_FOR_HEADER_LENGHT);
pMediaEx->offsets[nNALUnitsCount] = (Ipp32u) result_lenght;
pMediaEx->values[nNALUnitsCount] = iCode & NAL_UNITTYPE_BITS;
nNALUnitsCount++;
temp += lenght + D_BYTES_FOR_HEADER_LENGHT;
result_lenght += lenght + D_START_CODE_LENGHT;
}
result_lenght += 3; // for swap mode
if (!result_lenght && (result_lenght > pSource->GetDataSize() +
(avcRecord.numOfSequenceParameterSets + avcRecord.numOfPictureParameterSets + 3)*2))
{
pSource->SetDataSize(0);
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
m_pMem = m_pHeap->Allocate(result_lenght);
Ipp8u * write_buf = m_pMem->GetPointer();
nNALUnitsCount = 0;
// read sequence par sets
for (i = 0; i < avcRecord.numOfSequenceParameterSets; i++)
{
size_t nal_unit_lenght;
size_t lenght = BuildNALUnit(write_buf, nal_unit_lenght, p, 0, D_BYTES_FOR_HEADER_LENGHT);
pMediaEx->offsets[nNALUnitsCount++] = (Ipp32u)(write_buf - m_pMem->GetPointer());
write_buf += nal_unit_lenght;
p += lenght;
}
avcRecord.numOfPictureParameterSets = *p;
p++;
// read picture par sets
for (i = 0; i < avcRecord.numOfPictureParameterSets; i++)
{
size_t nal_unit_lenght;
size_t lenght = BuildNALUnit(write_buf, nal_unit_lenght, p, 0, D_BYTES_FOR_HEADER_LENGHT);
pMediaEx->offsets[nNALUnitsCount++] = (Ipp32u)(write_buf - m_pMem->GetPointer());
write_buf += nal_unit_lenght;
p += lenght;
}
result_lenght = write_buf - m_pMem->GetPointer();
pMediaEx->count = nNALUnitsCount;
pMediaEx->offsets[nNALUnitsCount] = (Ipp32u)result_lenght;
pSource->SetDataSize(0);
m_isHeaderReaded = true;
}
H264MemoryPiece * NALUnitSplitterMP4::GetNalUnits(MediaData * pSource, MediaDataEx *&out, H264MemoryPiece ** pMemCopy)
{
out = &m_MediaData;
if (pMemCopy)
*pMemCopy = m_pMemCopy;
if (!pSource)
return m_pMem;
if (m_pMem)
return m_pMem;
if (!m_isHeaderReaded)
{
ReadHeader(pSource);
((SwapperForMP4*)m_pSwapper)->SetTrackLenghtSize(avcRecord.lengthSizeMinusOne + 1);
return m_pMem;
}
((StartCodeIteratorMP4*)m_pStartCodeIter)->SetLenInBytes(avcRecord.lengthSizeMinusOne + 1);
return NALUnitSplitter::GetNalUnits(pSource, out, pMemCopy);
}
} // namespace UMC
#endif // UMC_ENABLE_H264_VIDEO_DECODER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -