[Libav-user] ffmpeg open AL

Dmitry Adjiev adjiev.dmitry at gmail.com
Sun Nov 9 13:25:56 CET 2014


2014-11-06 5:34 GMT+03:00 Dmitry Adjiev <adjiev.dmitry at gmail.com>:

> 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
>


It works fine with wav, so I plain to resample any sound to playabple
format and play
-- 
Regards,
Dmitry
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20141109/91fd9766/attachment.html>


More information about the Libav-user mailing list