<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2014-11-06 5:34 GMT+03:00 Dmitry Adjiev <span dir="ltr"><<a href="mailto:adjiev.dmitry@gmail.com" target="_blank">adjiev.dmitry@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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/" target="_blank">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" target="_blank">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" target="_blank">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?<span class="HOEnZb"><font color="#888888"><br></font></span></div><span class="HOEnZb"><font color="#888888"><div>-- <br><div>Regards,<br>Dmitry</div>
</div></font></span></div></div></div>
</blockquote></div><br><br clear="all"></div><div class="gmail_extra">It works fine with wav, so I plain to resample any sound to playabple format and play<br></div><div class="gmail_extra">-- <br><div class="gmail_signature">Regards,<br>Dmitry</div>
</div></div>