summaryrefslogtreecommitdiff
path: root/rotord/src/rotor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/src/rotor.cpp')
-rwxr-xr-xrotord/src/rotor.cpp67
1 files changed, 48 insertions, 19 deletions
diff --git a/rotord/src/rotor.cpp b/rotord/src/rotor.cpp
index 90f60a9..6e0c790 100755
--- a/rotord/src/rotor.cpp
+++ b/rotord/src/rotor.cpp
@@ -34,6 +34,7 @@ Node_factory::Node_factory(){
//nodes_drawing.h
add_type("shape",new Shape());
add_type("hello",new Hello_draw());
+ add_type("waves",new Waves());
//nodes_filters.h
add_type("blur",new Blur());
add_type("luma_levels",new Luma_levels());
@@ -212,28 +213,53 @@ bool Video_output::render(const float duration, const float framerate,const stri
gettimeofday(&start, NULL);
+ uint16_t *audioframe;
+ int samples_in_frame;
+
if (usingaudio){
- //does audioloader output interleaved samples?
- int samples_in_frame=(audioloader.codecContext->channels*audioloader.codecContext->sample_rate)/framerate;
+ //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 "+ofToString(samples_in_frame)+" samples at "+ofToString(audioloader.codecContext->sample_rate)+" hz");
- uint16_t *audioframe;
+ 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;
while (vf<duration){ //-vstep) {
+ uint16_t *audio=nullptr;
if (usingaudio) {
- while (!fless(af,vf)) {
- //insert audio frames until we are ahead of the video
- //instead: get full amount of samples for frame
+ uint16_t *audio=audioloader.get_samples(samples_in_frame);
+ if (aoffs>0){
+ //shift down samples
+ int s=0;
+ while ((s+aoffs)<audioend) {
+ for (int j=0;j<audioloader.codecContext->channels;j++){
+ audioframe[s*audioloader.codecContext->channels+j]=audioframe[(s+aoffs)*audioloader.codecContext->channels+j];
+ }
+ s++;
+ }
+ aoffs=s;
+ }
+ for (int i=0;i<samples_in_frame;i++){
+ for (int j=0;j<audioloader.codecContext->channels;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()<audioend) {
+ //insert audio frames until we are only 1 audio frame behind the next video frame
//send audio_framesize() of them through until buffer is used
//pass full buffer within frame_spec for av nodes
-
- exporter.encodeFrame(audioloader.get_samples(exporter.get_audio_framesize()));
+ exporter.encodeFrame(audioframe+(aoffs*audioloader.codecContext->channels));
af+=exporter.get_audio_step();
+ aoffs+=exporter.get_audio_framesize();
}
}
@@ -246,9 +272,12 @@ bool Video_output::render(const float duration, const float framerate,const stri
//[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: "<<vf<<" seconds, vstep "<<vstep<<" ,asking for frame "<<((int)((vf*framerate)+0.5))<<endl;
-
- Image* i=get_output(Frame_spec(vf,framerate,duration,outW,outH));
+ //cerr<<"videoloader: "<<vf<<" seconds, vstep "<<vstep<<" ,asking for frame "<<((int)((vf*framerate)+0.5))<<endl
+ Image* i;
+ if (usingaudio) {
+ i=get_output(Frame_spec(vf,framerate,duration,outW,outH,&Audio_frame(audio,audioloader.codecContext->channels,samples_in_frame)));
+ }
+ else i=get_output(Frame_spec(vf,framerate,duration,outW,outH));
if (i) {
exporter.encodeFrame(i->RGBdata);
@@ -264,11 +293,11 @@ bool Video_output::render(const float duration, const float framerate,const stri
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 "+ofToString(mtime)+" seconds");
-
+
if (usingaudio) {
audioloader.close();
- //delete[] audioframe;
- }
+ delete[] audioframe;
+ }
@@ -296,15 +325,15 @@ bool Video_loader::load(const string &_filename){
+", channels:"+ofToString(player.getNumberOfChannels()));
return true;
}
-
+
logger.error("Video_loader failed to load "+_filename);
-
+
return false;
}
Image* Video_loader::output(const Frame_spec &frame){
if (isLoaded){
- //this approach is running into the inability to seek when requesting playback speed > 1.
+ //this approach is running into the inability to seek when requesting playback speed > 1.
//need to cache frames so as to avoid asking for a frame other than the next one.
//need an algorithm to find the previous keyframe and seek forward
@@ -324,7 +353,7 @@ Image* Video_loader::output(const Frame_spec &frame){
if (!player.fetchFrame(frame.w,frame.h,wanted)) { //seek fail
Logger& logger = Logger::get("Rotor");
logger.error("Video_loader failed to seek frame "+ofToString(wanted)+" of "+attributes["filename"]->value);
-
+
if (image.w>0) return &image; //just return the previous frame if possible
else return nullptr;
}
@@ -334,4 +363,4 @@ Image* Video_loader::output(const Frame_spec &frame){
return &image;
}
return nullptr;
-}; \ No newline at end of file
+};