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

📄 umc_h264_au_stream.cpp

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

#include "umc_h264_au_stream.h"

#ifndef abs
#define abs(a) (((a) < 0) ? -(a) : (a))
#endif /* abs */

#include <memory>

#define TRAILING_SPAN 8

namespace UMC
{

    H264_AU_Stream::H264_AU_Stream(void)
    {
        m_iActiveUA = 0;
        m_iOutData = 0;
    }

    H264_AU_Stream::~H264_AU_Stream(void){}

    void H264_AU_Stream::Init(Ipp32s p_iSize)
    {
        m_au[0].buffer.reserve(p_iSize + TRAILING_SPAN);
        m_au[1].buffer.reserve(p_iSize + TRAILING_SPAN);
    }

    Status H264_AU_Stream::PutData(MediaData & p_rawAnnexB)
    {
        if(p_rawAnnexB.GetDataSize() < 1){
            return UMC_ERR_NOT_ENOUGH_DATA;
        }

        Status status = UMC_ERR_NOT_ENOUGH_DATA;

        H264NALUOctet octet;
        octet.ReadOctet((Ipp8u *)p_rawAnnexB.GetDataPointer());

#ifdef AU_TRACING
        printf("--nalu type=%d", (Ipp32s)octet.Type);
#endif // AU_TRACING

        switch(octet.Type){
            case H264_NAL_SLICE_NON_IDR:
            case H264_NAL_SLICE_A:
            case H264_NAL_SLICE_B:
            case H264_NAL_SLICE_C:
            case H264_NAL_SLICE_IDR:
                status = OnSlice(p_rawAnnexB);
                break;
            case H264_NAL_SET_SEQ:
                status = OnSequenceSet(p_rawAnnexB);
                break;
            case H264_NAL_SET_PIC:
                status = OnPictureSet(p_rawAnnexB);
                break;
            case H264_NAL_AU_DEL:
                m_lastSlice.is_valid = false;
                status = StartAU();
                AppendAU(p_rawAnnexB);
                break;
            case H264_NAL_END_SEQ:
                m_lastSlice.is_valid = false;
                AppendAU(p_rawAnnexB);
                status = StartAU();
                break;
            case H264_NAL_END_STM:
                m_lastSlice.is_valid = false;
                AppendAU(p_rawAnnexB);
                status = StartAU();
                break;
            default:
                // H264_NAL_FIL_DATA
                // H264_NAL_SLICE_SEI
                // H264_NAL_SET_SEQ_EXT
                // H264_NAL_SLICE_NI_05
                AppendAU(p_rawAnnexB);
                status = UMC_ERR_NOT_ENOUGH_DATA;
                break;
        }

#ifdef AU_TRACING
        printf("\n");
#endif // AU_TRACING
        return status;
    }

    Status H264_AU_Stream::OnSlice(MediaData & p_dataNALU)
    {
        H264SliceHeaderParse slice;

        MediaData localData = p_dataNALU;

        slice.octet.ReadOctet((Ipp8u *)localData.GetDataPointer());
        localData.MoveDataPointer(1);

        H264_SyntaxReader syntaxReader(localData);

        H264SequenceSetParse * pSeqSet = 0;

        if( UMC_OK != Read_slice_header(slice, syntaxReader, pSeqSet)){
            return UMC_ERR_FAILED;
        }

        if (m_lastSlice.is_valid && !IsPictureSame(slice)){
            Status status = StartAU();
            AppendAU(p_dataNALU);
            SetLastAttrs(*pSeqSet, slice);
            m_lastSlice = slice;
            m_lastSlice.is_valid = true;
            return status;
        }

        SetLastAttrs(*pSeqSet, slice);
        m_lastSlice = slice;
        m_lastSlice.is_valid = true;
        AppendAU(p_dataNALU);
        return UMC_ERR_NOT_ENOUGH_DATA;
    }

    Status H264_AU_Stream::OnPictureSet(MediaData & p_dataNALU)
    {
        if( p_dataNALU.GetDataSize() == 0){
            return UMC_ERR_NOT_ENOUGH_DATA;
        }

        H264PictureSetParse pic;

        MediaData localData = p_dataNALU;

        pic.octet.ReadOctet((Ipp8u *)localData.GetDataPointer());
        localData.MoveDataPointer(1);

        Ipp8u * pData = (Ipp8u *)localData.GetDataPointer();
        pic.buffer.insert(pic.buffer.end(), pData, pData + localData.GetDataSize());

        H264_SyntaxReader syntaxReader(localData);

        if( UMC_OK != Read_pic_parameter_set_rbsp(pic, syntaxReader)){
            return UMC_ERR_FAILED;
        }

        m_mapPic[pic.pic_parameter_set_id] = pic;

        Status status = UMC_ERR_NOT_ENOUGH_DATA;
        if (m_lastSlice.is_valid)
        {
            status = StartAU();
        }
        AppendAU(p_dataNALU);
        m_lastSlice.is_valid = false;
        return status;
    }

