summaryrefslogtreecommitdiff
path: root/rotord/src
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2014-01-30 18:13:45 +0000
committerTim Redfern <tim@eclectronics.org>2014-01-30 18:13:45 +0000
commitc2b62131b0e6984f8fea7f44e364ae5c886c211a (patch)
tree0e6e1502d95a8c9e99fea979f92d2ee12518ecbe /rotord/src
parent5858a7f89d844e3577f6400681bdd47a7bdd8e2c (diff)
making fragmenting exporter
Diffstat (limited to 'rotord/src')
-rw-r--r--rotord/src/graph.cpp169
-rw-r--r--rotord/src/graph.h17
-rw-r--r--rotord/src/rendercontext.cpp2
3 files changed, 154 insertions, 34 deletions
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp
index 7c61c3e..5dd6e0b 100644
--- a/rotord/src/graph.cpp
+++ b/rotord/src/graph.cpp
@@ -124,52 +124,31 @@ bool Graph::video_render(const string &output_filename,const double framerate,in
//
//setup defaults
- std::string container;
- std::string filestub;
+ std::string suffix;
+ std::string namestub;
Poco::StringTokenizer t(output_filename,".");
if (t.count()>1){
- filestub=t[t.count()-2];
- container="."+t[t.count()-1];
+ namestub=t[t.count()-2];
+ suffix="."+t[t.count()-1];
}
else {
- filestub=output_filename;
- container=".mp4";
- }
-
- if (container==".mpd") {
- use_dash=true;
- container=".mp4";
- cerr<<"found mpd, writing "<<filestub<<container<<endl;
+ namestub=output_filename;
+ suffix=".mp4";
}
libav::exporter exporter;
- Image* i;
-
-
- //dash implementation - write into a subfolder
-
- if (use_dash){
- struct stat st = {0};
- if (stat(filestub.c_str(), &st) == -1) {
- if (mkdir(filestub.c_str(), 0700)!=0){
- logger.error("MPEG-DASH output: error creating directory "+filestub);
- return false;
- }
- }
- //directory exists
- //now write the mpd file (for the basic static version)
- }
+ Image *i;
- if (exporter.setup(outW,outH,bitRate,framerate,container,use_fragmentation)) { //codecId,
- if (exporter.record(filestub+container)) {
+ if (exporter.setup(outW,outH,bitRate,framerate,suffix,use_fragmentation)) { //codecId,
+ if (exporter.record(namestub+suffix)) {
libav::audio_decoder audioloader;
bool usingaudio=audioloader.open(audio_filename);
- logger.information("Video_output rendering "+filestub+container+": "+toString(duration)+" seconds at "+toString(framerate)+" fps, audio frame size: "+toString(exporter.get_audio_framesize()));
+ logger.information("Video_output rendering "+namestub+suffix+": "+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
@@ -270,7 +249,7 @@ bool Graph::video_render(const string &output_filename,const double framerate,in
double mtime = ((_end.tv_sec-_start.tv_sec) + (_end.tv_usec-_start.tv_usec)/1000000.0);
- logger.information("Video_output: rendered "+filestub+container+": in "+toString(mtime)+" seconds");
+ logger.information("Video_output: rendered "+namestub+suffix+": in "+toString(mtime)+" seconds");
logger.information("compression codec took "+toString(mtime-video_output->time_taken)+" seconds");
for (auto n:nodes) {
@@ -296,6 +275,132 @@ bool Graph::video_render(const string &output_filename,const double framerate,in
return false;
}
+bool Graph::video_render2(const string &output_filename,const double framerate,int start, int stop) {
+
+ //
+ //rewrite the video render process to:
+ //include the possibility of writing fragmented files into a subdirectory
+ //
+
+ Logger& logger = Logger::get(Log_name);
+
+ if (output_filename.size()==0) {
+ logger.error("ERROR: video render passed empty filename");
+ return false;
+ }
+
+ if (!find_node("video_output")) {
+ logger.error("ERROR: video output node not found");
+ return false;
+ }
+
+ Video_output *video_output=dynamic_cast<Video_output*>(find_node("video_output"));
+
+ //
+ //should text handling and verification happen outside of here?
+ //
+
+ //first seperate path, name and suffix
+ std::string suffix="";
+ std::string path="";
+ std::string namestub="";
+
+ int pathsep=output_filename.find_last_of("/");
+ if (pathsep<output_filename.size()){ // "/" found
+ path=output_filename.substr(0,pathsep+1);
+ namestub=output_filename.substr(pathsep+1,string::npos);
+ }
+ else namestub=output_filename;
+
+ int dotsep=namestub.find_last_of(".");
+ if (dotsep<namestub.size()){ // "/" found
+ suffix=namestub.substr(dotsep,string::npos);
+ namestub=namestub.substr(0,dotsep);
+ }
+ else {
+ suffix=".mp4";
+ }
+
+
+ bool use_dash=false;
+ if (suffix==".mpd") {
+ use_dash=true;
+ suffix=".mp4";
+ }
+
+ //dash implementation - write into a subfolder
+ if (use_dash){
+ struct stat st = {0};
+ if (stat(namestub.c_str(), &st) == -1) {
+ if (mkdir(namestub.c_str(), 0700)!=0){
+ logger.error("MPEG-DASH output: error creating directory "+namestub);
+ return false;
+ }
+ }
+ //directory exists
+ logger.information("beginning mpd, chunk length "+toString(mpd_chunk_length)+" seconds");
+ path+=namestub;
+ //now write the mpd file (for the basic static version)
+ }
+
+ libav::exporter exporter;
+
+ if (!exporter.setup(outW,outH,bitRate,framerate,suffix,use_fragmentation)){
+ logger.error("ERROR: could not open codec for "+suffix);
+ return false;
+ }
+
+ //cerr<<"path= "<<path<<" ,stub= "<<namestub<<" ,suffix= "<<suffix<<endl;
+
+ logger.information("Video_output rendering "+namestub+suffix+": "+toString(duration)+" seconds at "+toString(framerate)+" fps, audio frame size: "+toString(exporter.get_audio_framesize()));
+
+
+ Image *i;
+ libav::audio_decoder audioloader;
+
+ bool usingaudio=false;
+
+ if (audio_filename!=""&&audioloader.open(audio_filename)){
+ video_output->create_envelope(audio_thumb->audiodata);
+ }
+
+ //time render
+ struct timeval _start, _end;
+ gettimeofday(&_start, NULL);
+ uint16_t *audioframe=nullptr;
+ uint16_t *audio=nullptr;
+ int samples_in_frame;
+
+ for (auto n:nodes) n.second->reset();
+
+ if (usingaudio){
+ samples_in_frame=(audioloader.get_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.get_sample_rate())+" hz");
+ audioframe=new uint16_t[(samples_in_frame+exporter.get_audio_framesize())*audioloader.get_number_channels()];
+ audio=new uint16_t[samples_in_frame*audioloader.get_number_channels()];
+ }
+
+ double vstep=1.0/framerate;
+ double vf=start*vstep;
+ double af=start*vstep;
+ int aoffs=0;
+ int audioend=0;
+ Audio_frame *a;
+ int64_t sample_start=(start*audioloader.get_sample_rate())/framerate;
+
+ double end=duration;
+ if (use_dash) end=vf+mpd_chunk_length;
+
+ while (vf<min(duration,stop*vstep)&&!cancelled){
+
+ vf+=vstep;
+ progress=vf/duration;
+ //end+=
+ }
+
+}
+
bool Graph::set_resolution(int w,int h){
if (w>64&&h>48){
outW=w;
diff --git a/rotord/src/graph.h b/rotord/src/graph.h
index bb8f83f..bfd175b 100644
--- a/rotord/src/graph.h
+++ b/rotord/src/graph.h
@@ -25,7 +25,19 @@ copy nodes `
namespace Rotor {
class Graph{
public:
- Graph(){duration=20.0;loaded = false;audio_loaded=false;bitRate=0;outW=640;outH=360;audio_thumb=new Audio_thumbnailer();use_fragmentation=false;analysis_seed=0;Log_name="";};
+ Graph(){
+ duration=20.0;
+ loaded = false;
+ audio_loaded=false;
+ bitRate=0;
+ outW=640;
+ outH=360;
+ audio_thumb=new Audio_thumbnailer();
+ use_fragmentation=false;
+ analysis_seed=0;
+ Log_name="";
+ mpd_chunk_length=2.0;
+ };
Graph(const string& _uid,const string& _desc){
Graph();
init(_uid,_desc);
@@ -53,6 +65,7 @@ namespace Rotor {
Node* find_node(const string &type);
bool signal_render(xmlIO &XML,const string &node,const double framerate);
bool video_render(const string &output_filename,const double framerate,int start, int end);
+ bool video_render2(const string &output_filename,const double framerate,int start, int end);
bool load(string data,string media_path);
bool loadFile(string &filename,string media_path);
bool parseXml(string media_path);
@@ -102,6 +115,8 @@ namespace Rotor {
int analysis_seed;
string Log_name;
+ double mpd_chunk_length;
+
};
class Thumbnailer{
public:
diff --git a/rotord/src/rendercontext.cpp b/rotord/src/rendercontext.cpp
index 813573b..39f9c9b 100644
--- a/rotord/src/rendercontext.cpp
+++ b/rotord/src/rendercontext.cpp
@@ -36,7 +36,7 @@ void Render_context::runTask() {
if(cmd.task==RENDER) {
state=RENDERING;
renders[cmd.uid]=Render_status(RENDERING);
- if(graph.video_render(output_filename,output_framerate,start,stop)){
+ if(graph.video_render2(output_filename,output_framerate,start,stop)){
state=IDLE;
if (graph.cancelled) renders[cmd.uid].status=CANCELLED;
else renders[cmd.uid].status=RENDER_READY;