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

📄 umc_frame_constructor.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    while (0 == bs.GetBits(8)); // skip all zeroes and one
    bs.GetBits(8); // skip nal_ref_idc and nal_unit_type

    Ipp8u uiPPSId = (Ipp8u)bs.GetUE();
    if (uiPPSId >= MAX_NUM_PPS_PARSETS)
        return UMC_ERR_INVALID_STREAM;

    FCH264PicParSet *pPPS = &pHeaders->m_PPS[uiPPSId];
    pPPS->seq_parameter_set_id = (Ipp8u)bs.GetUE();
    if (pPPS->seq_parameter_set_id >= MAX_NUM_SPS_PARSETS)
        return UMC_ERR_INVALID_STREAM;

    bs.GetBit(); // entropy_coding_mode
    pPPS->pic_order_present_flag = (Ipp8u)bs.GetBit();

    // if no error validate PPS
    pPPS->pic_parameter_set_id = uiPPSId;
    return UMC_OK;
}

Status H264FrameConstructor::ParseSliceHeader(Ipp8u *buf, Ipp32s iLen, H264HeaderSet *pHeaders, Mpeg2TrackInfo *pInfo)
{
    iLen;
    InterlaceType interlace_type = PROGRESSIVE;
    FCH264SliceHeader sh;
    H264BitstreamReader bs;
    bs.Init(buf);

    while (0 == bs.GetBits(8)); // skip all zeroes and one
    bs.GetBit(); // skip forbidden zero bit
    sh.nal_ref_idc = (Ipp8u)bs.GetBits(2);
    sh.idr_flag = (5 == bs.GetBits(5));

    bs.GetUE(); // first_mb_in_slice
    sh.slice_type = (Ipp8u)bs.GetUE();
    if (sh.slice_type > 9)
        return UMC_ERR_INVALID_STREAM;

    sh.pic_parameter_set_id = (Ipp8u)bs.GetUE();
    if (sh.pic_parameter_set_id >= MAX_NUM_PPS_PARSETS)
        return UMC_ERR_INVALID_STREAM;

    FCH264PicParSet *pPPS = &pHeaders->m_PPS[sh.pic_parameter_set_id];
    if (MAX_NUM_PPS_PARSETS == pPPS->pic_parameter_set_id)
    {
        sh.pic_parameter_set_id = MAX_NUM_PPS_PARSETS; // invalidate slice
        return UMC_ERR_INVALID_STREAM; // wrong reference
    }

    FCH264SeqParSet *pSPS = &pHeaders->m_SPS[pPPS->seq_parameter_set_id];
    if (MAX_NUM_SPS_PARSETS == pSPS->seq_parameter_set_id)
        return UMC_ERR_INVALID_STREAM; // wrong reference

    sh.frame_num = bs.GetBits(pSPS->log2_max_frame_num);
    if (0 == pSPS->frame_mbs_only_flag)
    {
        sh.field_pic_flag = (Ipp8u)bs.GetBit();
        if (0 != sh.field_pic_flag)
        {
            sh.bottom_field_flag = (Ipp8u)bs.GetBit();
            interlace_type = sh.bottom_field_flag ? INTERLEAVED_BOTTOM_FIELD_FIRST : INTERLEAVED_TOP_FIELD_FIRST;
        }
    }

    if (sh.idr_flag)
        sh.idr_pic_id = bs.GetUE();

    if (0 == pSPS->pic_order_cnt_type)
    {
        sh.pic_order_cnt_lsb = bs.GetBits(pSPS->log2_max_pic_order_cnt_lsb);
        if (pPPS->pic_order_present_flag && !sh.field_pic_flag)
            sh.delta_pic_order_cnt_bottom = bs.GetSE();
    }

    if (1 == pSPS->pic_order_cnt_type && 0 == pSPS->delta_pic_order_always_zero_flag)
    {
        sh.delta_pic_order_cnt[0] = bs.GetSE();
        if (pPPS->pic_order_present_flag && !sh.field_pic_flag)
            sh.delta_pic_order_cnt[1] = bs.GetSE();
    }

    if (pHeaders->iShCount == 1)
        pHeaders->m_PrevSH = pHeaders->m_LastSH;
    pHeaders->m_LastSH = sh;
    pHeaders->iShCount++;

    if (pInfo)
        ((VideoStreamInfo *)pInfo->m_pStreamInfo)->interlace_type = interlace_type;
    return UMC_OK;
}

