From c23c67796989dd436955dbcb14c6c5b8199abca1 Mon Sep 17 00:00:00 2001 From: Comment Date: Mon, 16 Sep 2013 23:15:51 +0100 Subject: cleanup exporter wrapper --- rotord/src/graph.cpp | 221 +++++---------------------------------------------- 1 file changed, 19 insertions(+), 202 deletions(-) (limited to 'rotord/src/graph.cpp') diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp index 81f3275..74a569b 100644 --- a/rotord/src/graph.cpp +++ b/rotord/src/graph.cpp @@ -74,12 +74,16 @@ bool Graph::preview(xmlIO &XML,string &node,string &_format,int frame,int w,int } } XML.popTag(); - return true; + return true; } return false; } bool Graph::video_render(const string &output_filename,const float framerate) { + + //https://www.adobe.com/devnet/video/articles/mp4_movie_atom.html + //https://www.google.ie/search?q=ffmbc&aq=f&oq=ffmbc&aqs=chrome.0.57j0l2j60j0j60.4360j0&sourceid=chrome&ie=UTF-8#q=ffmbc+git + //vector loaders=find_nodes("video_loader"); //for (auto i:loaders){ // if (!dynamic_cast(i)->isLoaded) { @@ -96,7 +100,12 @@ bool Graph::video_render(const string &output_filename,const float framerate) { //setup defaults int bitRate=5000000; AVCodecID codecId=AV_CODEC_ID_H264; //MPEG4; - std::string container ="mp4"; + std::string container; + Poco::StringTokenizer t(output_filename,"."); + if (t.count()>1){ + container="."+t[t.count()-1]; + } + else container=".mp4"; //at the moment it crashes if you render before audio is loaded and also on 2nd render libav::exporter exporter; @@ -141,7 +150,7 @@ bool Graph::video_render(const string &output_filename,const float framerate) { Audio_frame *a; int64_t sample_start=0; while (vf0){ @@ -174,7 +183,7 @@ bool Graph::video_render(const string &output_filename,const float framerate) { sample_start+=samples_in_frame; } else usingaudio=false; - + } @@ -223,151 +232,7 @@ bool Graph::video_render(const string &output_filename,const float framerate) { return false; } - - cerr<<"Rotor: video output node not found"< loaders=find_nodes("video_loader"); - //for (auto i:loaders){ - // if (!dynamic_cast(i)->isLoaded) { - // cerr<<"Rotor: all loaders must be populated before rendering"<(find_node("video_output")); - for (auto f: find_nodes("video_feedback")){ - (dynamic_cast(f))->set_feedback(&(video_output->image)); - } - // - //setup defaults - int bitRate=5000000; - AVCodecID codecId=AV_CODEC_ID_H264; //MPEG4; - std::string container ="mp4"; - - //at the moment it crashes if you render before audio is loaded and also on 2nd render - libav::exporter exporter; - - float spct=100.0f/duration; - - if (exporter.setup(outW,outH,bitRate,framerate,container)) { //codecId, - if (exporter.record(output_filename)) { - - libav::audioloader audioloader; - - bool usingaudio=audioloader.setup(audio_filename); - float *avframe=nullptr; - - Logger& logger = Logger::get("Rotor"); - logger.information("Video_output rendering "+output_filename+": "+toString(duration)+" seconds at "+toString(framerate)+" fps, audio frame size: "+toString(exporter.get_audio_framesize())); - //25fps video and 43.06640625fps audio? hmm - //how to get the timecodes correct for the interleaved files - - struct timeval start, end; - - gettimeofday(&start, NULL); - - uint16_t *audioframe; - int samples_in_frame; - - if (usingaudio){ - //does audioloader output interleaved samples? - samples_in_frame=(audioloader.codecContext->sample_rate)/framerate; - string whether=usingaudio?"Loading":"Cannot load"; - logger.information(whether+" audio file: "+audio_filename+", each frame contains "+toString(samples_in_frame)+" samples at "+toString(audioloader.codecContext->sample_rate)+" hz"); - audioframe=new uint16_t[(samples_in_frame+exporter.get_audio_framesize())*audioloader.codecContext->channels]; - } - - float vstep=1.0f/framerate; - float v=0.0f; - float vf=0.0f; - float af=0.0f; - int aoffs=0; - int audioend=0; - Audio_frame *a; - while (vf0){ - //shift down samples - int s=0; - while ((s+aoffs)channels;j++){ - audioframe[s*audioloader.codecContext->channels+j]=audioframe[(s+aoffs)*audioloader.codecContext->channels+j]; - } - s++; - } - aoffs=s; - } - for (int i=0;ichannels;j++){ - audioframe[(aoffs+i)*audioloader.codecContext->channels+j]=audio[i*audioloader.codecContext->channels+j]; - } - } - audioend=aoffs+samples_in_frame; - aoffs=0; - //while (fless(vf+vstep,af+exporter.get_audio_step())) { - while (aoffs+exporter.get_audio_framesize()channels)); - af+=exporter.get_audio_step(); - aoffs+=exporter.get_audio_framesize(); - } - a=new Audio_frame(audio,audioloader.codecContext->channels,samples_in_frame); - } - - - //[mp3 @ 0x7fffe40330e0] max_analyze_duration 5000000 reached at 5015510 microseconds - //[mp3 @ 0x7fffe4033ec0] Insufficient thread locking around avcodec_open/close() - //[mp3 @ 0x7fffe40330e0] Estimating duration from bitrate, this may be inaccurate - //[libx264 @ 0x7fffe8003940] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 - //[libx264 @ 0x7fffe8003940] profile High, level 3.0 - //[libx264 @ 0x7fffe8003940] 264 - core 123 r2189 35cf912 - H.264/MPEG-4 AVC codec - Copyleft 2003-2012 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=10 keyint_min=1 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=abr mbtree=1 bitrate=400 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 - //Assertion ff_avcodec_locked failed at libavcodec/utils.c:2967 - - //cerr<<"videoloader: "<get_output(Frame_spec(vf,framerate,duration,outW,outH,a)); - } - else i=video_output->get_output(Frame_spec(vf,framerate,duration,outW,outH)); - if (i) { - exporter.encodeFrame(i->RGBdata); - } - vf+=vstep; - progress=vf/duration; - if (usingaudio) {delete a;}; - } - - exporter.finishRecord(); - - gettimeofday(&end, NULL); - - float mtime = ((end.tv_sec-start.tv_sec) + (end.tv_usec-start.tv_usec)/1000000.0) + 0.5; - - logger.information("Video_output: rendered "+output_filename+": in "+toString(mtime)+" seconds"); - - if (usingaudio) { - audioloader.close(); - delete[] audioframe; - } - - - - return true; - } - } - - return false; - } - cerr<<"Rotor: video output node not found"<parameters.find(parameter)!=nodes[nodeID]->parameters.end()) { float val=jnodes[i]["parameters"][l]["value"].asFloat(); if (val!=nodes[nodeID]->parameters.find(parameter)->second->value){ @@ -514,7 +379,7 @@ bool Graph::parseJson(string &data,string &media_path){ else if (fromID!="") cerr << "Rotor: linking parameter " << parameter << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl; } else cerr << "Rotor: cannot find parameter '" << parameter << "' of "<set_parameter(xml.getAttribute("parameter","name","",i5),xml.getAttribute("parameter","value","",i5)); //} //if (n5>0) cerr << "Rotor: found " << n5 << " extra parameters for node '" << nodeID << "'" << endl; - + xml.popTag(); } } @@ -667,54 +532,6 @@ bool Graph::parseXml(string media_path){ loaded=true; return true; } -bool Graph::_load_audio(const string &filename,vector processors){ - Logger& logger = Logger::get("Rotor"); - logger.information("Analysing "+filename); - - libav::audioloader loader; - loader.setup(filename); - - duration=((float)loader.formatContext->duration)/AV_TIME_BASE; - - 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 = 16; //???why can't we read this loader.codecContext->bits_per_raw_sample; - - for (auto p: processors) { - if(!p->init(channels,bits,samples,rate) ){ - logger.error("ERROR: Audio plugin failed to initialse"); - return false; - } - } - - AVFrame* frame=loader.get_frame(); - int sample_processed=0; - - while (frame&&!cancelled) - { - //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; //atomic on 64 bit? - //mutex.unlock(); - - frame=loader.get_frame(); - } - - loader.close(); - - for (auto p: processors) { - p->cleanup(); - p->print_summary(); - } - - logger.information("Finished audio analysis"); - return true; -} bool Graph::load_audio(const string &filename,vector processors){ Logger& logger = Logger::get("Rotor"); logger.information("Analysing "+filename); -- cgit v1.2.3