gpt4 book ai didi

audio - 如何使用 FFmpeg 将 ADPCM 转换为 PCM?

转载 作者:行者123 更新时间:2023-12-02 22:28:18 53 4
gpt4 key购买 nike

我有一个视频源,它使用 ADPCM 编解码器向我发送音频。但是,android 只支持 PCM 格式。如何将 ADPCM 音频输入转换为 PCM 音频输入?

这个问题的答案可能类似于 this question 的答案。 .

我已经使用以下代码成功解码了帧:

int len = avcodec_decode_audio4(pAudioCodecCtx, pAudioFrame, &frameFinished, &packet);

这里的秘诀是使用反向 编码 功能?

这是我到目前为止的音频解码功能:
<!-- language: c -->
if(packet_queue_get(env, javaThread, pAudioPacketQueue, &packet, 1) < 0) {
LOGE("audio - after get packet failed");
return;
}
LOGD("Dequeued audio packet");

// calculate frame size
int frameSize;
if (pPcmAudioCodecCtx->frame_size) {
frameSize = pPcmAudioCodecCtx->frame_size;
} else {
/* if frame_size is not set, the number of samples must be
* calculated from the buffer size */
int64_t nb_samples = (int64_t)AUDIO_PCM_OUTBUFF_SIZE * 8 /
(av_get_bits_per_sample(pPcmAudioCodecCtx->codec_id) *
pPcmAudioCodecCtx->channels);
frameSize = nb_samples;
}

int pcmBytesPerSample = av_get_bytes_per_sample(pPcmAudioCodecCtx->sample_fmt);
int pcmFrameBytes = frameSize * pcmBytesPerSample * pPcmAudioCodecCtx->channels;

uint8_t *pDataStart = packet.data;
while(packet.size > 0) {
int len = avcodec_decode_audio4(pAudioCodecCtx, pAudioFrame, &frameFinished, &packet);
LOGD("Decoded ADPCM frame");

if (len < 0) {
LOGE("Error while decoding audio");
return;
}

if (frameFinished) {
// store frame data in FIFO buffer
uint8_t *inputBuffer = pAudioFrame->data[0];
int inputBufferSize = pAudioFrame->linesize[0];
av_fifo_generic_write(fifoBuffer, inputBuffer, inputBufferSize, NULL);
LOGD("Added ADPCM frame to FIFO buffer");

// check if fifo buffer has enough data for a PCM frame
while (av_fifo_size(fifoBuffer) >= pcmFrameBytes) {
LOGI("PCM frame data in FIFO buffer");

// read frame's worth of data from FIFO buffer
av_fifo_generic_read(fifoBuffer, pAudioPcmOutBuffer, pcmFrameBytes, NULL);
LOGD("Read data from FIFO buffer into pcm frame");


avcodec_get_frame_defaults(pPcmAudioFrame);
LOGD("Got frame defaults");

pPcmAudioFrame->nb_samples = pcmFrameBytes / (pPcmAudioCodecCtx->channels *
pcmBytesPerSample);

avcodec_fill_audio_frame(pPcmAudioFrame, pPcmAudioCodecCtx->channels,
pPcmAudioCodecCtx->sample_fmt,
pAudioPcmOutBuffer, pcmFrameBytes, 1);
LOGD("Filled frame audio with data");

// fill audio play buffer
int dataSize = pPcmAudioFrame->linesize[0];
LOGD("Data to output: %d", dataSize);
jbyteArray audioPlayBuffer = (jbyteArray) env->GetObjectField(ffmpegCtx, env->GetFieldID(cls, "audioPlayBuffer", "[B"));
jbyte *bytes = env->GetByteArrayElements(audioPlayBuffer, NULL);
memcpy(bytes, pPcmAudioFrame->data[0], dataSize);
env->ReleaseByteArrayElements(audioPlayBuffer, bytes, 0);
LOGD("Copied data into Java array");

env->CallVoidMethod(player, env->GetMethodID(playerCls, "updateAudio", "(I)V"), dataSize);
}

最佳答案

原来 audio_decode_函数返回 16 位 PCM 格式,我只是不知道如何正确访问它。

以下是根据 avcodec_decode_audio4 播放音频的数据包循环内的更改代码.

int len = avcodec_decode_audio4(pAudioCodecCtx, pAudioFrame, &frameFinished, &packet);

if (len < 0) {
LOGE("Error while decoding audio");
return;
}

if (frameFinished) {
int planeSize;
uint8_t *pcmBuffer = pAudioFrame->extended_data[0];
int dataSize = av_samples_get_buffer_size(&planeSize, pAudioCodecCtx->channels,
pAudioFrame->nb_samples,
pAudioCodecCtx->sample_fmt, 1);
// fill audio play buffer
jbyteArray audioPlayBuffer = (jbyteArray) env->GetObjectField(ffmpegCtx, env->GetFieldID(cls, "audioPlayBuffer", "[B"));
jbyte *bytes = env->GetByteArrayElements(audioPlayBuffer, NULL);
memcpy(bytes, pcmBuffer, dataSize);
env->ReleaseByteArrayElements(audioPlayBuffer, bytes, 0);
env->CallVoidMethod(player, env->GetMethodID(playerCls, "updateAudio", "(I)V"), dataSize);
}

关于audio - 如何使用 FFmpeg 将 ADPCM 转换为 PCM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14492678/

53 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com