解码循环逻辑从matroska (mkv, webm)到音频(c++通过libvorbis)

Decoding loop logic from matroska (mkv, webm) to audio (C++ via libvorbis)

本文关键字:音频 c++ libvorbis 通过 webm mkv 循环 解码 matroska      更新时间:2023-10-16

(我英语不流利,但我会尽力做到最好)

我尝试编码(c++)一个简单的mkv播放器。我对这门学科很陌生,所以我一点一点地发现我所需要的。一开始,我用VP8编解码器编视频,用Vorbis编音频。视频方面目前看来还可以,但是音频方面有问题。

我无法找出循环逻辑来解码我从mkvparserlibvorbis得到的音频帧。我查阅了这个样本和这个简短的解释,但无法使它在我的情况下工作。我没有找到其他简单的例子。

这是我的一段代码:

const mkvparser::Block* const pBlock = m_pMkvContext->pBlockEntry->GetBlock();
const mkvparser::Track* const pTrack = m_pMkvContext->pTracks->GetTrackByNumber( (unsigned long)pBlock->GetTrackNumber() );
if ( pTrack != NULL )
{
    const long long trackType  = pTrack->GetType();
    const int       frameCount = pBlock->GetFrameCount();
    if ( frameCount > 0 )
    {
        const mkvparser::Block::Frame& oFrame = pBlock->GetFrame( 0 );
        unsigned char* pData = (unsigned char*)malloc( (size_t)oFrame.len );
        oFrame.Read( &m_pMkvContext->oReader, pData );
        if ( trackType == mkvparser::Track::kVideo )
        {
            // i'm ok here
        }
        else if ( trackType == mkvparser::Track::kAudio )
        {
            // what to do here with my audio frame data ?
        }
        free( pData );
    }
}

也许我获取帧的方式适合视频而不适合音频…

你们知道一些好的资源来分享吗?或者一些建议?

感谢您的帮助!

[EDIT]:我忘记添加我的一个尝试:

bool MoviePlayer::DecodeAudioData( unsigned char* pData, uint32 iSize )
{
    int ret;
    char* pBuffer = NULL;
    pBuffer = ogg_sync_buffer( &m_pOVContext->oOggSyncState, iSize );
    memcpy( pBuffer, pData, iSize );
    ogg_sync_wrote( &m_pOVContext->oOggSyncState, iSize );
    ret = ogg_sync_pageout( &m_pOVContext->oOggSyncState, &m_pOVContext->oOggPage );
    ret = ogg_stream_init( &m_pOVContext->oOggStreamState, ogg_page_serialno(&m_pOVContext->oOggPage) );
    ret = ogg_stream_pagein( &m_pOVContext->oOggStreamState, &m_pOVContext->oOggPage );
    int iPacketsCount = ogg_page_packets( &m_pOVContext->oOggPage );
    for ( int i = 0; i < iPacketsCount; ++i )
    {
        ret = ogg_stream_packetout(&m_pOVContext->oOggStreamState, &m_pOVContext->oOggPacket);
        // do something with the packet...
    }
    return true;
}

ogg_sync_pageout处崩溃,因为我的ogg_page没有正确初始化。但是,不是来自一个适当的。ogg文件在我发现的例子中,我不知道如何正确地初始化vorbis结构。

https://matroska.org/technical/specs/codecid/index.html
在A_VORBIS部分私有数据按顺序包含前三个Vorbis数据包....

编解码器private在这里
https://matroska.org/technical/specs/index.html
"CodecPrivate 3 [63][A2]"