diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-06-07 16:14:33 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-06-07 16:14:33 +0100 |
| commit | a3801a0476f86b2a8ec69ef4060b1cdd605ec420 (patch) | |
| tree | 800d400f814ecd12caa6f83f8c36ca8c359daf77 /rotord/rendercontext.cpp | |
| parent | 49ed3d2e3e4ed8385e8c007c334c01c65cd3acfe (diff) | |
fixed 2nd render only when delete context
Diffstat (limited to 'rotord/rendercontext.cpp')
| -rw-r--r-- | rotord/rendercontext.cpp | 182 |
1 files changed, 23 insertions, 159 deletions
diff --git a/rotord/rendercontext.cpp b/rotord/rendercontext.cpp index 9e6d958..422ef08 100644 --- a/rotord/rendercontext.cpp +++ b/rotord/rendercontext.cpp @@ -269,190 +269,54 @@ Command_response Render_context::session_command(const std::vector<std::string>& } return response; } -/* -//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/ -//great to use c++11 features -bool Render_context::load_audio(const string &filename,vector<Base_audio_processor*> processors){ - - audioloader.setup(filename); - - av_dump_format(audioloader.formatContext, 0, 0, false); //avformat.h line 1256 - int samples = ((audioloader.formatContext->duration + 5000)*audioloader.codecContext->sample_rate)/AV_TIME_BASE; - graph.duration=((float)audioloader.formatContext->duration)/AV_TIME_BASE; - - - for (auto p: processors) { - if(!p->init(audioloader.codecContext->channels,audioloader.codecContext->bits_per_raw_sample,samples,audioloader.codecContext->sample_rate) ){ - cerr<<"Plugin failed to initialse"<<endl; - return false; - } - } - return true; -} -*/ bool Render_context::load_audio(const string &filename,vector<Base_audio_processor*> processors){ + + cerr<<"Rotor: starting audio analysis"<<endl; + + libav::audioloader loader; + loader.setup(filename); - av_register_all(); - - AVFrame* frame = avcodec_alloc_frame(); - if (!frame) - { - std::cout << "Error allocating the frame" << std::endl; - return false; - } - - AVFormatContext* formatContext = NULL; - if (avformat_open_input(&formatContext, filename.c_str(), NULL, NULL) != 0) - { - av_free(frame); - std::cout << "Error opening the file" << std::endl; - return false; - } - - - if (avformat_find_stream_info(formatContext, NULL) < 0) - { - av_free(frame); - avformat_close_input(&formatContext); - std::cout << "Error finding the stream info" << std::endl; - return false; - } + graph.duration=((float)loader.formatContext->duration)/AV_TIME_BASE; - AVStream* audioStream = NULL; - for (unsigned int i = 0; i < formatContext->nb_streams; ++i) - { - if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) - { - audioStream = formatContext->streams[i]; - break; - } - } - - if (audioStream == NULL) - { - av_free(frame); - avformat_close_input(&formatContext); - std::cout << "Could not find any audio stream in the file" << std::endl; - return false; - } - - AVCodecContext* codecContext = audioStream->codec; - - codecContext->codec = avcodec_find_decoder(codecContext->codec_id); - if (codecContext->codec == NULL) - { - av_free(frame); - avformat_close_input(&formatContext); - std::cout << "Couldn't find a proper decoder" << std::endl; - return false; - } - else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0) - { - av_free(frame); - avformat_close_input(&formatContext); - std::cout << "Couldn't open the context with the decoder" << std::endl; - return false; - } - - av_dump_format(formatContext, 0, 0, false); //avformat.h line 1256 - int samples = ((formatContext->duration + 5000)*codecContext->sample_rate)/AV_TIME_BASE; - graph.duration=((float)formatContext->duration)/AV_TIME_BASE; - - std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<<samples <<" samples" << std::endl; - std::cout << "The data is in format " <<codecContext->sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ")"<<std::endl; - //std::cout << "Decoding to format " <<frame->format<< " at "<<frame->sample_rate<<" Hz"<<std::endl; - - //frame->sample_rate=codecContext->sample_rate; + int rate = loader.codecContext->sample_rate; + int samples = ((loader.formatContext->duration + 5000)*rate)/AV_TIME_BASE; //why 5000 more? + int channels= loader.codecContext->channels; + int bits = loader.codecContext->bits_per_raw_sample; for (auto p: processors) { - if(!p->init(codecContext->channels,16,samples,codecContext->sample_rate) ){ + if(!p->init(channels,bits,samples,rate) ){ cerr<<"Plugin failed to initialse"<<endl; return false; } } - AVPacket packet; - av_init_packet(&packet); + AVFrame* frame=loader.get_frame(); int sample_processed=0; - while (true) + while (frame) { - int ret=av_read_frame(formatContext, &packet); - if (ret<0) { - cerr << "finished with code "<<ret <<(ret==AVERROR_EOF?" ,EOF":"")<<endl; - break; + //now we can pass the data to the processor(s) + for (auto p: processors) { + p->process_frame(frame->data[0],frame->nb_samples); } - if (packet.stream_index == audioStream->index) - { - // Try to decode the packet into a frame - int frameFinished = 0; - //int bytes = - avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet); - - // Some frames rely on multiple packets, so we have to make sure the frame is finished before - // we can use it - if (frameFinished) - { - // frame now has usable audio data in it. How it's stored in the frame depends on the format of - // the audio. If it's packed audio, all the data will be in frame->data[0]. If it's in planar format, - // the data will be in frame->data and possibly frame->extended_data. Look at frame->data, frame->nb_samples, - // frame->linesize, and other related fields on the FFmpeg docs. I don't know how you're actually using - // the audio data, so I won't add any junk here that might confuse you. Typically, if I want to find - // documentation on an FFmpeg structure or function, I just type "<name> doxygen" into google (like - // "AVFrame doxygen" for AVFrame's docs) - - //av_get_channel_layout_string (char *buf, int buf_size, int nb_channels, uint64_t channel_layout) + sample_processed+=frame->nb_samples; + //mutex.lock(); + progress=((float)sample_processed)/samples; + //mutex.unlock(); - - //now we can pass the data to the processor(s) - for (auto p: processors) { - p->process_frame(frame->data[0],frame->nb_samples); - } - sample_processed+=frame->nb_samples; - //mutex.lock(); - progress=((float)sample_processed)/samples; - //mutex.unlock(); - } - } - // You *must* call av_free_packet() after each call to av_read_frame() or else you'll leak memory - av_free_packet(&packet); + frame=loader.get_frame(); } - // Some codecs will cause frames to be buffered up in the decoding process. If the CODEC_CAP_DELAY flag - // is set, there can be buffered up frames that need to be flushed, so we'll do that - if (codecContext->codec->capabilities & CODEC_CAP_DELAY) - { - av_init_packet(&packet); - // Decode all the remaining frames in the buffer, until the end is reached - int frameFinished = 0; - int bytes = avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet); - while (bytes >= 0 && frameFinished) - { - for (auto p: processors) { - p->process_frame(frame->data[0],frame->nb_samples); - } - //mutex.lock(); - progress=((double)sample_processed)/samples; - //mutex.unlock(); - } - } - - cerr << "finished processing: "<<sample_processed << " samples of "<<samples<<", "<<((double)sample_processed*100)/samples<<"%"<< std::endl; + loader.close(); - // Clean up! for (auto p: processors) { p->cleanup(); p->print_summary(); } - - av_free(frame); - avcodec_close(codecContext); - avformat_close_input(&formatContext); - - return true; + cerr<<"Rotor: finished audio analysis"<<endl; } bool Render_context::load_video(const string &nodeID,const string &filename){ //this is a good standard example of how to find |