bool H264FrameConstructor::IsFirstVLCNALUnit(H264HeaderSet *pHeaders)
{
    FCH264SeqParSet *pSPS = pHeaders->m_SPS;
    FCH264PicParSet *pPPS = pHeaders->m_PPS;
    FCH264SliceHeader *pLastSH = &pHeaders->m_LastSH;
    FCH264SliceHeader *pPrevSH = &pHeaders->m_PrevSH;

    if (pHeaders->iShCount < 2)
        return false;

    // one of slices refers to invalid PPS
    if (MAX_NUM_PPS_PARSETS == pLastSH->pic_parameter_set_id ||
        MAX_NUM_PPS_PARSETS == pPrevSH->pic_parameter_set_id)
        return true;

    // frame_num differs in value
    if (pLastSH->frame_num != pPrevSH->frame_num)
        return true;

    // pic_parameter_set_id differs in value
    if (pLastSH->pic_parameter_set_id != pPrevSH->pic_parameter_set_id)
        return true;

    // field_pic_flag differs in value
    if (pLastSH->field_pic_flag != pPrevSH->field_pic_flag)
        return true;

    // bottom_pic_flag is present in both and differs in value
    if (pLastSH->field_pic_flag && pPrevSH->field_pic_flag)
        if (pLastSH->bottom_field_flag != pPrevSH->bottom_field_flag)
            return true;

    // nal_ref_idc differs in value with one of the nal_ref_idc values being equal to 0
    if (0 != pLastSH->nal_ref_idc && pHeaders->bOneOfNALRefIdcEqualTo0)
        return true;

    // pic_order_cnt_type is equal to 0 for both and
    // either pic_order_cnt_lsb differs in value, or delta_pic_order_cnt_bottom differs in value
    if (0 == pSPS[pPPS[pLastSH->pic_parameter_set_id].seq_parameter_set_id].pic_order_cnt_type &&
        0 == pSPS[pPPS[pPrevSH->pic_parameter_set_id].seq_parameter_set_id].pic_order_cnt_type)
        if (pLastSH->pic_order_cnt_lsb != pPrevSH->pic_order_cnt_lsb ||
            pLastSH->delta_pic_order_cnt_bottom != pPrevSH->delta_pic_order_cnt_bottom)
            return true;

    // pic_order_cnt_type is equal to 1 for both and
    // either delta_pic_order_cnt[0] differs in value, or delta_pic_order_cnt[1] differs in value
    if (1 == pSPS[pPPS[pLastSH->pic_parameter_set_id].seq_parameter_set_id].pic_order_cnt_type &&
        1 == pSPS[pPPS[pPrevSH->pic_parameter_set_id].seq_parameter_set_id].pic_order_cnt_type)
        if (pLastSH->delta_pic_order_cnt[0] != pPrevSH->delta_pic_order_cnt[0] ||
            pLastSH->delta_pic_order_cnt[1] != pPrevSH->delta_pic_order_cnt[1])
            return true;

    // nal_unit_type differs in value with one of the nal_unit_type values being equal to 5
    if (!pLastSH->idr_flag && pHeaders->bOneOfNALUnitTypeEqualTo5)
        return true;

    // nal_unit_type is equal to 5 for both and idr_pic_id differs in value
    if (pLastSH->idr_flag && pPrevSH->idr_flag)
        if (pLastSH->idr_pic_id != pPrevSH->idr_pic_id)
            return true;

    return false;
}

FrameConstructorParams::FrameConstructorParams()
{
    m_pInfo = NULL;
    m_lBufferSize = 0;
    m_nOfFrames = 0;
    m_pMemoryAllocator = NULL;
}

FrameConstructor::FrameConstructor()
{
    // reset variables
    m_midAllocatedBuffer = MID_INVALID;
    m_pMemoryAllocator = NULL;
    m_pAllocated = NULL;
    m_pBuf = NULL;
    m_pInfo = NULL;

    m_bEndOfStream = false;
    m_bIsOutputBufferLocked = false;
    m_bInfoFilled = false;

    m_lBufferSize = 0;
    m_lLastBytePos = 0;
    m_lFirstBytePos = 0;
    m_lCurPos = 0;
    m_lCurPicStart = 0;
    m_iCurrentLevel = 0;
    m_uiCommitedFrames = 0;
    m_uiTotalFrames = 0;
    m_iFirstInDecOrderIdx = 0;
    m_dRate = 1.0;

    m_LastFrame.SetBufferPointer(NULL, 0);
    m_LastFrame.SetAbsPos(0);
    m_LastFrame.SetTime(-1.0, -1.0);

    // reset mutex
    vm_mutex_set_invalid(&m_synchro);

}

FrameConstructor::~FrameConstructor()
{
    Close();

    // destroy mutex
    if (1 == vm_mutex_is_valid(&m_synchro))
        vm_mutex_destroy(&m_synchro);

}

Status FrameConstructor::Stop()
{
    return UMC_OK;
}

