summaryrefslogtreecommitdiff
path: root/NT/src
diff options
context:
space:
mode:
Diffstat (limited to 'NT/src')
-rw-r--r--NT/src/rendercontext.cpp477
-rw-r--r--NT/src/rendercontext.h21
-rw-r--r--NT/src/rotor.cpp4
-rw-r--r--NT/src/rotor.h3
-rw-r--r--NT/src/rotord.cpp8
-rw-r--r--NT/src/rotord.h1
-rw-r--r--NT/src/rotord.obin122328 -> 136232 bytes
7 files changed, 503 insertions, 11 deletions
diff --git a/NT/src/rendercontext.cpp b/NT/src/rendercontext.cpp
index ffc55ed..3309b16 100644
--- a/NT/src/rendercontext.cpp
+++ b/NT/src/rendercontext.cpp
@@ -2,6 +2,8 @@
using namespace Rotor;
using namespace std;
+using Poco::Net::HTTPResponse;
+using Poco::Logger;
string Render_context::text_render(string node_id){
Logger& logger = Logger::get(id);
@@ -31,4 +33,479 @@ string Render_context::text_render(string node_id){
st+=(dynamic_cast<Node_type<string>*>(p))->get_output(f)+"\n";
}
return st;
+}
+void Render_context::session_command(const Session_command& command,xmlIO& XML,HTTPResponse::HTTPStatus& status){
+
+ string s;
+ for (auto c:command.commands){
+ s+=c;
+ s+=" ";
+ }
+
+ Logger& logger = Logger::get(id);
+ status=HTTPResponse::HTTP_BAD_REQUEST; //error by default
+ if (command.commands[1]=="resolution") {
+ if (command.method=="PUT") {
+ if (command.body!="") {
+ if (state!=RENDERING) {
+ Poco::StringTokenizer t1(command.body,",");
+ if (t1.count()>1){
+ int w=toInt(t1[0]);
+ int h=toInt(t1[1]);
+ if (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.commands[1]=="bitrate") {
+ if (command.method=="PUT") {
+ int b=toInt(command.body);
+ if (graph.set_bitrate(b)){
+ logger.information("bitrate set to "+command.body);
+ XML.addValue("status","bitrate set to "+command.body);
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ logger.error("ERROR: Could not set bitrate set to "+command.body);
+ XML.addValue("error","Could not set bitrate set to "+command.body);
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Bad request");
+ XML.addValue("error","Bad request");
+ }
+ }
+ if (command.commands[1]=="fragmentation") {
+ if (command.method=="PUT") {
+ bool f=(toInt(command.body)!=0);
+ if (graph.set_fragmentation(f)){
+ string fs=f?"on":"off";
+ logger.information("MP4 fragmentation "+fs);
+ XML.addValue("status","MP4 fragmentation "+fs);
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ logger.error("ERROR: Could not set MP4 fragmentation");
+ XML.addValue("error","Could not set MP4 fragmentation");
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Bad request");
+ XML.addValue("error","Bad request");
+ }
+ }
+ if (command.commands[1]=="dash") {
+ if (command.method=="PUT") {
+ bool f=(toInt(command.body)!=0);
+ if (graph.set_dash(f)){
+ string fs=f?"on":"off";
+ logger.information("MPEG-DASH output "+fs);
+ XML.addValue("status","MPEG-DASH output "+fs);
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ logger.error("ERROR: Could not set MPEG-DASH output");
+ XML.addValue("error","Could not set MPEG-DASH output");
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Bad request");
+ XML.addValue("error","Bad request");
+ }
+ }
+ if (command.commands[1]=="audio") {
+ if (command.method=="PUT") { //get audio file location and initiate analysis
+ if (command.body!="") {
+ if (state==IDLE) {
+ graph.audio_filename=media_dir+command.body; //for now, store session variables in memory //check file exists
+ Poco::File f=Poco::File(graph.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(Session_task(command.uid,ANALYSE_AUDIO));
+ status=HTTPResponse::HTTP_OK;
+ logger.information("Audio analysis: "+command.body);
+ XML.addValue("status","Starting audio analysis: "+command.body);
+ }
+ else {
+ status=HTTPResponse::HTTP_NOT_FOUND;
+ logger.error("ERROR: audio file "+command.body+" not found");
+ XML.addValue("error",command.body+" not found");
+ }
+
+ }
+ else {
+ logger.error("ERROR: Session busy");
+ XML.addValue("error","Session busy");
+ }
+ }
+ }
+ if (command.method=="GET") {
+ if (state==ANALYSING_AUDIO) {
+ status=HTTPResponse::HTTP_OK;
+ XML.addValue("status","Analysing audio");
+ char c[20];
+ sprintf(c,"%02f",graph.progress);
+ XML.addValue("progress",string(c));
+ }
+ else if (graph.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");
+ graph.audio_thumb->print_vector(XML);
+ //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.method=="DELETE") {
+ if (state==IDLE) {
+ graph.audio_filename="";
+ graph.audio_loaded=false;
+ 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.commands[1]=="graph") {
+ if (command.method=="GET") {
+ if (state!=LOADING_GRAPH) {
+ if (graph.loaded) {
+ status=HTTPResponse::HTTP_OK;
+ //XML.addValue("patchbay",graph.toString());
+ logger.information("Graph loaded");
+ //XML.loadFromBuffer(graph.graphToString());
+ XML.addValue("status","Graph loaded");
+ }
+ else {
+ logger.error("ERROR: graph not loaded");
+ XML.addValue("error","graph not loaded");
+ }
+ }
+ else {
+ logger.error("ERROR: Graph loading");
+ XML.addValue("error","Graph loading");
+ }
+ }
+ if (command.method=="PUT") { //get new graph from file
+ if (command.body!="") {
+ //should interrupt whatever is happening?
+ //before begining to load from xml
+ if (state==IDLE) { //eventually not like this
+ if (command.body!="") {
+ graph_filename="";
+ graph_body="";
+ if (Poco::File(graph_dir+command.body).exists()) {
+ graph_filename=graph_dir+command.body;
+ add_queue(Session_task(command.uid,LOAD_GRAPH));
+ status=HTTPResponse::HTTP_OK;
+ logger.information("Loading graph from file: "+command.body);
+ XML.addValue("status","Loading graph from file: "+command.body);
+ //XML.addValue("render_id",command.uid); process ID?
+ }
+ else {
+ xmlIO xml;
+ bool readable=true;
+ if (!xml.loadFromBuffer(command.body)){
+ Json::Value root; // will contains the root value after parsing.
+ Json::Reader reader;
+ if ( !reader.parse( command.body, root ) )
+ {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Could not load graph");
+ XML.addValue("error","Could not load graph");
+ readable=false;
+ }
+ }
+ if (readable) {
+ graph_body=command.body;
+ add_queue(Session_task(command.uid,LOAD_GRAPH));
+ status=HTTPResponse::HTTP_OK;
+ logger.information("Loading graph from body request");
+ XML.addValue("status","Loading graph from body request");
+ }
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Empty request");
+ XML.addValue("error","Empty request");
+ }
+ }
+ else {
+ logger.error("ERROR: Session busy");
+ XML.addValue("error","Session busy");
+ }
+ }
+ }
+ if (command.method=="DELETE") {
+ //for now
+ graph.clear();
+ logger.information("graph deleted");
+ XML.addValue("status","graph deleted");
+ status=HTTPResponse::HTTP_OK;
+ }
+ }
+ if (command.commands[1]=="signal") {
+ if (command.method=="GET") { //generate xml from 1st signal output
+ if (state==IDLE) {
+ if (command.commands.size()>2) {
+ double framerate;
+ framerate=toFloat(command.body);
+ if (framerate==0.0) framerate=graph.framerate;
+ if (graph.signal_render(XML,command.commands[2],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.commands[1]=="video") {
+ if (command.method=="PUT") { //get vide file location and initiate analysis
+ if (command.body!="") { //there should be a filename + a destination node
+ if (state!=RENDERING) {
+ if (command.commands.size()>2) {
+ string video_filename=media_dir+command.body;
+ //check file exists
+ Poco::File f=Poco::File(video_filename);
+ if (f.exists()) {
+ if (graph.load_video(command.commands[2],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.body+" into video node "+command.commands[2]);
+ XML.addValue("status","Succesfully loaded "+command.body+" into video node "+command.commands[2]);
+ }
+ else {
+ status=HTTPResponse::HTTP_INTERNAL_SERVER_ERROR;
+ logger.error("ERROR: could not load "+command.body+" into video node "+command.commands[2]);
+ XML.addValue("error","could not load "+command.body+" into video node "+command.commands[2]);
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_NOT_FOUND;
+ logger.error("ERROR: "+command.body+" not found");
+ XML.addValue("error",command.body+" not found");
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_NOT_FOUND;
+ logger.error("ERROR: video loader node not specified");
+ XML.addValue("error","video loader node not specified");
+ }
+ }
+ 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");
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Bad request");
+ XML.addValue("error","Bad request");
+ }
+ }
+ if (command.commands[1]=="preview") {
+ if (command.method=="GET") {
+ if(state==IDLE){
+ //parse json to get preview spec, return XML? this is a mess
+ string preview_node=command.commands[2];
+ Json::Value root; // will contains the root value after parsing.
+ Json::Reader reader;
+ if (reader.parse( command.body, root )) {
+ int frame=root["frame"].asInt();
+ int width=root["width"].asInt();
+ int height=root["height"].asInt();
+ string format=root["format"].asString();
+ if (graph.preview(XML,preview_node,format,frame,width,height)) {
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Could not create preview");
+ XML.addValue("error","Could not preview node '"+preview_node+"', frame "+toString(frame)+" at "+toString(width)+"x"+toString(height));
+ }
+ }
+ else {
+ std::cout << "Failed to parse preview request\n"
+ << reader.getFormattedErrorMessages();
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Bad preview request");
+ XML.addValue("error","Bad preview request");
+ }
+ }
+ 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.commands[1]=="features") {
+ if (command.method=="GET") {
+ if(state==IDLE){
+ if (command.commands.size()>2){
+ //parse json to get preview spec, return XML? this is a mess
+ string features_node=command.commands[2];
+ if (graph.print_features(XML,features_node)) {
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Could not print features for node /"+features_node+"/");
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Features node not specified");
+ }
+ }
+ 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.commands[1]=="render") {
+ if (command.method=="GET") {
+ if(state==RENDERING){
+ //graph.mutex.lock();
+ status=HTTPResponse::HTTP_OK;
+ XML.addValue("status","Rendering video");
+ XML.addValue("progress",toString(graph.progress));
+ //graph.mutex.unlock();
+ }
+ else {
+ logger.error("ERROR: Render progress requested but not rendering");
+ XML.addValue("error","Not rendering");
+ }
+ }
+ if (command.method=="PUT") {
+ if (command.body!="") {
+ if (state==IDLE) {
+ Poco::StringTokenizer t1(command.body,",");
+ if (t1.count()>1){
+ output_filename=output_dir+t1[0];
+ start=toInt(t1[1]);
+ if (t1.count()>2){
+ stop=toInt(t1[2]);
+ if (t1.count()>3){
+ double framerate=toFloat(t1[3]);
+ if (framerate>0.0) {
+ output_framerate=framerate;
+ }
+ }
+ }
+ }
+ else {
+ start=0;
+ stop=999999;
+ output_filename=output_dir+command.body;
+ }
+ add_queue(Session_task(command.uid,RENDER));
+ status=HTTPResponse::HTTP_OK;
+ logger.information("Starting render: "+command.body);
+ XML.addValue("status","Starting render: "+command.body);
+ XML.addValue("render_id",command.uid);
+ XML.addValue("path",output_filename);
+ }
+ 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.method=="DELETE") {
+ status=HTTPResponse::HTTP_OK;
+ logger.error("ERROR: Not implemented");
+ XML.addValue("status","DUMMY RESPONSE: cancelling render");
+ }
+ }
+ if (command.commands[1]=="cancel") {
+ if (command.method=="PUT") {
+ if (state==RENDERING){
+ graph.cancelled=true;
+ logger.information("Render cancelled.");
+ XML.addValue("status","render cancelled");
+ }
+ else if (state==ANALYSING_AUDIO){
+ graph.cancelled=true;
+ logger.information("Audio analysis cancelled.");
+ XML.addValue("status","audio analysis cancelled");
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: no process to cancel");
+ XML.addValue("error","No process to cancel");
+ }
+ }
+ else {
+ status=HTTPResponse::HTTP_BAD_REQUEST;
+ logger.error("ERROR: Bad request");
+ XML.addValue("error","Bad request");
+ }
+ }
} \ No newline at end of file
diff --git a/NT/src/rendercontext.h b/NT/src/rendercontext.h
index 097af3f..a84cad8 100644
--- a/NT/src/rendercontext.h
+++ b/NT/src/rendercontext.h
@@ -43,6 +43,12 @@ namespace Rotor {
#define RENDER 3
#define LOAD_GRAPH 4
+ class Session_command {
+ public:
+ Session_command(){body="";};
+ string uid,method,id,body;
+ vector<string> commands;
+ };
class Render_status {
public:
Render_status():status(0),progress(0.0){};
@@ -50,6 +56,11 @@ namespace Rotor {
int status;
double progress;
};
+ class Render_settings {
+ public:
+ Render_settings(int w=640,int h=360):width(w),height(h){};
+ int width,height;
+ };
class Render_context: public Poco::Task {
public:
Render_context(const std::string& _id): Task(_id) {
@@ -76,6 +87,12 @@ namespace Rotor {
sleep(100);
}
}
+ bool set_preset(std::string& _preset){
+ if (presets.find(_preset)==presets.end()) return false;
+ preset=_preset;
+ return true;
+ }
+ void session_command(const Session_command& command,xmlIO& XML,Poco::Net::HTTPResponse::HTTPStatus& status);
Render_status get_render_status(const string &uid){
if (renders.find(uid)!=renders.end()){
if (renders[uid].status==RENDERING){
@@ -89,7 +106,9 @@ namespace Rotor {
Graph graph;
private:
std::string id;
- std::unordered_map<string,Render_status> renders;
+ std::unordered_map<std::string,Render_status> renders;
+ std::unordered_map<std::string,Render_settings> presets;
+ std::string preset;
};
};
diff --git a/NT/src/rotor.cpp b/NT/src/rotor.cpp
index 2909255..12218e5 100644
--- a/NT/src/rotor.cpp
+++ b/NT/src/rotor.cpp
@@ -40,10 +40,9 @@ Json::Value Variable_array_type<T>::to_json(){
return json;
}
-//explicit template instantiation
+//explicit template instantiation to avoid linker errors
template class Variable_type<double>;
template class Variable_type<string>;
-
template class Variable_array_type<double>;
@@ -65,7 +64,6 @@ Json::Value Node::to_json(){
return node;
}
-//factory generates linker errors if rotor.h implementation is seperated: why?
//int main(){
diff --git a/NT/src/rotor.h b/NT/src/rotor.h
index 17c8545..f687694 100644
--- a/NT/src/rotor.h
+++ b/NT/src/rotor.h
@@ -22,6 +22,8 @@ What next?
#include <json/json.h>
#include <typeinfo>
+#include "xmlIO.h"
+
#include "Poco/Logger.h"
#include "Poco/Channel.h"
#include "Poco/SplitterChannel.h"
@@ -32,6 +34,7 @@ What next?
#include "Poco/Formatter.h"
#include "Poco/PatternFormatter.h"
#include "Poco/AutoPtr.h"
+#include "Poco/Net/HTTPResponse.h"
using Poco::Logger;
using Poco::Channel;
diff --git a/NT/src/rotord.cpp b/NT/src/rotord.cpp
index d1c1e66..983bbe7 100644
--- a/NT/src/rotord.cpp
+++ b/NT/src/rotord.cpp
@@ -41,10 +41,6 @@ HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPS
xmlIO XML; //xml object handles the servers responses
XML.addTag("rotor");
- //can we create a tinyxml object here and pass a pointer to it to the render context?
- //can tinyxml output to a string? is there any reason to use poco instead?
-
-
if (command.size()) {
/*
if (command[0]=="thumbnail") {
@@ -250,7 +246,7 @@ HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPS
if(task->name()==command[0]) {
//valid session command
- /*
+
found=true;
XML.addAttribute("rotor","context",task->name(),0);
XML.pushTag("rotor");
@@ -291,7 +287,7 @@ HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPS
renders[SC.uid]=command[0];
}
}
- */
+
}
}
if (!found) {
diff --git a/NT/src/rotord.h b/NT/src/rotord.h
index 659bb74..c57c6c4 100644
--- a/NT/src/rotord.h
+++ b/NT/src/rotord.h
@@ -73,7 +73,6 @@ using Poco::AutoPtr;
#include "rendercontext.h"
-#include "xmlIO.h"
class RenderContextHandler: public HTTPRequestHandler
{
diff --git a/NT/src/rotord.o b/NT/src/rotord.o
index 3c1187f..e73e551 100644
--- a/NT/src/rotord.o
+++ b/NT/src/rotord.o
Binary files differ