    Status H264_AU_Stream::OnSequenceSet(MediaData & p_dataNALU)
    {
        if( p_dataNALU.GetDataSize() == 0){
            return UMC_ERR_NOT_ENOUGH_DATA;
        }

        H264SequenceSetParse seq;

        MediaData localData = p_dataNALU;

        H264_SyntaxReader syntaxReader(localData);

        seq.octet.ReadOctet((Ipp8u *)localData.GetDataPointer());
        localData.MoveDataPointer(1);

        Ipp8u * pData = (Ipp8u *)localData.GetDataPointer();
        seq.buffer.insert(seq.buffer.end(), pData, pData + localData.GetDataSize());

        if( UMC_OK != Read_seq_parameter_set_rbsp(seq, syntaxReader)){
            return UMC_ERR_FAILED;
        }

        m_mapSeq[seq.seq_parameter_set_id] = seq;

        Status status = UMC_ERR_NOT_ENOUGH_DATA;
        if (m_lastSlice.is_valid)
        {
            status = StartAU();
        }

        AppendAU(p_dataNALU);
        m_lastSlice.is_valid = false;
        return status;
    }

    void H264_AU_Stream::AppendAU(MediaData & p_dataNALU)
    {
        static const Ipp8s s_stopSeq[] = {0x00, 0x00, 0x00, 0x01};
        Ipp8u * pData = (Ipp8u*)p_dataNALU.GetDataPointer();
        m_au[m_iActiveUA].buffer.insert(m_au[m_iActiveUA].buffer.end(), (Ipp8u*)s_stopSeq, (Ipp8u*)s_stopSeq + sizeof(s_stopSeq));
        m_au[m_iActiveUA].buffer.insert(m_au[m_iActiveUA].buffer.end(), pData, pData + p_dataNALU.GetDataSize());
    }

    Status H264_AU_Stream::StartAU()
    {
        if( m_au[m_iActiveUA].buffer.empty()){
            return UMC_ERR_NOT_ENOUGH_DATA;
        }
        // Swapping buffers
        m_iActiveUA = ( m_iActiveUA + 1) % 2;
        m_au[m_iActiveUA].buffer.clear();
        return UMC_OK;
    }

    void H264_AU_Stream::Swap()
    {
        m_iActiveUA = ( m_iActiveUA + 1) % 2;
    }

    Status H264_AU_Stream::LockOutputData(MediaData & o_dataAU)
    {
        Ipp32s iNum = ( m_iActiveUA + 1) % 2;
        // Ensuring that there is also a span in the end of NALU

        Ipp32s iTrail = (Ipp32s)(m_au[iNum].buffer.capacity() - m_au[iNum].buffer.size());
        if( iTrail < TRAILING_SPAN ){
            m_au[iNum].buffer.reserve(m_au[iNum].buffer.size() + TRAILING_SPAN);
        }

        if (m_au[iNum].buffer.size() == 0)
        {
            o_dataAU.SetBufferPointer(0, 0);
            o_dataAU.SetDataSize(0);
            return UMC_OK;
        }

        o_dataAU.SetBufferPointer(&(m_au[iNum].buffer[0]), m_au[iNum].buffer.size());
        o_dataAU.SetDataSize(m_au[iNum].buffer.size());

        m_iOutData += (Ipp32s)m_au[iNum].buffer.size();
        return UMC_OK;
    }

    Status H264_AU_Stream::UnLockOutputData(MediaData & /*o_dataAU*/)
    {
        return UMC_OK;
    }

#define GO_OR_QUIT_SIMPLE( op ) if( UMC_OK != op ) return UMC_ERR_FAILED;
#define GO_OR_QUIT( op ) if( UMC_OK != p_reader.op ) return UMC_ERR_FAILED;

    Status H264_AU_Stream::Read_seq_parameter_set_rbsp(H264SequenceSetParse & p_SequenceSet, H264_SyntaxReader & p_reader)
    {
        Ipp32u iValue = 0;
        Ipp32s siValue = 0;
        Ipp32u profile_idc = 0;
        GO_OR_QUIT( ReadU(8, profile_idc) );
        GO_OR_QUIT( ReadU(1, iValue) );
        GO_OR_QUIT( ReadU(1, iValue) );
        GO_OR_QUIT( ReadU(1, iValue) );
        GO_OR_QUIT( ReadU(1, iValue) );
        GO_OR_QUIT( ReadU(4, iValue) );
        GO_OR_QUIT( ReadU(8, iValue) );
        GO_OR_QUIT( ReadUE(p_SequenceSet.seq_parameter_set_id) );

⌨️ 快捷键说明

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