【问题标题】:SDL2 + ffmpeg2 intermittent clicks instead of audioSDL2 + ffmpeg2 间歇性点击而不是音频
【发布时间】:2014-02-16 00:13:17
【问题描述】:

使用 c++、SDL2、SDL2_mix、ffmpeg2。

使用回调初始化 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-&gt;sample_rate, AUDIO_S16SYS, m_audioCodecContext-&gt;channels, 4096); 重新打开 MIX。有趣的是m_audioCodecContext-&gt;channels == 2,当我的回调被称为_len = 16384。不知道该怎么做。请帮忙!!!

【问题讨论】:

  • 最新版本。花了将近一个小时才弄清楚:danger教程不适用于最新的ffmpeg lib,因为一些defs和方法已被弃用,而且 - 现在可以用avcodec_decode_audio4方法替换相当大的代码块......如果我理解正确的话。重点是-我做了一些搜索以了解如何使事情几乎正常工作。这是我第一次使用音频(

标签: c++ audio ffmpeg sdl


【解决方案1】:

您没有展示如何执行 ffmpeg 初始化;我推测您忘记指定请求的示例格式:

aCodecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16;

看看我的卡拉 OK 歌词编辑器的源代码,它使用基于最新 ffmpeg(以及因此 decode_audio4)的 SDL/ffmpeg 音频播放器:https://sourceforge.net/p/karlyriceditor/code/HEAD/tree/src/audioplayerprivate.cpp

【讨论】:

  • 感谢您的代码。重写回调,听起来好一点,但仍然无法正常工作。请看看这个gist.github.com/anonymous/8615126
  • 好吧,我建议将您的代码更改为可行的代码(例如我的或任何其他基于 SDL 的播放器),然后开始实施您自己的更改。您的代码编写方式可能会导致声音缓冲区下溢,因此会点击。
  • 谢谢。只需弄清楚“aCodecCtx->request_sample_fmt”效果不佳,无论如何它都会在“aCodecCtx->sample_fmt”中解码。起初我只是用浮点样本格式重新打开了 SDL_mixer,但它在 IOS 上不起作用,所以最后 - 我使用“swr_convert”来转换我的声音数据。剩下的一件事是 - 在我获取足够的声音数据之前 - 我解码了相当多的视频帧,所以我的声音延迟了。
猜你喜欢
  • 1970-01-01
  • 2016-01-16
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多