簡體   English   中英

Libav和XAudio2-音頻無法播放

[英]Libav and xaudio2 - audio not playing

我正在嘗試使用xaudio2在libav上播放音頻。 我正在使用的xaudio2代碼可與使用avcodec_decode_audio2的較舊ffmpeg一起使用,但已不推薦使用avcodec_decode_audio4。 我嘗試了以下各種libav示例,但似乎無法播放音頻。 視頻可以正常播放(或者說,它現在可以快速播放,因為我尚未編碼任何同步代碼)。

首先音頻被初始化,沒有錯誤,視頻被初始化,然后是數據包:

while (1) {
    //is this packet from the video or audio stream?
    if (packet.stream_index == player.v_id) {
        add_video_to_queue(&packet);
    } else if (packet.stream_index == player.a_id) { 
        add_sound_to_queue(&packet);
    } else {
        av_free_packet(&packet);
    }
}

然后在add_sound_to_queue中:

int add_sound_to_queue(AVPacket * packet) {
AVFrame *decoded_frame = NULL;
int done = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int got_frame = 0;

if (!decoded_frame) {
    if (!(decoded_frame = avcodec_alloc_frame())) {
        printf("[ADD_SOUND_TO_QUEUE] Out of memory\n");
        return -1;
    }
} else {
    avcodec_get_frame_defaults(decoded_frame);
}

if (avcodec_decode_audio4(player.av_acodecctx, decoded_frame, &got_frame, packet) < 0)  {
    printf("[ADD_SOUND_TO_QUEUE] Error in decoding audio\n");
    av_free_packet(packet);
    //continue;
    return -1;
}
if (got_frame) {
    int data_size;
    if (packet->size > done) {
        data_size = done;
    } else {
        data_size = packet->size;
    }
    BYTE * snd = (BYTE *)malloc( data_size * sizeof(BYTE));

    XMemCpy(snd,
        AudioBytes, 
        data_size * sizeof(BYTE)
    );

    XMemSet(&g_SoundBuffer,0,sizeof(XAUDIO2_BUFFER));

    g_SoundBuffer.AudioBytes = data_size;
    g_SoundBuffer.pAudioData = snd;
    g_SoundBuffer.pContext = (VOID*)snd;

    XAUDIO2_VOICE_STATE state;
    while( g_pSourceVoice->GetState( &state ), state.BuffersQueued > 60 ) {
        WaitForSingleObject( XAudio2_Notifier.hBufferEndEvent, INFINITE );
    }

    g_pSourceVoice->SubmitSourceBuffer( &g_SoundBuffer );
}
return 0;
}

我似乎無法弄清楚問題,我在init中添加了錯誤消息,打開了視頻,對編解碼器進行了處理。如前所述,xaudio2代碼與較舊的ffmpeg兼容,所以也許我錯過了avcodec_decode_audio4的東西嗎?

如果此代碼片段不夠用,我可以發布整個代碼,這些只是代碼中的位置,我認為問題可能是:(

我看不到您在解碼后任何地方都訪問了decoded_frame 您如何期望以其他方式獲取數據?

BYTE * snd = (BYTE *)malloc( data_size * sizeof(BYTE));

鑒於data_size是從數據包大小派生的,這看起來也很data_size 分組大小是壓縮數據的大小,與解碼的PCM幀的大小幾乎沒有關系。

解碼后的數據位於decoded_frame->extended_data ,后者是指向數據平面的指針的數組,有關詳細信息,請參見此處 解碼后的數據的大小由decoded_frame->nb_samples確定。 注意,在最新的Libav版本中,許多解碼器返回平面音頻,因此不同的通道位於不同的數據緩沖區中。 對於許多用例,您需要將其轉換為交錯格式,其中所有通道只有一個緩沖區。 為此使用libavresample

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM