summaryrefslogtreecommitdiff
path: root/rotord/rendercontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/rendercontext.cpp')
-rw-r--r--rotord/rendercontext.cpp386
1 files changed, 0 insertions, 386 deletions
diff --git a/rotord/rendercontext.cpp b/rotord/rendercontext.cpp
deleted file mode 100644
index 7362d64..0000000
--- a/rotord/rendercontext.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-#include "rotor.h"
-
-
-using namespace Rotor;
-void Render_context::runTask() {
- while (!isCancelled()) {
- int cmd=0;
- mutex.lock();
- if (work_queue.size()){
- cmd=work_queue[0];
- work_queue.pop_front();
- }
- mutex.unlock();
- if(cmd==ANALYSE_AUDIO) {
- state=ANALYSING_AUDIO;
- vector<Base_audio_processor*> processors;
- processors.push_back(audio_thumb);
- vector<Node*> analysers=graph.find_nodes("audio_analysis");
- for (auto a: analysers) {
- processors.push_back(dynamic_cast<Base_audio_processor*>(a));
- }
- if (load_audio(audio_filename,processors)) {
- audio_loaded=true;
- state=IDLE;
- }
- else {
- //an error occurred: TODO have to clean up allocated data. autoptr?
- audio_loaded=false;
- state=IDLE;
- }
- }
- if(cmd==RENDER) {
- state=RENDERING;
- if(graph.video_render(output_filename,audio_filename,output_framerate,progress)){
- state=IDLE;
- }
- else {
- //an error occurred: TODO have to clean up allocated data. autoptr?
- cerr<<"Rotor: render failed"<<endl;
- state=IDLE;
- }
- }
- sleep(100);
- }
- printf("Rotor: stopping thread\n");
-}
-void Render_context::add_queue(int item) {
- mutex.lock();
- work_queue.push_back(item);
- mutex.unlock();
-}
-void Render_context::session_command(const std::vector<std::string>& command,xmlIO& XML,HTTPResponse::HTTPStatus& status){
- Logger& logger = Logger::get("Rotor");
- status=HTTPResponse::HTTP_BAD_REQUEST; //error by default
- if (command[2]=="resolution") {
- if (command[0]=="PUT") {
- if (command.size()>2) {
- if (state==IDLE) {
- Poco::StringTokenizer t1(command[3],",");
- if (t1.count()>1){
- int w=ofToInt(t1[0]);
- int h=ofToInt(t1[1]);
- if (graph.set_resolution(w,h)){
- logger.information("resolution set to "+t1[0]+"x"+t1[1]);
- XML.addValue("status","resolution set to "+t1[0]+"x"+t1[1]);
- status=HTTPResponse::HTTP_OK;
- }
- else {
- logger.error("ERROR: invalid resolution request: "+t1[0]+"x"+t1[1]);
- XML.addValue("error","invalid resolution request: "+t1[0]+"x"+t1[1]);
- }
- }
- }
- else {
- XML.addValue("error","session busy");
- }
- }
- }
- }
- if (command[2]=="audio") {
- if (command[0]=="PUT") { //get audio file location and initiate analysis
- if (command.size()>2) {
- if (state==IDLE) {
- audio_filename=media_dir+command[3]; //for now, store session variables in memory //check file exists
- Poco::File f=Poco::File(audio_filename);
- if (f.exists()) {
- //pass to worker thread ??if engine is ready?? ??what if engine has finished but results aren't read??
- add_queue(ANALYSE_AUDIO);
- status=HTTPResponse::HTTP_OK;
- logger.information("Starting audio analysis: "+command[3]);
- XML.addValue("status","Starting audio analysis: "+command[3]);
- }
- else {
- status=HTTPResponse::HTTP_NOT_FOUND;
- logger.error("ERROR: audio file "+command[3]+" not found");
- XML.addValue("error",command[3]+" not found");
- }
-
- }
- else {
- logger.error("ERROR: Session busy");
- XML.addValue("error","Session busy");
- }
- }
- }
- if (command[0]=="GET") {
- if (state==ANALYSING_AUDIO) {
- status=HTTPResponse::HTTP_OK;
- XML.addValue("status","Analysing audio");
- char c[20];
- sprintf(c,"%02f",progress);
- XML.addValue("progress",string(c));
- }
- else if (audio_loaded) {
- //not sure about this-- should this state be retained?
- //can the data only be read once?
- //for now
- status=HTTPResponse::HTTP_OK;
- XML.addValue("status","Audio ready");
- XML.addValue("audio",audio_thumb->print());
- }
- else {
- logger.error("ERROR: audio thumbnail requested but no audio loaded");
- XML.addValue("error","No audio loaded");
- }
- }
- if (command[0]=="DELETE") {
- if (state==IDLE) {
- audio_filename="";
- logger.information("Audio deleted");
- XML.addValue("status","Audio deleted");
- status=HTTPResponse::HTTP_OK;
- }
- else {
- logger.error("ERROR: Session busy");
- XML.addValue("error","Session busy");
- }
- }
- }
- if (command[2]=="graph") {
- if (command[0]=="GET") {
- if (graph.loaded) {
- status=HTTPResponse::HTTP_OK;
- //XML.addValue("patchbay",graph.toString());
- logger.information("Requested graph");
- XML.loadFromBuffer(graph.toString());
- }
- else {
- logger.error("ERROR: graph not loaded: check XML");
- XML.addValue("error","graph not loaded: check XML");
- }
- }
- if (command[0]=="PUT") { //get new graph from file
- if (command.size()>2) {
- //should interrupt whatever is happening?
- //before begining to load from xml
- if (state==IDLE) { //eventually not like this
- if (graph.load(command[3])) {
- status=HTTPResponse::HTTP_OK;
- logger.information("Loaded graph from http PUT body");
- XML.addValue("status","Loaded graph from PUT body");
- if (audio_loaded) {
- add_queue(ANALYSE_AUDIO);
- status=HTTPResponse::HTTP_OK;
- logger.information("Starting audio analysis for graph: "+command[3]);
- XML.addValue("status","Starting audio analysis for graph: "+command[3]);
- }
- }
- else {
- string graph_filename=graph_dir+command[3];
- Poco::File f=Poco::File(graph_filename);
- if (f.exists()) {
- if (graph.loadFile(graph_filename)) {
- status=HTTPResponse::HTTP_OK;
- //XML.addValue("patchbay",graph.toString());
- //XML.loadFromBuffer(graph.toString());
- XML=graph.xml;
- //the graph could actually contain an xml object and we could just print it here?
- //or could our nodes even be subclassed from xml nodes?
- //the graph or the audio could load first- have to analyse the audio with vamp after the graph is loaded
- //for now the graph must load 1st
- if (audio_loaded) {
- add_queue(ANALYSE_AUDIO);
- status=HTTPResponse::HTTP_OK;
- logger.information("Starting audio analysis for graph: "+command[3]);
- XML.addValue("status","Starting audio analysis for graph: "+command[3]);
- }
- }
- else {
- status=HTTPResponse::HTTP_INTERNAL_SERVER_ERROR; //~/sources/poco-1.4.6-all/Net/include/Poco/Net/HTTPResponse.h
- logger.error("ERROR: graph not loaded: check XML");
- XML.addValue("error","graph not loaded: check XML");
- }
- }
- else {
- status=HTTPResponse::HTTP_NOT_FOUND;
- logger.error("ERROR: "+command[3]+" not found");
- XML.addValue("error",command[3]+" not found");
- }
- }
- }
- }
- }
- if (command[0]=="DELETE") {
- //for now
- graph=Graph();
- logger.information("graph deleted");
- XML.addValue("status","graph deleted");
- status=HTTPResponse::HTTP_OK;
- }
- }
- if (command[2]=="signal") {
- if (command[0]=="GET") { //generate xml from 1st signal output
- if (state==IDLE) {
- //direct call for testing
- float framerate=25.0f;
- //if (command.size()>2) {
- // framerate=ofToFloat(command[3]);
- //}
- string signal_xml;
- if (graph.signal_render(signal_xml,framerate)){
- status=HTTPResponse::HTTP_OK;
- logger.information("rendering signal to xml");
- XML.addValue("signal",signal_xml); //this doesn't work >> pseudo xml
- }
- else {
- status=HTTPResponse::HTTP_INTERNAL_SERVER_ERROR;
- logger.error("ERROR: could not render output signal");
- XML.addValue("error","could not render output signal");
- }
- //else {
- // status=HTTPResponse::HTTP_NOT_FOUND;
- // XML.addValue("error","Signal output not found in graph");
- //}
- }
- else {
- status=HTTPResponse::HTTP_SERVICE_UNAVAILABLE;
- logger.error("ERROR: context busy");
- XML.addValue("error","Context busy");
- }
- }
- }
- if (command[2]=="video") {
- if (command[0]=="PUT") { //get vide file location and initiate analysis
- if (command.size()>4) { //there should be a filename + a destination node
- if (state==IDLE) {
- string video_filename=media_dir+command[4];
- //check file exists
- Poco::File f=Poco::File(video_filename);
- if (f.exists()) {
- if (load_video(command[3],video_filename)) {
- //pass to worker thread ??if engine is ready?? ??what if engine has finished but results aren't read??
- //DUMMY RESPONSE
- status=HTTPResponse::HTTP_OK;
- logger.information("Succesfully loaded "+command[4]+" into video node "+command[3]);
- XML.addValue("status","Succesfully loaded "+command[4]+" into video node "+command[3]);
- }
- else {
- status=HTTPResponse::HTTP_INTERNAL_SERVER_ERROR;
- logger.error("ERROR: could not load "+command[4]+" into video node "+command[3]);
- XML.addValue("error","could not load "+command[4]+" into video node "+command[3]);
- }
- }
- else {
- status=HTTPResponse::HTTP_NOT_FOUND;
- logger.error("ERROR: "+command[4]+" not found");
- XML.addValue("error",command[4]+" not found");
- }
- }
- else {
- status=HTTPResponse::HTTP_BAD_REQUEST;
- logger.error("ERROR: Session busy");
- XML.addValue("error","Session busy");
- }
- }
- else {
- status=HTTPResponse::HTTP_BAD_REQUEST;
- logger.error("ERROR: Bad request");
- XML.addValue("error","Bad request");
- }
- }
- }
- if (command[2]=="render") {
- if (command[0]=="GET") {
- if(state==RENDERING){
- status=HTTPResponse::HTTP_OK;
- XML.addValue("status","Rendering video");
- XML.addValue("progress",ofToString(progress));
- }
- else {
- logger.error("ERROR: Render progress requested but not rendering");
- XML.addValue("error","Not rendering");
- }
- }
- if (command[0]=="PUT") {
- if (command.size()>2) {
- if (state==IDLE) {
- output_filename=output_dir+command[3];
- if (command.size()>3) {
-// output_framerate=ofToFloat(command[4]);
- }
- add_queue(RENDER);
- status=HTTPResponse::HTTP_OK;
- logger.information("Starting render: "+command[3]);
- XML.addValue("status","Starting render: "+command[3]);
- }
- else {
- status=HTTPResponse::HTTP_BAD_REQUEST;
- logger.error("ERROR: Session busy");
- XML.addValue("error","Session busy");
- }
- }
- else {
- status=HTTPResponse::HTTP_BAD_REQUEST;
- logger.error("ERROR: No output file specified");
- XML.addValue("error","No output file specified");
- }
- }
- if (command[0]=="DELETE") {
- status=HTTPResponse::HTTP_OK;
- logger.error("ERROR: Not implemented");
- XML.addValue("status","DUMMY RESPONSE: cancelling render");
- }
- }
-}
-
-bool Render_context::load_audio(const string &filename,vector<Base_audio_processor*> processors){
- Logger& logger = Logger::get("Rotor");
- logger.information("Starting audio analysis");
-
- libav::audioloader loader;
- loader.setup(filename);
-
- graph.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 = 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)
- {
- //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 Render_context::load_video(const string &nodeID,const string &filename){
- //this is a good standard example of how to find
- //a node of a specific type by ID and do something
- if (graph.nodes.find(nodeID)!=graph.nodes.end()){
- if (graph.nodes[nodeID]->type=="video_loader") {
- if (((Video_loader*)graph.nodes[nodeID])->load(filename)) {
- return true;
- }
- }
- }
- return false;
-}