From a3801a0476f86b2a8ec69ef4060b1cdd605ec420 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Fri, 7 Jun 2013 16:14:33 +0100 Subject: fixed 2nd render only when delete context --- rotord/rendercontext.cpp | 182 ++++++----------------------------------------- 1 file changed, 23 insertions(+), 159 deletions(-) (limited to 'rotord/rendercontext.cpp') 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& } 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 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"< processors){ + + cerr<<"Rotor: starting audio analysis"<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 "<sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ")"<format<< " at "<sample_rate<<" Hz"<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"<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 " 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: "<cleanup(); p->print_summary(); } - - av_free(frame); - avcodec_close(codecContext); - avformat_close_input(&formatContext); - - return true; + cerr<<"Rotor: finished audio analysis"<