2014-11-06 5:34 GMT+03:00 Dmitry Adjiev <[email protected]>: > 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
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
