Reputation: 597
I am very new with FFMpeg and I am currently trying to convert audio data from PCM AV_SAMPLE_FMT_S16 format to Mp3 AV_SAMPLE_FMT_FLTP format.
For this I am using the AudioResampleContext from FFMpeg
av_opt_set_int( audioResampleCtx, "in_sample_fmt", m_aplayer->aCodecCtx->sample_fmt, 0);
av_opt_set_int( audioResampleCtx, "in_sample_rate", m_aplayer->aCodecCtx->sample_rate, 0);
av_opt_set_int( audioResampleCtx, "in_channels", m_aplayer->aCodecCtx->channels,0);
av_opt_set_int( audioResampleCtx, "out_channel_layout", audioCodecCtx->channel_layout, 0);
av_opt_set_int( audioResampleCtx, "out_sample_fmt", audioCodecCtx->sample_fmt, 0);
av_opt_set_int( audioResampleCtx, "out_sample_rate", audioCodecCtx->sample_rate, 0);
av_opt_set_int( audioResampleCtx, "out_channels", audioCodecCtx->channels, 0);
The conversion works well since I can listen to my mp3 file but the problems is that my original file is 60 seconds long and the output mp3 file is just 34 seconds. I can hear that it is very accelerated just like if something speeded up the sound. When looking for information with FFMpeg I see that the bitrate just went from 128kbps to 64 kbps.
EDIT: To complete with more information, I want to compress some raw audio data with mp3 codec and have a output.mp3 output format. The raw audio data sample format is AV_SAMPLE_FMT_S16 and the supported sample format for mp3 codec is FLTP (or S16P). Therefore I am doing a sample format conversion from AV_SAMPLE_FMT_S16 to AV_SAMPLE_FMT_FLTP but it is missing half of the data.
Could anyone help me with this ? I know I'm missing something very simple but I just can't figure what.
EDIT:2 Here is the code that does the resampling (coming fromhttps://github.com/martin-steghoefer/debian-karlyriceditor/blob/master/src/ffmpegvideoencoder.cpp) . The audio source isn't an AVFrame but just an array of bytes :
// Resample the input into the audioSampleBuffer until we proceed the whole decoded data
if ( (err = avresample_convert( audioResampleCtx,
NULL,
0,
0,
audioFrame->data,
0,
audioFrame->nb_samples )) < 0 )
{
qWarning( "Error resampling decoded audio: %d", err );
return -1;
}
if( avresample_available( audioResampleCtx ) >= audioFrame->nb_samples )
{
// Read a frame audio data from the resample fifo
if ( avresample_read( audioResampleCtx, audioFrame->data, audioFrame->nb_samples ) != audioFrame->nb_samples )
{
qWarning( "Error reading resampled audio: %d", err );
return -1;
}
//Init packet, do the encoding and write data to file
Thank you for your help !
Upvotes: 2
Views: 4515
Reputation: 523
1) If the audio is played faster, than the sampling rate might be incorrect. Check if the input sample rate for the resampler is the same as in the decoder. AND the output sample rate is the same you use in the encoder.
2) Planar vs non-planar is just a way of saving samples in buffer (check: What is the difference between AV_SAMPLE_FMT_S16P and AV_SAMPLE_FMT_S16?). You shouldn't be missing a plane.
3) As the output is shorter: Remind to flush decoder, resampler, encoder. All of them buffer data. When all data is fed to your processor chain (d-r-e) you need to flush each component and handle the flushed data in the next stage (flush decoder -> resample -> encode; flush resampler -> encode; flush encoder).
Did you find a way to solve your issue by now? I'm struggling with a similar issue. When converting from S16 -> FLTP I get an ffmpeg error: "processor: psymodel.c:576: calc_energy: Assertion `el >= 0' failed."
Upvotes: 0