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