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

📄 umc_avi_splitter.cpp

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

    if (AVI_FOURCC_vids == track.m_StreamHeader.fccType)
        ((BitmapInfoHeader *)track.m_pStreamFormat)->SwapBigEndian();
    else if (AVI_FOURCC_auds == track.m_StreamHeader.fccType)
        ((WaveFormatEx *)track.m_pStreamFormat)->SwapBigEndian();

    //  Ascend from 'strf'
    umcRes = m_AviChunkReader.Ascend();
    if (UMC_OK != umcRes)
        return umcRes;

    umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_INDX);
    if (umcRes == UMC_OK)
    {
        // index buffer doesn't include chunk header!
        track.m_uiIndexSize = m_AviChunkReader.GetChunkSize();
        track.m_pIndex = ippsMalloc_8u(track.m_uiIndexSize);
        if (!track.m_pIndex)
            return UMC_ERR_ALLOC;
        m_AviChunkReader.GetData(track.m_pIndex, track.m_uiIndexSize);
        if (UMC_OK != umcRes)
            return umcRes;

        //  Ascend from 'indx'
        umcRes = m_AviChunkReader.Ascend();
    }

    //  Ascend from LIST
    umcRes = m_AviChunkReader.Ascend();
    if (UMC_OK != umcRes)
        return umcRes;

    return UMC_OK;
}

