[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