[Libav-user] Fwd: mp3 file size inconsistency
Jean Porcherot
jeanporcherot at yahoo.fr
Thu Jul 25 21:48:39 CEST 2013
Hi,
I am using ffmpeg 2.0 to read audio files from (Visual) C++ code. I had a
hard time finding how to achieve this but it now works smartly for WAV
files. However, for MP3 files, I am unable to read all samples: when
opening the mp3 file in a mp3 editor (like Audicity), it reports me a
number of samples available. Now, if I read the file from ffmpeg, I cannot
read as many samples as reported.
I could isolate the problem in a very simple sample program (source below).
This code:
- computes the number of samples expected (via frequency and file size
attributes), this is always (tested 3 different files) the same value as
the one reported by Audicity.
- does a while loop to read all samples incrementing a counter. This gives
the actual number of samples "readable".
If given a WAV file as parameter, the two computed values are the same.
If given a MP3 file as parameter, we read less samples than expected
(difference is between 0 and packet.size). As if last packet reading
failed....
If somebody can help, this would be greatly appreciated!
Thanks in advance,
Jean
PS: I posted the question on the
forum<http://ffmpeg.gusari.org/viewtopic.php?f=16&t=1008&p=2373#p2367>but
were recommended to use this list...
extern "C" {
#include "libavformat/avformat.h"
}
#include <iostream>
#include <sstream>
void check_size( char* filename )
{
av_register_all();
AVFormatContext* container = avformat_alloc_context();
int stream_id = 0;
if ( avformat_open_input(&container,filename,NULL,NULL) < 0 ||
av_find_stream_info(container) < 0 ||
(stream_id = av_find_best_stream(container, AVMEDIA_TYPE_AUDIO,
-1, -1, NULL, 0)) < 0 )
{
std::cout << "Unable to open file \"" << filename << "\"" <<
std::endl;
}
else
{
av_dump_format(container,0,filename,false);
AVCodecContext *ctx = container->streams[stream_id]->codec;
AVCodec *codec = avcodec_find_decoder(ctx->codec_id);
if ( codec == NULL || avcodec_open2( ctx, codec, NULL ) < 0 )
{
std::cout << "Codec cannot be found or inited" << std::endl;
}
else
{
// this code works for both wav and mp3
double sample_rate = ctx->sample_rate;
int64_t durationUS = container->duration;
double periodUS = AV_TIME_BASE / sample_rate;
// this gives the theoretical number of samples
// it's consitent with the number of samples displayed by
Audicity audio file editor
int64_t numberOfSamplesExpected = static_cast<int>( durationUS
/ periodUS );
// let's read and see how many samples we can get!
AVPacket packet;
av_init_packet( &packet );
packet.pos = 0;
packet.data = NULL;
packet.size = 0;
AVFrame *frame = avcodec_alloc_frame();
int64_t samplesFound = 0;
int frameFinished = 0;
while ( av_read_frame( container, &packet ) >= 0 )
{
if ( packet.stream_index == stream_id )
{
if ( avcodec_decode_audio4( ctx, frame, &frameFinished,
&packet ) >= 0 )
{
samplesFound += frame->nb_samples;
}
}
}
avcodec_free_frame( &frame );
if ( samplesFound == numberOfSamplesExpected )
{
std::cout << "OK, found all " << samplesFound << "
sample(s)" << std::endl;
}
else
{
std::cout << "FAILED, only got " << samplesFound << "
sample(s), out of " << numberOfSamplesExpected << std::endl;
std::cout << (numberOfSamplesExpected-samplesFound) << "
samples could not be extracted!" << std::endl;
}
}
}
av_close_input_file(container);
}
int main(int argc, char **argv)
{
if ( argc == 2 )
{
check_size(argv[1]);
return 0;
}
else
{
printf("usage: %s input_file\n",
argv[0]);
return 1;
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20130725/85fbfc6e/attachment.html>
More information about the Libav-user
mailing list