Status AVISplitter::FillAudioStreamInfo(Ipp32u uiTrack, TrackInfo *pInfo)
{
    Status umcRes = UMC_OK;
    AviTrack &rTrack = m_pTrack[uiTrack];

    AudioStreamInfo *pAInfo = (AudioStreamInfo *)pInfo->m_pStreamInfo;
    WaveFormatEx *pWavFmt = (WaveFormatEx *)rTrack.m_pStreamFormat;
    if (!pWavFmt)
        return UMC_ERR_FAILED;

    pAInfo->channels = pWavFmt->nChannels;
    pAInfo->sample_frequency = pWavFmt->nSamplesPerSec;
    pAInfo->bitrate = pWavFmt->nAvgBytesPerSec * 8;
    pAInfo->bitPerSample = pWavFmt->wBitsPerSample ? pWavFmt->wBitsPerSample: 16;

    IndexEntry entry;
    umcRes = m_pTrackIndex[uiTrack].Last(entry);
    pAInfo->duration = UMC_OK == umcRes ? entry.GetTimeStamp() : 0.0;

    pAInfo->stream_type = UNDEF_AUDIO;
    pAInfo->stream_subtype = UNDEF_AUDIO_SUBTYPE;
    if (WAVE_FORMAT_PCM == pWavFmt->wFormatTag)
    {
        pAInfo->stream_type = PCM_AUDIO;
        pInfo->m_Type = TRACK_PCM;
    }
    else if (WAVE_FORMAT_MPEGLAYER3 == pWavFmt->wFormatTag)
    {
        pAInfo->stream_type = (pWavFmt->nSamplesPerSec >= 32000) ? MP1L3_AUDIO : MP2L3_AUDIO;
        pInfo->m_Type = TRACK_MPEGA;
    }
    else if (WAVE_FORMAT_DVM == pWavFmt->wFormatTag)
    {
        pAInfo->stream_type = AC3_AUDIO;
        pInfo->m_Type = TRACK_AC3;
    }
    else if (WAVE_FORMAT_AAC == pWavFmt->wFormatTag)
    {
        pAInfo->stream_type = AAC_AUDIO;
        pInfo->m_Type = TRACK_AAC;
    }
    else if (WAVE_FORMAT_ALAW == pWavFmt->wFormatTag)
    {
        pAInfo->stream_type = ALAW_AUDIO;
        pInfo->m_Type = TRACK_AMR;
    }
    else if (WAVE_FORMAT_MULAW == pWavFmt->wFormatTag)
    {
        pAInfo->stream_type = MULAW_AUDIO;
        pInfo->m_Type = TRACK_AMR;
    }

    pAInfo->channel_mask = 0;
    if (1 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_CENTER;
    else if (2 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT;
    else if (3 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER;
    else if (4 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER | CHANNEL_TOP_CENTER;
    else if (5 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER |
            CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT;
    else if (6 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER |
            CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT | CHANNEL_LOW_FREQUENCY;
    else if (7 == pWavFmt->nChannels)
        pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER | CHANNEL_BACK_LEFT |
            CHANNEL_BACK_RIGHT | CHANNEL_LOW_FREQUENCY | CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER;

    return UMC_OK;
}

Status AVISplitter::FillVideoStreamInfo(Ipp32u uiTrack, TrackInfo *pInfo)
{
    Status umcRes = UMC_OK;
    AviTrack &rTrack = m_pTrack[uiTrack];

    VideoStreamInfo *pVInfo = (VideoStreamInfo *)pInfo->m_pStreamInfo;
    BitmapInfoHeader* pBmpHdr = (BitmapInfoHeader *)rTrack.m_pStreamFormat;
    if (!pBmpHdr)
        return UMC_ERR_FAILED;

    pVInfo->clip_info.width = pBmpHdr->biWidth;
    pVInfo->clip_info.height = pBmpHdr->biHeight;
    pVInfo->bitrate = 8 * m_AviHdr.uiMaxBytesPerSec;
    pVInfo->framerate = (Ipp64f)rTrack.m_StreamHeader.uiRate / rTrack.m_StreamHeader.uiScale;

    IndexEntry entry;
    umcRes = m_pTrackIndex[uiTrack].Last(entry);
    pVInfo->duration = (UMC_OK == umcRes) ? entry.GetTimeStamp() : 0.0;

    pVInfo->stream_type = UNDEF_VIDEO;
    pVInfo->stream_subtype = UNDEF_VIDEO_SUBTYPE;
    Ipp32u fccHandler = rTrack.m_StreamHeader.fccHandler;
    if (AVI_FOURCC_DIVX == fccHandler || AVI_FOURCC_divx == fccHandler ||
        AVI_FOURCC_DX50 == fccHandler || AVI_FOURCC_dx50 == fccHandler ||
        AVI_FOURCC_DIV4 == fccHandler || AVI_FOURCC_div4 == fccHandler ||
        AVI_FOURCC_XVID == fccHandler || AVI_FOURCC_xvid == fccHandler ||
        AVI_FOURCC_MP4V == fccHandler || AVI_FOURCC_mp4v == fccHandler)
    {
        pInfo->m_Type = TRACK_MPEG4V;
        pVInfo->stream_type = MPEG4_VIDEO;
        if (AVI_FOURCC_DX50 == fccHandler || AVI_FOURCC_dx50 == fccHandler)
            pVInfo->stream_subtype = MPEG4_VIDEO_DIVX5;
    }
    else if (AVI_FOURCC_DVHP == fccHandler || AVI_FOURCC_dvhp == fccHandler ||
             AVI_FOURCC_DVHD == fccHandler || AVI_FOURCC_dvhd == fccHandler ||
             AVI_FOURCC_DVH1 == fccHandler || AVI_FOURCC_dvh1 == fccHandler)
    {
        pVInfo->stream_type = DIGITAL_VIDEO_HD;
        pInfo->m_Type = TRACK_DVHD;
    }
    else if (AVI_FOURCC_DV50 == fccHandler || AVI_FOURCC_dv50 == fccHandler)
    {
        pVInfo->stream_type = DIGITAL_VIDEO_50;
        pInfo->m_Type = TRACK_DV50;
    }
    else if (AVI_FOURCC_DVSD == fccHandler || AVI_FOURCC_dvsd == fccHandler ||
             AVI_FOURCC_DSVD == fccHandler || AVI_FOURCC_dsvd == fccHandler ||
             AVI_FOURCC_VIDV == fccHandler || AVI_FOURCC_vidv == fccHandler ||
             AVI_FOURCC_DVSL == fccHandler || AVI_FOURCC_dvsl == fccHandler ||
             AVI_FOURCC_SLDV == fccHandler || AVI_FOURCC_sldv == fccHandler)
    {
        pInfo->m_Type = TRACK_DVSD;
        pVInfo->stream_type = DIGITAL_VIDEO_SD;
    }
    else if (AVI_FOURCC_WMV3 == fccHandler)
    {
        pInfo->m_Type = TRACK_WMV;
        pVInfo->stream_type = WMV_VIDEO;
    }
    else if (AVI_FOURCC_H263 == fccHandler || AVI_FOURCC_h263 == fccHandler ||
             AVI_FOURCC_I263 == fccHandler || AVI_FOURCC_i263 == fccHandler ||
             AVI_FOURCC_M263 == fccHandler || AVI_FOURCC_m263 == fccHandler ||
             AVI_FOURCC_VIVO == fccHandler || AVI_FOURCC_vivo == fccHandler)
    {
        pInfo->m_Type = TRACK_H263;
        pVInfo->stream_type = H263_VIDEO;
    }
    else if (AVI_FOURCC_H261 == fccHandler || AVI_FOURCC_h261 == fccHandler)
    {
        pInfo->m_Type = TRACK_H261;
        pVInfo->stream_type = H261_VIDEO;
    }
    else if (AVI_FOURCC_MJPG == fccHandler || AVI_FOURCC_mjpg == fccHandler ||
             AVI_FOURCC_MJPX == fccHandler || AVI_FOURCC_mjpx == fccHandler ||
             AVI_FOURCC_dmb1 == fccHandler)
    {
        pInfo->m_Type = TRACK_MJPEG;
        pVInfo->stream_type = MJPEG_VIDEO;
    }
    else if (AVI_FOURCC_ILV4 == fccHandler || AVI_FOURCC_ilv4 == fccHandler ||
             AVI_FOURCC_VSSH == fccHandler || AVI_FOURCC_vssh == fccHandler)
    {
        pInfo->m_Type = TRACK_H264;
        pVInfo->stream_type = H264_VIDEO;
    }
    else if (AVI_FOURCC_DIB == fccHandler)
    {
        Ipp32u biCompression = ((BitmapInfoHeader *)rTrack.m_pStreamFormat)->biCompression;
        pVInfo->stream_type = UNCOMPRESSED_VIDEO;
        pVInfo->stream_subtype = (VideoStreamSubType)biCompression;
        pInfo->m_Type = TRACK_YUV;
    }
    else
    {
        // There are many codecs, which can produce uncompressed video.
        // So we compare not a codec handler, but the compression type.
        Ipp32u biCompression = ((BitmapInfoHeader *)rTrack.m_pStreamFormat)->biCompression;
        if (AVI_FOURCC_IYUV == biCompression)
        {
            pInfo->m_Type = TRACK_YUV;
            pVInfo->stream_type = UNCOMPRESSED_VIDEO;
            pVInfo->stream_subtype = (VideoStreamSubType)biCompression;
        }
    }

    return UMC_OK;
}

Status AVISplitter::FillDvStreamInfo(Ipp32u uiTrack, TrackInfo *pInfo)
{
    Status umcRes = UMC_OK;
    AviTrack &rTrack = m_pTrack[uiTrack];

    VideoStreamInfo *pVInfo = (VideoStreamInfo *)pInfo->m_pStreamInfo;

    IndexEntry entry;
    umcRes = m_pTrackIndex[uiTrack].Last(entry);
    pVInfo->duration = (UMC_OK == umcRes) ? entry.GetTimeStamp() : 0.0;
    pVInfo->bitrate = 8 * m_AviHdr.uiMaxBytesPerSec;
    pVInfo->stream_type = UNDEF_VIDEO;
    pVInfo->stream_subtype = UNDEF_VIDEO_SUBTYPE;
    Ipp32u fccHandler = rTrack.m_StreamHeader.fccHandler;
    if (AVI_FOURCC_DVHP == fccHandler || AVI_FOURCC_dvhp == fccHandler ||
        AVI_FOURCC_DVHD == fccHandler || AVI_FOURCC_dvhd == fccHandler ||
        AVI_FOURCC_DVH1 == fccHandler || AVI_FOURCC_dvh1 == fccHandler)
    {
        pVInfo->stream_type = DIGITAL_VIDEO_HD;
        pInfo->m_Type = TRACK_DVHD;
    }
    else if (AVI_FOURCC_DV50 == fccHandler || AVI_FOURCC_dv50 == fccHandler)
    {
        pVInfo->stream_type = DIGITAL_VIDEO_50;
        pInfo->m_Type = TRACK_DV50;
    }
    else if (AVI_FOURCC_DVSD == fccHandler || AVI_FOURCC_dvsd == fccHandler ||
             AVI_FOURCC_DSVD == fccHandler || AVI_FOURCC_dsvd == fccHandler ||
             AVI_FOURCC_VIDV == fccHandler || AVI_FOURCC_vidv == fccHandler ||
             AVI_FOURCC_DVSL == fccHandler || AVI_FOURCC_dvsl == fccHandler ||
             AVI_FOURCC_SLDV == fccHandler || AVI_FOURCC_sldv == fccHandler)
    {
        pInfo->m_Type = TRACK_DVSD;
        pVInfo->stream_type = DIGITAL_VIDEO_SD;
    }
    else
    {
        return UMC_ERR_FAILED;
    }

    Ipp32u uiDVVAuxSrc = ((DvInfo *)rTrack.m_pStreamFormat)->uiDVVAuxSrc;
    Ipp32u uiFieldsNum = (uiDVVAuxSrc >> 21) & 0x1;
    Ipp32u uiSType = (uiDVVAuxSrc >> 16) & 0x1f;
    switch (uiSType)
    {
    case 0: case 1: case 4:
        pVInfo->clip_info.width = 720;
        pVInfo->clip_info.height = (0 == uiFieldsNum) ? 480 : 576;
        pVInfo->framerate = (0 == uiFieldsNum) ? 29.97 : 25.00;
        break;
    case 20:
        pVInfo->clip_info.width = 1920;
        pVInfo->clip_info.height = 1080;
        pVInfo->framerate = (0 == uiFieldsNum) ? 29.97 : 25.00;
        break;
    case 24:
        pVInfo->clip_info.width = 1280;
        pVInfo->clip_info.height = 720;
        pVInfo->framerate = 59.94;
        break;
    default:
        pVInfo->framerate = (Ipp64f)rTrack.m_StreamHeader.uiRate / rTrack.m_StreamHeader.uiScale;
        pVInfo->clip_info.width = rTrack.m_StreamHeader.rcFrame.right - rTrack.m_StreamHeader.rcFrame.left;
        pVInfo->clip_info.height = rTrack.m_StreamHeader.rcFrame.bottom - rTrack.m_StreamHeader.rcFrame.top;
        if (pVInfo->clip_info.width <= 0) pVInfo->clip_info.width = m_AviHdr.uiWidth;
        if (pVInfo->clip_info.height <= 0) pVInfo->clip_info.height = m_AviHdr.uiHeight;
    }

    return UMC_OK;
}

inline
Ipp32u GetTrackId(Ipp32u fourCC)
{
    return 10 * ((fourCC & 0xFF) - '0') + (((fourCC >> 8) & 0xFF) - '0');
}

inline
bool IsAudio(Ipp32u fourCC)
{
    return ((fourCC & 0xFFFF0000) == AVI_FOURCC_WB);
}

inline
bool IsVideo(Ipp32u fourCC)
{
    return (((fourCC & 0xFFFF0000) == AVI_FOURCC_DC) || ((fourCC & 0xFFFF0000) == AVI_FOURCC_DB));
}

inline
bool IsAudioOrVideo(Ipp32u fourCC)
{
    return (IsAudio(fourCC) || IsVideo(fourCC));
}

inline
Ipp64f GetSampleDuration(bool bIsVideoTrack, bool bIsVBRAudio, Ipp64f dFrameDuration, Ipp32u nBlockAlign, Ipp32u nSampleSize)
{
    if (bIsVideoTrack)
    {
        return dFrameDuration;
    }
    else
    {
        if (bIsVBRAudio)
            return dFrameDuration * ((nSampleSize - 1) / nBlockAlign + 1);
        else
            return dFrameDuration * nSampleSize / nBlockAlign;
    }
}

Status AVISplitter::GenerateIndex()
{
    Status umcRes = UMC_OK;
    bool bUseOldIndex = false;
    Ipp32u i;

    for(i = 0; i < m_AviHdr.uiStreams; i++)
    {
        if (AVI_FOURCC_auds == m_pTrack[i].m_StreamHeader.fccType ||
            AVI_FOURCC_vids == m_pTrack[i].m_StreamHeader.fccType ||
            AVI_FOURCC_iavs == m_pTrack[i].m_StreamHeader.fccType ||
            AVI_FOURCC_ivas == m_pTrack[i].m_StreamHeader.fccType)
        {
            if (NULL == m_pTrack[i].m_pIndex || 0 == m_pTrack[i].m_uiIndexSize)
                bUseOldIndex = true;
        }
    }

    if (bUseOldIndex)
    {
        Ipp32u riffType = AVI_FOURCC_AVI_;
        bool bExtension = false;

        while (umcRes == UMC_OK)
        {
            if (bExtension)
                riffType = AVI_FOURCC_AVIX;

            umcRes = m_AviChunkReader.DescendRIFF(riffType);
            if (umcRes != UMC_OK)
                return bExtension ? UMC_OK : umcRes;

            umcRes = m_AviChunkReader.DescendLIST(AVI_FOURCC_MOVI);
            if (umcRes != UMC_OK)
                return umcRes;

            // offset in idx1 can be absolute offset, or position relatively to
            // the first byte of "movi" indentificator.
            Ipp64u nMoviChunkStartAddr = m_AviChunkReader.GetChunkHead() - 4;
            Ipp64u nMoviChunkEndAddr = nMoviChunkStartAddr + m_AviChunkReader.GetChunkSize();
            m_AviChunkReader.Ascend();

            umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_IDX1);
            if (umcRes != UMC_OK)
                return bExtension ? UMC_OK : umcRes;

            Ipp32u nIndexSize = m_AviChunkReader.GetChunkSize();
            Ipp8u *pIndex = ippsMalloc_8u(nIndexSize);
            if (pIndex == NULL)
                return UMC_ERR_ALLOC;

            umcRes = m_AviChunkReader.GetData(pIndex, nIndexSize);
            if (UMC_OK != umcRes)
            {
                ippsFree(pIndex);
                return umcRes;
            }

#ifdef _BIG_ENDIAN_
            ippsSwapBytes_32u_I((Ipp32u *)pIndex, nIndexSize / 4);
#endif

            InitIndexUsingOldAVIIndex(pIndex, nIndexSize, nMoviChunkStartAddr, nMoviChunkEndAddr);
            ippsFree(pIndex);
            // ascend from idx1
            m_AviChunkReader.Ascend();

⌨️ 快捷键说明

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