2013-08-24 5 views
0

xaudio2를 사용하여 libav로 오디오를 재생하려고합니다. 내가 사용하고있는 xaudio2 코드는 avcodec_decode_audio2를 사용하는 이전 ffmpeg에서 작동하지만 avcodec_decode_audio4에 대해서는 더 이상 사용되지 않습니다. 나는 다양한 libav 예제를 따라 해봤지만 오디오를 재생할 수없는 것처럼 보입니다. 동영상이 잘 재생됩니다 (또는 아직 동기화 코드를 코딩하지 않았으므로 오히려 바로 지금 바로 재생됩니다).Libav 및 xaudio2 - 오디오가 재생되지 않음

첫째 오디오 init이됩니다, 오류, 비디오가 init을하지 도착, 다음 패킷 : add_sound_to_queue에서 다음

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); 
    } 
} 

:

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로 뭔가를 놓쳤을 수 있습니까? 이 코드 snappet이 충분하지 않으면

, 나는 전체 코드를 게시 할 수 있습니다,이 내가 문제가 :(난 당신이 어디 decoded_frame 접근이 표시되지 않습니다

답변

1

있을 거라고 생각 코드에서 바로 장소입니다 디코딩 후. 어떻게 당신이 밖으로 그렇지 않으면 데이터를 얻을 것으로 예상합니까?

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

이것은 또한 data_size이 패킷 크기에서 파생 주어진 매우 비린내가 보인다. 패킷 크기가 압축 된 데이터의 크기, 그것은이 디코딩 된 PCM 프레임의 크기와 거의 관련이 없습니다.

디코딩 된 데이터는 데이터 플 '폼에 대한 포인터 배열 인 decoded_frame->extended_data에 있습니다. 자세한 내용은 here을 참조하십시오. 디코딩 된 데이터의 크기는 decoded_frame->nb_samples에 의해 결정됩니다. 최근의 Libav 버전에서는 많은 디코더가 평면 오디오를 반환하므로 서로 다른 채널이 다른 데이터 버퍼에 저장됩니다. 많은 유스 케이스의 경우, 인터리브 형식으로 변환해야합니다. 여기에는 모든 채널에 버퍼가 하나만 있습니다. 이를 위해서는 libavresample을 사용하십시오.

+0

빠른 답장을 보내 주셔서 감사합니다. 지난 밤에 decoded_frame에 액세스하지 못했음을 알았고 코드를 약간 변경했습니다. 비디오가 동기화되어 있기 때문에 오디오에 액세스 할 수 있다고 생각합니다 (재생 속도는 다른 미디어 플레이어와 동일합니다). Line 34 http://pastebin.com/Bv1fBA5M에서 AudioBytes는 xmemcpy의 src 버퍼 였지만 이제는 decoded_frame-> data [0]이어야합니다. AudioBytes는 (BYTE *)이며 data [0]은 uint8_t *입니다. 나는 (const void *) decoded_frame-> data [0] 등을 시도했지만 ptr 오류 xmemset을 얻습니다. memcpy와 memset을 사용해 보았습니다. 운이 없었습니다. – siz

관련 문제