summaryrefslogtreecommitdiff
path: root/rotord/rendercontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/rendercontext.cpp')
-rw-r--r--rotord/rendercontext.cpp182
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