2014-01-24 18 views
1

使用C++,SDL2,SDL2_mix,ffmpeg2。SDL2 + ffmpeg2間歇性點擊而非音頻

Inited SDL2_mix有回調

Mix_HookMusic(MusicPlayer, &g_audioPos); 
從OGG到AVFrame *

解碼後的音頻這段代碼:

while(av_read_frame(m_formatContext, &m_packet) >= 0) 
{ 
    if(m_packet.stream_index == m_audioStream) 
    { 
     int audio_frame_finished; 
     avcodec_decode_audio4(m_audioCodecContext, m_audioFrame, &audio_frame_finished, &m_packet); 
     if(!audio_frame_finished) 
     { 
      continue; 
     } 
    } 
} 

此代碼後我有一些m_audioFrame->data[0]m_audioFrame->linesize[0] == 4096

一旦框架一會兒我的回叫被稱爲:

void MusicPlayer(void *_udata, Uint8 *_stream, int _len) 
    { 
     if(!g_audioData) 
     { 
      return; 
     } 

     AudioData* audio = reinterpret_cast<AudioData*>(g_audioData); 

     if(!audio || audio->Frame->linesize[0] == 0) 
     { 
      return; 
     } 

     SDL_memcpy((Uint8*)audio->Data + audio->Pos, (Uint8*)audio->Frame->data[0], audio->Frame->linesize[0]); 

     audio->Pos+= audio->Frame->linesize[0]; 
     int rest = g_chunkSize - audio->Pos;//frame->linesize[0]; 


     if(rest <= 0) 
     { 
      SDL_memcpy(_stream, audio->Data, _len); 
      audio->Pos = 0; 
      *(int*)_udata += _len; 
     } 
    } 

_len == 8192,所以我必須推2幀填充流,但我得到 - 點擊我的揚聲器。我究竟做錯了什麼?

PS:試圖重新打開與Mix_OpenAudio(m_audioCodecContext->sample_rate, AUDIO_S16SYS, m_audioCodecContext->channels, 4096);混合。有趣的是m_audioCodecContext->channels == 2,當我的回調被稱爲_len = 16384。不知道該怎麼做。請幫忙!!!

+1

什麼是ffmpeg2? – rogerdpack

+0

最新版本。花了將近一個小時才發現:dranger教程不能很好地適用於最新的ffmpeg庫,因爲一些defs和方法已經被廢棄了,現在可以用avcodec_decode_audio4方法取代大量的代碼...如果我理解正確的話。要點是 - 我做了一些搜索,以找出如何使東西幾乎工作。這是我第一次使用音頻( – FertoVordalastr

回答

0

您沒有顯示如何執行ffmpeg初始化;我猜測你忘了指定要求的採樣格式:

aCodecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16; 

看看我的卡拉OK歌詞編輯器的源代碼,使用基於最新的ffmpeg的SDL/ffmpeg的音頻播放器(因此decode_audio4) :https://sourceforge.net/p/karlyriceditor/code/HEAD/tree/src/audioplayerprivate.cpp

+0

感謝您的代碼。重寫回調,聽起來好一點,但仍然不工作。請看看這個https://gist.github.com/anonymous/8615126 – FertoVordalastr

+0

那麼,我建議將你的代碼改成可以工作的東西(比如我的或者任何其他基於SDL的播放器),然後開始實現你自己的改變。你寫代碼的方式可能會導致聲音緩衝區下溢,因此點擊。 –

+0

謝謝。只需要弄清楚「aCodecCtx-> request_sample_fmt」效果不好,它將在「aCodecCtx-> sample_fmt」中進行解碼。首先,我剛剛重新打開了浮點採樣格式的SDL_mixer,但它不起作用在IOS上,finaly - 我使用「swr_convert」來轉換我的聲音數據。剩下的一件事是 - 在我抓取足夠的聲音數據之前 - 我解碼prety大量的視頻幀,所以我的聲音延遲。 – FertoVordalastr