summaryrefslogtreecommitdiff
path: root/rotord
diff options
context:
space:
mode:
authorTim Redfern <tim@herge.(none)>2013-04-11 18:34:59 +0100
committerTim Redfern <tim@herge.(none)>2013-04-11 18:34:59 +0100
commit74d1f70bcde75dd1c1ef4d4a1673aa62014d4278 (patch)
tree9fdaa5c15dd6156b43b54cf860226a55ac13654a /rotord
parent4761b802f1378f830c74bdcd695d5f74a38a7ed6 (diff)
first attempt to output video craqshes
Diffstat (limited to 'rotord')
-rw-r--r--rotord/02.xml14
-rw-r--r--rotord/ValgrindOut.xml51
-rwxr-xr-xrotord/rotor.cpp142
-rwxr-xr-xrotord/rotor.h2
-rw-r--r--rotord/style01.xml7
-rw-r--r--rotord/style02.xml7
6 files changed, 215 insertions, 8 deletions
diff --git a/rotord/02.xml b/rotord/02.xml
new file mode 100644
index 0000000..79c1b6c
--- /dev/null
+++ b/rotord/02.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<patchbay ID="0f7aa258-7c2f-11e2-abbd-133252267708">Off and on template ©Rotor 2013
+ <node ID="01" type="audio_analysis" soname="qm-vamp-plugins" id="qm-tempotracker" output="signal">beats
+ </node>
+ <node ID="04" type="bang" output="signal">outputs 0 except when signal first passes a new integer: then 1
+ <signal_input from="01">signal to analyse</signal_input>
+ </node>
+ <node ID="05" type="signal_output">outputs data when changed
+ <signal_input from="04">signal to output</signal_input>
+ </node>
+ <node ID="06" type="video_output">renders the video
+ <image_input from="04">video to output</image_input>
+ </node>
+</patchbay>
diff --git a/rotord/ValgrindOut.xml b/rotord/ValgrindOut.xml
new file mode 100644
index 0000000..f0b4b6d
--- /dev/null
+++ b/rotord/ValgrindOut.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>memcheck</protocoltool>
+
+<preamble>
+ <line>Memcheck, a memory error detector</line>
+ <line>Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.</line>
+ <line>Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info</line>
+ <line>Command: rotord </line>
+</preamble>
+
+<pid>21214</pid>
+<ppid>18095</ppid>
+<tool>memcheck</tool>
+
+<args>
+ <vargv>
+ <exe>/usr/bin/valgrind.bin</exe>
+ <arg>--suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp</arg>
+ <arg>--leak-check=yes</arg>
+ <arg>--xml=yes</arg>
+ <arg>--xml-file=ValgrindOut.xml</arg>
+ </vargv>
+ <argv>
+ <exe>rotord</exe>
+ <arg></arg>
+ </argv>
+</args>
+
+<status>
+ <state>RUNNING</state>
+ <time>00:00:00:00.048 </time>
+</status>
+
+
+<status>
+ <state>FINISHED</state>
+ <time>00:00:02:38.523 </time>
+</status>
+
+<errorcounts>
+</errorcounts>
+
+<suppcounts>
+</suppcounts>
+
+</valgrindoutput>
+
diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp
index 5736c2f..2da6a8b 100755
--- a/rotord/rotor.cpp
+++ b/rotord/rotor.cpp
@@ -25,7 +25,7 @@ void Render_context::runTask() {
processors.push_back(audio_thumb);
vector<Node*> analysers=graph.find_nodes("audio_analysis");
for (auto a: analysers) {
- processors.push_back(a);
+ processors.push_back(dynamic_cast<Base_audio_processor*>(a));
}
if (load_audio(audio_filename,processors)) {
state=AUDIO_READY;
@@ -308,7 +308,7 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
if (avformat_find_stream_info(formatContext, NULL) < 0)
{
av_free(frame);
- av_close_input_file(formatContext);
+ avformat_close_input(&formatContext);
std::cout << "Error finding the stream info" << std::endl;
return false;
}
@@ -326,7 +326,7 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
if (audioStream == NULL)
{
av_free(frame);
- av_close_input_file(formatContext);
+ avformat_close_input(&formatContext);
std::cout << "Could not find any audio stream in the file" << std::endl;
return false;
}
@@ -337,14 +337,14 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
if (codecContext->codec == NULL)
{
av_free(frame);
- av_close_input_file(formatContext);
+ 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);
- av_close_input_file(formatContext);
+ avformat_close_input(&formatContext);
std::cout << "Couldn't open the context with the decoder" << std::endl;
return false;
}
@@ -378,7 +378,8 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
{
// Try to decode the packet into a frame
int frameFinished = 0;
- int bytes = avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
+ //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
@@ -438,7 +439,7 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
av_free(frame);
avcodec_close(codecContext);
- av_close_input_file(formatContext);
+ avformat_close_input(&formatContext);
return true;
}
@@ -606,4 +607,131 @@ void Audio_analysis::print_features(){
}
bool Video_output::render(const float duration, const float framerate,const string &output_filename,const string &audio_filename){
//render out the network
+ /*
+ //testing signal routes
+ cerr << "Rotor: Signal_output rendering " << duration << " seconds at " << framerate << " frames per second" << endl;
+ float step=1.0f/framerate;
+ float v=0.0f;
+ for (float f=0.0f;f<duration;f+=step) {
+ float u=get_output(Time_spec(f,framerate));
+ if (!fequal(u,v)) {
+ xml_out+=("<signal time='"+ofToString(f)+"'>"+ofToString(u)+"</signal>\n");
+ v=u;
+ }
+ }
+ return true;
+ */
+ //set up output context
+ //then iterate through frames
+ //querying graph at each frame
+
+ av_register_all();
+
+ AVCodec *codec;
+ AVCodecContext *c= NULL;
+ int i, out_size, size, x, y, outbuf_size;
+ FILE *f;
+ AVFrame *picture;
+ uint8_t *outbuf, *picture_buf;
+
+ cerr << "Rotor: rendering " << output_filename << " , " << duration << " seconds at " << framerate << " frames per second" << endl;
+
+ /* find the mpeg1 video encoder */
+ codec = avcodec_find_encoder(AV_CODEC_ID_H264);
+ if (!codec) {
+ cerr<< "codec not found" << endl;
+ return false;
+ }
+
+ c= avcodec_alloc_context3(codec);
+ picture= avcodec_alloc_frame();
+
+ /* put sample parameters */
+ c->bit_rate = 400000;
+ /* resolution must be a multiple of two */
+ c->width = 640;
+ c->height = 250;
+ /* frames per second */
+ c->time_base= (AVRational){1,25};
+ c->gop_size = 10; /* emit one intra frame every ten frames */
+ c->max_b_frames=1;
+ c->pix_fmt = PIX_FMT_YUV420P; //AV_PIX_FMT_RGB24
+
+ AVDictionary *options;
+
+ /* open it */
+ if (avcodec_open2(c, codec, &options) < 0) {
+ cerr << "could not open codec" << endl;
+ return false;
+ }
+
+ f = fopen(output_filename.c_str(), "wb");
+ if (!f) {
+ cerr << "could not open "<< output_filename<<endl;
+ return false;
+ }
+
+ /* alloc image and output buffer */
+ outbuf_size = 100000;
+ outbuf = malloc(outbuf_size);
+ size = c->width * c->height;
+ picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
+
+ picture->data[0] = picture_buf;
+ picture->data[1] = picture->data[0] + size;
+ picture->data[2] = picture->data[1] + size / 4;
+ picture->linesize[0] = c->width;
+ picture->linesize[1] = c->width / 2;
+ picture->linesize[2] = c->width / 2;
+
+ /* encode 1 second of video */
+ for(i=0;i<25;i++) {
+ fflush(stdout);
+ /* prepare a dummy image */
+ /* Y */
+ for(y=0;y<c->height;y++) {
+ for(x=0;x<c->width;x++) {
+ picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
+ }
+ }
+
+ /* Cb and Cr */
+ for(y=0;y<c->height/2;y++) {
+ for(x=0;x<c->width/2;x++) {
+ picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
+ picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
+ }
+ }
+
+ /* encode the image */
+ out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
+ printf("encoding frame %3d (size=%5d)\n", i, out_size);
+ fwrite(outbuf, 1, out_size, f);
+ }
+
+ /* get the delayed frames */
+ for(; out_size; i++) {
+ fflush(stdout);
+
+ out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
+ printf("write frame %3d (size=%5d)\n", i, out_size);
+ fwrite(outbuf, 1, out_size, f);
+ }
+
+ /* add sequence end code to have a real mpeg file */
+ outbuf[0] = 0x00;
+ outbuf[1] = 0x00;
+ outbuf[2] = 0x01;
+ outbuf[3] = 0xb7;
+ fwrite(outbuf, 1, 4, f);
+ fclose(f);
+ free(picture_buf);
+ free(outbuf);
+
+ avcodec_close(c);
+ av_free(c);
+ av_free(picture);
+ printf("\n");
+
+ return true;
} \ No newline at end of file
diff --git a/rotord/rotor.h b/rotord/rotor.h
index b0bfad2..4bba577 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -144,7 +144,7 @@ namespace Rotor {
Time_spec(float _seconds,float _framerate){ seconds=_seconds; framerate=_framerate; };
float seconds;
float framerate;
- const Time_spec lastframe(){
+ Time_spec lastframe(){
return Time_spec(seconds-(1.0f/framerate),framerate);
}
};
diff --git a/rotord/style01.xml b/rotord/style01.xml
new file mode 100644
index 0000000..d2d2f46
--- /dev/null
+++ b/rotord/style01.xml
@@ -0,0 +1,7 @@
+<style ID="0f7aa258-7c2f-11e2-abbd-133252267708" thumbnail="style01.png">No Offs
+ <info>A quick cutting style that cuts the beat and energy of the tune. We recommend this style for a performance based video, which requires two full track length takes of a singer and/or other members of the act or a single take of another action. A minimum of seven other videos should be uploaded to get the most out of animated zooming overlays.</info>
+ <slot minvideos="1" maxvideos="1" ID="1">This should be a video of a full performance of the song</slot>
+ <slot minvideos="1" maxvideos="1" ID="2">This should be a video of a full performance of the song</slot>
+ <slot minvideos="5" maxvideos="-1" ID="10">These should be a sequence of video cutaways</slot>
+ <slot minvideos="5" maxvideos="-1" ID="11">These should be a sequence of video cutaways</slot>
+</style>
diff --git a/rotord/style02.xml b/rotord/style02.xml
new file mode 100644
index 0000000..d2d2f46
--- /dev/null
+++ b/rotord/style02.xml
@@ -0,0 +1,7 @@
+<style ID="0f7aa258-7c2f-11e2-abbd-133252267708" thumbnail="style01.png">No Offs
+ <info>A quick cutting style that cuts the beat and energy of the tune. We recommend this style for a performance based video, which requires two full track length takes of a singer and/or other members of the act or a single take of another action. A minimum of seven other videos should be uploaded to get the most out of animated zooming overlays.</info>
+ <slot minvideos="1" maxvideos="1" ID="1">This should be a video of a full performance of the song</slot>
+ <slot minvideos="1" maxvideos="1" ID="2">This should be a video of a full performance of the song</slot>
+ <slot minvideos="5" maxvideos="-1" ID="10">These should be a sequence of video cutaways</slot>
+ <slot minvideos="5" maxvideos="-1" ID="11">These should be a sequence of video cutaways</slot>
+</style>