Status FrameConstructor::Init(MediaReceiverParams *pInit)
{
    FrameConstructorParams *pParams = DynamicCast<FrameConstructorParams> (pInit);

    if (NULL == pParams)
        return UMC_ERR_NULL_PTR;

    if (0 == pParams->m_nOfFrames || 0 == pParams->m_lBufferSize)
        return UMC_ERR_INIT;

    Close();

    // init mutex
    if (0 == vm_mutex_is_valid(&m_synchro))
        if (VM_OK != vm_mutex_init(&m_synchro))
            return UMC_ERR_INIT;

    // allocate buffer (one more)
    m_lBufferSize = (Ipp32s)pParams->m_lBufferSize;

    if (pParams->m_pMemoryAllocator)
    { // use the external memory allocator
        m_pMemoryAllocator = pParams->m_pMemoryAllocator;
    }
    else
    { // allocate default memory allocator
        m_pAllocated = new DefaultMemoryAllocator();
        if (NULL == m_pAllocated)
            return UMC_ERR_ALLOC;

        m_pMemoryAllocator = m_pAllocated;
    }

    Status umcRes = m_pMemoryAllocator->Alloc(&m_midAllocatedBuffer, m_lBufferSize + 4, UMC_ALLOC_PERSISTENT, 16);
    if (UMC_OK != umcRes)
        return UMC_ERR_ALLOC;

    m_pBuf = (Ipp8u *)m_pMemoryAllocator->Lock(m_midAllocatedBuffer);
    if (NULL == m_pBuf)
        return UMC_ERR_ALLOC;

    m_iCurrentLevel = 0;

    m_pInfo = new Mpeg2TrackInfo;
    if (NULL == m_pInfo)
        return UMC_ERR_ALLOC;

    if (pParams->m_pInfo)
    {
        umcRes = m_pInfo->CopyFrom(pParams->m_pInfo);
    }
    else
    {
        umcRes = m_pInfo->Alloc();
    }
    if (UMC_OK != umcRes)
        return umcRes;

    m_dRate = 1.0;
    return UMC_OK;
}

Status FrameConstructor::Close()
{
    Reset();

    // delete buffer
    if (m_pBuf && m_pMemoryAllocator)
    {
        m_pMemoryAllocator->Unlock(m_midAllocatedBuffer);
        m_pMemoryAllocator->Free(m_midAllocatedBuffer);
        m_pBuf = NULL;
    }

    // delete allocator if was allocated internally
    if (m_pAllocated)
    {
        delete m_pAllocated;
        m_pAllocated = NULL;
    }

    if (m_pInfo)
    {
        m_pInfo->ReleaseAll();
        delete m_pInfo;
        m_pInfo = NULL;
    }

    m_midAllocatedBuffer = MID_INVALID;
    m_pMemoryAllocator = NULL;
    m_lBufferSize = 0;
    m_iCurrentLevel = 0;
    m_uiCommitedFrames = 0;
    m_uiTotalFrames = 0;

    m_bInfoFilled = false;
    m_bIsOutputBufferLocked = false;
    return UMC_OK;
}

Status FrameConstructor::Reset()
{
    AutomaticMutex guard(m_synchro);

    while (UMC_OK == m_OutputQueue.Remove());

    m_bEndOfStream = false;
    m_bIsOutputBufferLocked = false;

    m_lLastBytePos = 0;
    m_lFirstBytePos = 0;
    m_lCurPos = 0;
    m_lCurPicStart = 0;
    m_iCurrentLevel = 0;
    m_uiCommitedFrames = 0;
    m_uiTotalFrames = 0;

    m_CurFrame.Reset();
    m_LastFrame.SetBufferPointer(NULL, 0);
    m_LastFrame.SetAbsPos(0);
    m_LastFrame.SetTime(-1.0, -1.0);

    return UMC_OK;
}

Status FrameConstructor::SoftReset()
{
    AutomaticMutex guard(m_synchro);

    m_bEndOfStream = false;

    if (m_uiTotalFrames > 0)
    {
        m_lCurPicStart = m_lCurPos = m_lLastBytePos = m_OutputQueue.LastBO()->iBufOffset + m_OutputQueue.LastBO()->uiSize;
        m_CurFrame.iBufOffset = m_lLastBytePos;
        m_CurFrame.dPTS = -1.0;
        m_CurFrame.dDTS = -1.0;
    }
    else
    {
        m_lCurPicStart = m_lCurPos = m_lLastBytePos = m_CurFrame.iBufOffset = m_lFirstBytePos = 0;
        m_CurFrame.Reset();
    }

    m_PrevSample.uiSize = 0;
    m_LastSample.uiSize = 0;
    return UMC_OK;
}

void FrameConstructor::SetRate(Ipp64f dRate)
{
    m_dRate = dRate;
}

Status FrameConstructor::LockInputBuffer(MediaData *in)
{
    AutomaticMutex guard(m_synchro);
    Ipp32s lChunkSize;

    // check error(s)
    if (NULL == in)
        return UMC_ERR_NULL_PTR;

    lChunkSize = (Ipp32s)in->GetDataSize();

    if ((m_lFirstBytePos > m_lLastBytePos) && (m_lLastBytePos + lChunkSize + 4 >= m_lFirstBytePos))
        return UMC_ERR_NOT_ENOUGH_BUFFER; // at least 4 bytes gap between last and first bytes

    if ((m_lFirstBytePos <= m_lLastBytePos) && (m_lLastBytePos + lChunkSize > m_lBufferSize))
    {
        if (m_lLastBytePos + lChunkSize - m_CurFrame.iBufOffset >= m_lFirstBytePos)
            return UMC_ERR_NOT_ENOUGH_BUFFER;

        ippsCopy_8u(m_pBuf + m_CurFrame.iBufOffset, m_pBuf, m_lLastBytePos - m_CurFrame.iBufOffset);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -