Hello. This code plays file too fast as I understood ... I had this done from internet, I just made some changes for actual ffmpeg version
/* * ffmpeg/libav audio decode and playback using openal * * * sources of inspiration: * http://blinkingblip.wordpress.com/2011/10/08/decoding-and-playing-an-audio-stream-using-libavcodec-libavformat-and-libao/ * http://git.libav.org/?p=libav.git;a=blob;f=libavcodec/api-example.c;hb=HEAD * http://kcat.strangesoft.net/openal-tutorial.html * * compile: * gcc decode.c -lavformat -lopenal * * Cheers * Xerxes RÄnby */ #include <stdio.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/avutil.h> #include <AL/al.h> #include <AL/alc.h> void die(const char* message) { fprintf(stderr, "%s\n", message); exit(1); } int main(int argc, char* argv[]) { if (argc < 2) { die("Please provide the file path as the first argument"); } const char* input_filename = argv[1]; // This call is necessarily done once in your app to initialize // libavformat to register all the muxers, demuxers and protocols. av_register_all(); // A media container AVFormatContext* container = 0; if (avformat_open_input(&container, input_filename, NULL, NULL) < 0) { die("Could not open file"); } if (avformat_find_stream_info(container, NULL) < 0) { die("Could not find file info"); } int stream_id = -1; // To find the first audio stream. This process may not be necessary // if you can gurarantee that the container contains only the desired // audio stream int i; for (i = 0; i < container->nb_streams; i++) { if (container->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { stream_id = i; break; } } if (stream_id == -1) { die("Could not find an audio stream"); } // Find the apropriate codec and open it AVCodecContext* codec_context = container->streams[stream_id]->codec; AVCodec* codec = avcodec_find_decoder(codec_context->codec_id); if (!avcodec_open2(codec_context, codec, NULL) < 0) { die("Could not find open the needed codec"); } // To initalize openal for playback ALCdevice *dev; ALCcontext *ctx; dev = alcOpenDevice(NULL); if(!dev) { fprintf(stderr, "Oops\n"); return 1; } ctx = alcCreateContext(dev, NULL); alcMakeContextCurrent(ctx); if(!ctx) { fprintf(stderr, "Oops2\n"); return 1; } int initBuffer = 1; int bufferNumber = 0; #define NUM_BUFFERS 3 #define BUFFER_SIZE 4096 ALuint source, buffers[NUM_BUFFERS]; ALuint frequency = 44100; ALenum format = AL_FORMAT_STEREO16; alGenBuffers(NUM_BUFFERS, buffers); alGenSources(1, &source); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error generating :(\n"); return 1; } // libav AVPacket packet; AVFrame* decodedFrame; decodedFrame=av_frame_alloc(); int len; while (1) { // Read one packet into `packet` if (av_read_frame(container, &packet) < 0) { break; // End of stream. Done decoding. } if(packet.stream_index!=stream_id) { // Skip Video and subtitle packets printf("V"); continue; } printf("A"); // Decodes audio data from `packet` into the frame while( packet.size >0) { int finishedFrame=0; len = avcodec_decode_audio4(codec_context, decodedFrame, &finishedFrame, &packet); if(len<0) { printf("error"); break; // Error in decoding } if (finishedFrame) { // Decoded data is now available in // decodedFrame->data[0] int data_size = av_samples_get_buffer_size(NULL, codec_context->channels, decodedFrame->nb_samples, codec_context->sample_fmt, 1); // OpenAL consumes buffers in the background // we first need to initialize the OpenAL buffers then // start continous playback. if(initBuffer) { alBufferData(buffers[bufferNumber], format, decodedFrame->data[0], data_size, frequency); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error loading :(\n"); return 1; } if(bufferNumber==2){ // all buffers queued alSourceQueueBuffers(source, NUM_BUFFERS, buffers); // start playback alSourcePlay(source); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error starting :(\n"); return 1; } initBuffer=0; } // update buffer number to fill bufferNumber=(bufferNumber+1)%3; } else { // OpenAL is playing in the background. // one new frame with audio data is ready // first wait for openal to release one buffer ALuint buffer; ALint val; do { alGetSourcei(source, AL_BUFFERS_PROCESSED, &val); } while (val <=0); // fill and requeue the empty buffer alSourceUnqueueBuffers(source, 1, &buffer); alBufferData(buffer, format, decodedFrame->data[0], data_size, frequency); alSourceQueueBuffers(source, 1, &buffer); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error buffering :(\n"); return 1; } //Restart openal playback if needed alGetSourcei(source, AL_SOURCE_STATE, &val); if(val != AL_PLAYING) alSourcePlay(source); } } //There may be more than one frame of audio data //inside the packet. packet.size-=len; packet.data+=len; } // while packet.size > 0 } // while more packets exist inside container. avformat_close_input(&container); // Wait for openal to finish playback of any remaining buffers. ALint val; do { alGetSourcei(source, AL_SOURCE_STATE, &val); } while(val == AL_PLAYING); // Free OpenAL resources alDeleteSources(1, &source); alDeleteBuffers(NUM_BUFFERS, buffers); alcMakeContextCurrent(NULL); alcDestroyContext(ctx); alcCloseDevice(dev); fprintf(stdout, "Done playing. Exiting..."); return 0; } What I do wrong? -- Regards, Dmitry
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
