我正在使用 FFmpeg 并尝试使用内置的 FFmpeg“opus”编解码器将原始 PCM 声音编码和解码为 Opus。我的输入样本是 AV_SAMPLE_FMT_S16 格式的原始 PCM 8000 Hz 16 位单声道。由于 Opus 只需要采样格式 AV_SAMPLE_FMT_FLTP 和采样率 48000 Hz,所以我在编码之前重新采样我的样本。
我有两个ResamplerAudio类的实例,它们执行重采样音频样本的工作,并且有一个成员SwrContext,我使用第一个实例ResamplerAudio在编码之前重采样原始 PCM 输入音频,第二个实例用于重采样解码音频以获得它的格式和采样率与输入原始音频的源值相同。
ResamplerAudio 类有一个函数来初始化它的 SwrContext 成员,如下所示:
void ResamplerAudio::init(AVCodecContext *codecContext, int inSampleRate, int outSampleRate, AVSampleFormat inSampleFmt, AVSampleFormat outSampleFmt)
{
swrContext = swr_alloc();
if (!swrContext)
{
LOGE(TAG, "[init] Couldn't allocate swr context");
return;
}
av_opt_set_int(swrContext, "in_channel_layout", (int64_t) codecContext->channel_layout, 0);
av_opt_set_int(swrContext, "out_channel_layout", (int64_t) codecContext->channel_layout, 0);
av_opt_set_int(swrContext, "in_channel_count", codecContext->channels, 0);
av_opt_set_int(swrContext, "out_channel_count", codecContext->channels, 0);
av_opt_set_int(swrContext, "in_sample_rate", inSampleRate, …Run Code Online (Sandbox Code Playgroud) 我正在使用 Android MediaCodec 并将其用于来自相机的实时 H264 编码和解码帧。我以同步方式使用 MediaCodec 并将输出渲染到解码器的表面,并且一切正常,除了我的实时延迟很长,需要 1.5-2 秒,我很困惑为什么会这样。我测量了编码和解码过程的总时间,它保持在 50-65 毫秒左右,所以我认为问题不在于它们。我试图更改编码器的配置,但没有帮助,目前它的配置如下:
val formatEncoder = MediaFormat.createVideoFormat("video/avc", 1920, 1080)
formatEncoder.setInteger(MediaFormat.KEY_FRAME_RATE, 30)
formatEncoder.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5)
formatEncoder.setInteger(MediaFormat.KEY_BIT_RATE, 1920 * 1080)
formatEncoder.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)
val encoder = MediaCodec.createEncoderByType("video/avc")
encoder.configure(formatEncoder, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
val inputSurface = encoder.createInputSurface() // I use it to send frames from camera to encoder
encoder.start()
Run Code Online (Sandbox Code Playgroud)
更改解码器的配置也根本没有帮助我,目前我是这样配置的:
val formatDecoder = MediaFormat.createVideoFormat("video/avc", 1920, 1080)
val decoder = MediaCodec.createDecoderByType("video/avc")
decoder.configure(formatDecoder , outputSurface, null, 0) // I use outputSurface to render decoded frames into it
decoder.start()
Run Code Online (Sandbox Code Playgroud)
我使用以下超时来等待可用的编码器/解码器缓冲区,我试图减少它们的值,但它没有帮助我,我将它们保留如下: …