Bugzilla – Attachment 457 Details for
Bug 725
FFMPEGMediaPlayer audio frame decode and playback
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
Log In
[x]
|
Forgot Password
Login:
[x]
decode.c ffmpeg/libav audio decode and openal playback native example.
decode.c (text/x-csrc), 6.70 KB, created by
Xerxes Rånby
on 2013-04-24 23:07:36 CEST
(
hide
)
Description:
decode.c ffmpeg/libav audio decode and openal playback native example.
Filename:
MIME Type:
Creator:
Xerxes Rånby
Created:
2013-04-24 23:07:36 CEST
Size:
6.70 KB
patch
obsolete
>/* > * 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 (av_find_stream_info(container) < 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_open(codec_context, codec) < 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=avcodec_alloc_frame(); > 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. > > av_close_input_file(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; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 725
: 457