使用 avcodec_decode_audio4 解码 FLAC 文件效果不佳
decode FLAC file with avcodec_decode_audio4 not work well
我用FFmpeg
解码我的flac
文件并将其写入pcm
文件,然后用GoldenWave用pcm signed 16bit, little endian, mono
播放它,总播放时间是行。
我怀疑我将 2 通道文件写在一个地方,但我不知道如何获取每个信号通道并将其写入 pcm
文件。
有什么帮助吗?谢谢。
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt;
do {
ret = decode_packet(&got_frame, 0);
if (ret < 0)
break;
pkt.data += ret;
pkt.size -= ret;
} while (pkt.size > 0);
av_free_packet(&orig_pkt);
}
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
LOG("flush cached frames");
} while (got_frame);
static int decode_packet(int *got_frame, int cached)
{
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == audio_stream_idx) {
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
LOG("Error decoding audio frame (%s)\n", av_err2str(ret));
return ret;
}
decoded = FFMIN(ret, pkt.size);
if (*got_frame) {
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(audio_dec_ctx->sample_fmt);
//decode packet nb_samples:4608, xx:2, unpadded_linesize: 9216
LOG("decode packet nb_samples:%d, xx:%d, unpadded_linesize: %d",
frame->nb_samples, av_get_bytes_per_sample(audio_dec_ctx->sample_fmt), unpadded_linesize);
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
//int nb_sample = frame->nb_samples;
//fwrite(frame->extended_data[0], 1, nb_sample, audio_dst_file);
//fwrite(frame->extended_data[0] + nb_sample, 1, nb_sample, audio_dst_file);
}
}
if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
av_frame_unref(frame);
return decoded;
}
你没有描述你遇到的问题,但从你写的内容来看,我看到了两个问题:
- 您没有检查帧的原始音频格式,请参阅 frame->format (or audio_dec_ctx->sample_fmt). You're writing it as if it were AV_SAMPLE_FMT_S16,但您没有检查它是
- 您的 unpadded_linesize 未乘以通道数(参见例如 frame->channels)
我用FFmpeg
解码我的flac
文件并将其写入pcm
文件,然后用GoldenWave用pcm signed 16bit, little endian, mono
播放它,总播放时间是行。
我怀疑我将 2 通道文件写在一个地方,但我不知道如何获取每个信号通道并将其写入 pcm
文件。
有什么帮助吗?谢谢。
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt;
do {
ret = decode_packet(&got_frame, 0);
if (ret < 0)
break;
pkt.data += ret;
pkt.size -= ret;
} while (pkt.size > 0);
av_free_packet(&orig_pkt);
}
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
LOG("flush cached frames");
} while (got_frame);
static int decode_packet(int *got_frame, int cached)
{
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == audio_stream_idx) {
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
LOG("Error decoding audio frame (%s)\n", av_err2str(ret));
return ret;
}
decoded = FFMIN(ret, pkt.size);
if (*got_frame) {
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(audio_dec_ctx->sample_fmt);
//decode packet nb_samples:4608, xx:2, unpadded_linesize: 9216
LOG("decode packet nb_samples:%d, xx:%d, unpadded_linesize: %d",
frame->nb_samples, av_get_bytes_per_sample(audio_dec_ctx->sample_fmt), unpadded_linesize);
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
//int nb_sample = frame->nb_samples;
//fwrite(frame->extended_data[0], 1, nb_sample, audio_dst_file);
//fwrite(frame->extended_data[0] + nb_sample, 1, nb_sample, audio_dst_file);
}
}
if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
av_frame_unref(frame);
return decoded;
}
你没有描述你遇到的问题,但从你写的内容来看,我看到了两个问题:
- 您没有检查帧的原始音频格式,请参阅 frame->format (or audio_dec_ctx->sample_fmt). You're writing it as if it were AV_SAMPLE_FMT_S16,但您没有检查它是
- 您的 unpadded_linesize 未乘以通道数(参见例如 frame->channels)