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; } }
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
