⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_nal_spl.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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 + -