summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xrotord/libavwrapper_guarded.cpp144
-rwxr-xr-xrotord/libavwrapper_guarded.h14
-rw-r--r--rotord/rendercontext.cpp182
-rwxr-xr-xrotord/rotor.cpp89
-rwxr-xr-xrotord/rotor.h11
5 files changed, 196 insertions, 244 deletions
diff --git a/rotord/libavwrapper_guarded.cpp b/rotord/libavwrapper_guarded.cpp
index 8e40145..829a07f 100755
--- a/rotord/libavwrapper_guarded.cpp
+++ b/rotord/libavwrapper_guarded.cpp
@@ -61,7 +61,7 @@ int readFunction(void* opaque, uint8_t* buf, int buf_size)
{
//QIODevice* stream = (QIODevice*)opaque;
ifstream* stream = (ifstream*)opaque;
- //int numBytes =
+ //int numBytes =
stream->read((char*)buf, (streamsize)buf_size);
return stream->gcount(); //?? is this right
//numBytes; //TODO work out
@@ -159,9 +159,7 @@ decoder::decoder(QUrl url, PixelFormat pixelFormat)
}
*/
-/* virtual */
-libav::decoder::~decoder()
-{
+void libav::decoder::cleanup(){
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
if (NULL != Sctx) {
@@ -203,8 +201,15 @@ libav::decoder::~decoder()
//if (reply != NULL) {
// reply->deleteLater();
// reply = NULL;
- //}
+ //}
// Don't need to free pCodec?
+
+}
+
+/* virtual */
+libav::decoder::~decoder()
+{
+ cleanup();
}
/*
bool decoder::open(QUrl url, enum PixelFormat formatParam)
@@ -584,7 +589,7 @@ libav::encoder::encoder(const char * file_name, int width, int height, float _fr
fmt->video_codec = codec_id;
// fmt->video_codec = CODEC_ID_H264; // fails to write
- AVStream * video_st = avformat_new_stream(container, NULL);
+ video_st = avformat_new_stream(container, NULL);
pCtx = video_st->codec;
pCtx->codec_id = fmt->video_codec;
@@ -696,19 +701,54 @@ libav::encoder::encoder(const char * file_name, int width, int height, float _fr
//
//
// added audio init
- AVCodec * acodec = avcodec_find_encoder(AV_CODEC_ID_AAC);
- int ret = avcodec_open2(pCtx, acodec, NULL);
+ fmt->audio_codec = AV_CODEC_ID_MP3;
+ // fmt->video_codec = CODEC_ID_H264; // fails to write
+
+ audio_st = avformat_new_stream(container, NULL);
+
+ aCtx = audio_st->codec;
+ aCtx->codec_id = fmt->audio_codec;
+ aCtx->codec_type = AVMEDIA_TYPE_AUDIO;
+
+ aCtx->sample_fmt=AV_SAMPLE_FMT_S16P; //s16p is invalid or not supported by aac: S16 not by mp3
+ aCtx->channels=2;
+ aCtx->sample_rate=44100;
+ aCtx->channel_layout=AV_CH_LAYOUT_STEREO;
+ aCtx->bit_rate = 64000;
+
+
+
+ AVCodec * acodec = avcodec_find_encoder(aCtx->codec_id);
+ mutex.lock();
+ int ret = avcodec_open2(aCtx, acodec, NULL);
+ mutex.unlock();
if (ret < 0) {
throw std::runtime_error("Could not open audio codec:");
-
+
}
- if (pCtx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
+ if (aCtx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
audio_input_frame_size = 10000;
else
- audio_input_frame_size = pCtx->frame_size; //is coming out at 0?
+ audio_input_frame_size = aCtx->frame_size; //is coming out at 0?
+
+ cerr<<"audio codec frame size is "<<audio_input_frame_size<<endl;
+
+ //if (audio_input_frame_size ==0) { can't do this
+ // audio_input_frame_size =10000;
+ //}
+
+ // [mpeg4 @ 0x7f02f00200e0] nb_samples (10000) != frame_size (0) (avcodec_encode_audio2) - quits thread
+ // why is frame size 0?
+ // should there be a seperate pCtx for audio?
+
+ if (container->oformat->flags & AVFMT_GLOBALHEADER)
+ aCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+
+ audiostep=((float)audio_input_frame_size)/(aCtx->sample_rate);
+
- audiostep=((float)audio_input_frame_size)/(pCtx->sample_rate);
// are we supposed to use the same codeccontext?
@@ -716,7 +756,7 @@ libav::encoder::encoder(const char * file_name, int width, int height, float _fr
/* open the output file */
if (!(fmt->flags & AVFMT_NOFILE))
- {
+ {
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
if (avio_open(&container->pb, file_name, AVIO_FLAG_WRITE) < 0)
@@ -747,7 +787,7 @@ void libav::encoder::write_frame(float seconds,uint8_t *rgbdata)
/* encode the image */
// use non-deprecated avcodec_encode_video2(...)
- AVPacket packet;
+ AVPacket packet={0};
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
@@ -755,13 +795,17 @@ void libav::encoder::write_frame(float seconds,uint8_t *rgbdata)
//no time stamps as is
//http://dranger.com/ffmpeg/tutorial07.html
- picture_yuv->pts=(uint64_t)(seconds*timebase);
+ picture_yuv->pts=(uint64_t)(seconds*timebase); //
int got_packet;
int ret = avcodec_encode_video2(pCtx,
&packet,
picture_yuv,
&got_packet);
+
+ //packet.pts=(uint64_t)(seconds*timebase); //added 0606
+ packet.stream_index = video_st->index;; //added 0606
+
if (ret < 0)
throw std::runtime_error("Video encoding failed");
if (got_packet)
@@ -778,7 +822,7 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
av_init_packet(&pkt);
audio_frame->nb_samples = audio_input_frame_size;
uint8_t *sampleptr;
- int bufsize=audio_input_frame_size * av_get_bytes_per_sample(pCtx->sample_fmt) *pCtx->channels;
+ int bufsize=audio_input_frame_size * av_get_bytes_per_sample(aCtx->sample_fmt) *aCtx->channels;
if (audiodata) {
sampleptr=(uint8_t*)audiodata;
}
@@ -787,15 +831,21 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
memset(sampleptr,0,bufsize);
}
- avcodec_fill_audio_frame(audio_frame, pCtx->channels, pCtx->sample_fmt,
+ audio_frame->pts=(uint64_t)(seconds*timebase); //
+
+ avcodec_fill_audio_frame(audio_frame, aCtx->channels, aCtx->sample_fmt,
sampleptr,
audio_input_frame_size *
- av_get_bytes_per_sample(pCtx->sample_fmt) *
- pCtx->channels, 0); //;
+ av_get_bytes_per_sample(aCtx->sample_fmt) *
+ aCtx->channels, 0); //;
+
+
+
+ ret = avcodec_encode_audio2(aCtx, &pkt, audio_frame, &got_packet);
- audio_frame->pts=(uint64_t)(seconds*timebase);
+ pkt.stream_index = audio_st->index; //hardcoded stream index added 0606
+ //pkt.pts=(uint64_t)(seconds*timebase); //added 060613
- ret = avcodec_encode_audio2(pCtx, &pkt, audio_frame, &got_packet);
if (!audiodata) {
delete[] sampleptr;
}
@@ -806,7 +856,7 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
if (!got_packet)
return;
- // ? pkt.stream_index = st->index;
+ // ? pkt.stream_index = st->index;
ret = av_interleaved_write_frame(container, &pkt);
avcodec_free_frame(&audio_frame);
@@ -815,33 +865,43 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
/* virtual */
libav::encoder::~encoder()
{
+
+ //avcodec_flush_buffers(pCtx); ???? from exporter version
+
+
int result = av_write_frame(container, NULL); // flush
result = av_write_trailer(container);
- {
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
avio_close(container->pb);
mutex.unlock();
+
+ //added 0706
+ video_st=nullptr;
+ audio_st=nullptr;
+ //
+
+ for (int i = 0; i < container->nb_streams; ++i) {
+ av_freep(container->streams[i]); //CRASHING HERE ON STREAM 1, OUTPUT IS VALID BUT AUDIO INAUDIBLE - 060613
}
- for (int i = 0; i < container->nb_streams; ++i)
- av_freep(container->streams[i]);
av_free(container);
- container = NULL;
-
- {
+ container = nullptr;
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
+ avcodec_close(aCtx);
avcodec_close(pCtx);
mutex.unlock();
- }
av_free(pCtx);
pCtx = NULL;
+ av_free(aCtx);
+ aCtx=nullptr;
av_free(picture_yuv->data[0]);
av_free(picture_yuv);
picture_yuv = NULL;
av_free(picture_rgb->data[0]);
av_free(picture_rgb);
picture_rgb = NULL;
+
}
bool libav::exporter::setup(int w,int h, int bitRate, int frameRate, std::string container){
@@ -875,6 +935,8 @@ bool libav::exporter::record(std::string filename){
video_st = NULL;
audio_st = NULL;
+ fmt->video_codec=AV_CODEC_ID_MPEG4;
+
if (fmt->video_codec != AV_CODEC_ID_NONE) {
video_st = add_stream(oc, &video_codec, fmt->video_codec);
}
@@ -1007,7 +1069,7 @@ void libav::exporter::finishRecord(){
close_audio(oc, audio_st);
if (!(fmt->flags & AVFMT_NOFILE)) {
- // Close the output file. //
+ // Close the output file. //
mutex.lock();
avio_close(oc->pb);
mutex.unlock();
@@ -1102,6 +1164,7 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
// allocate and init a re-usable frame //
frame = avcodec_alloc_frame();
+ // moved to constructor and freeing in destructor -- stills crashes the same
if (!frame) {
//fprintf(stderr, "Could not allocate video frame\n");
exit(1);
@@ -1192,7 +1255,7 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
sampleptr=new uint8_t[bufsize];
memset(sampleptr,0,bufsize);
}
-
+
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
sampleptr,
audio_input_frame_size *
@@ -1351,6 +1414,10 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
av_init_packet(&pkt);
// encode the image //
+
+ // 2nd time you render it crashes right after here
+
+ // where the hell is frame being allocated? is the problem caused by it being freed? (see removeal of avframe_free in cleanup)
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
//fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
@@ -1388,7 +1455,10 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
avcodec_close(st->codec);
av_free(src_picture.data[0]);
av_free(dst_picture.data[0]);
- av_free(frame);
+ av_free(frame); //removed to explore crash 2nd time render
+ //gives *** Error in `./rotord': corrupted double-linked list: 0x00007fd8b005bd60 ***
+ //where is frame initialised???
+ //moved to destructor
av_free(outPixels); //SIGSEV here???
mutex.unlock();
}
@@ -1450,7 +1520,7 @@ bool libav::audioloader::setup(const std::string &filename){
mutex.lock();
if (codecContext->codec == NULL)
{
-
+
av_free(frame);
avformat_close_input(&formatContext);
std::cout << "Couldn't find a proper decoder" << std::endl;
@@ -1458,7 +1528,7 @@ bool libav::audioloader::setup(const std::string &filename){
}
else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
{
-
+
av_free(frame);
avformat_close_input(&formatContext);
mutex.lock();
@@ -1609,6 +1679,8 @@ bool libav::audioloader::close() {
avcodec_close(codecContext);
avformat_close_input(&formatContext);
mutex.unlock();
-
+ ready=false;
+ sample_start=0;
+ sample_end=0;
return true;
-} \ No newline at end of file
+}
diff --git a/rotord/libavwrapper_guarded.h b/rotord/libavwrapper_guarded.h
index f38d407..646f23c 100755
--- a/rotord/libavwrapper_guarded.h
+++ b/rotord/libavwrapper_guarded.h
@@ -25,6 +25,10 @@
//*** Error in `./rotord': double free or corruption (out): 0x00007f3bf8210080 ***
///////////////////////
+
+//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
+//great to use c++11 features
+
#ifndef UINT64_C
#define UINT64_C(c) (c ## ULL)
#endif
@@ -86,6 +90,7 @@ namespace libav {
decoder(PixelFormat pixelFormat=PIX_FMT_RGB24);
//decoder(QUrl url, PixelFormat pixelFormat=PIX_FMT_RGB24);
+ void cleanup();
virtual ~decoder();
//bool open(QUrl url, enum PixelFormat formatParam = PIX_FMT_RGB24);
//bool open(QIODevice& fileStream, QString& fileName, enum PixelFormat formatParam = PIX_FMT_RGB24);
@@ -151,7 +156,7 @@ namespace libav {
public:
//typedef encoder::Channel Channel;
- encoder(const char * file_name, int width, int height, float _framerate=25.0f, enum AVCodecID codec_id = CODEC_ID_MPEG4);
+ encoder(const char * file_name, int width, int height, float _framerate=25.0f, enum AVCodecID codec_id = CODEC_ID_H264);
virtual ~encoder();
void setPixelIntensity(int x, int y, int c, uint8_t value);
void write_frame(float seconds,uint8_t *rgbdata);
@@ -168,6 +173,10 @@ namespace libav {
float timebase;
struct SwsContext *Sctx;
+ AVStream *audio_st;
+ AVStream *video_st;
+
+ AVCodecContext *aCtx;
int audio_input_frame_size;
float audiostep;
};
@@ -243,6 +252,7 @@ namespace libav {
AVCodecContext* codecContext;
AVFormatContext* formatContext;
+ int channels; //necessary to handle final packet -- unititialised after load/ problem?
private:
std::vector<uint16_t> buffer;
AVFrame* frame;
@@ -252,7 +262,7 @@ namespace libav {
AVPacket packet;
int sample_end;
int sample_start;
- int channels; //necessary to handle final packet
+
};
}
diff --git a/rotord/rendercontext.cpp b/rotord/rendercontext.cpp
index 9e6d958..422ef08 100644
--- a/rotord/rendercontext.cpp
+++ b/rotord/rendercontext.cpp
@@ -269,190 +269,54 @@ Command_response Render_context::session_command(const std::vector<std::string>&
}
return response;
}
-/*
-//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
-//great to use c++11 features
-bool Render_context::load_audio(const string &filename,vector<Base_audio_processor*> processors){
-
- audioloader.setup(filename);
-
- av_dump_format(audioloader.formatContext, 0, 0, false); //avformat.h line 1256
- int samples = ((audioloader.formatContext->duration + 5000)*audioloader.codecContext->sample_rate)/AV_TIME_BASE;
- graph.duration=((float)audioloader.formatContext->duration)/AV_TIME_BASE;
-
-
- for (auto p: processors) {
- if(!p->init(audioloader.codecContext->channels,audioloader.codecContext->bits_per_raw_sample,samples,audioloader.codecContext->sample_rate) ){
- cerr<<"Plugin failed to initialse"<<endl;
- return false;
- }
- }
- return true;
-}
-*/
bool Render_context::load_audio(const string &filename,vector<Base_audio_processor*> processors){
+
+ cerr<<"Rotor: starting audio analysis"<<endl;
+
+ libav::audioloader loader;
+ loader.setup(filename);
- av_register_all();
-
- AVFrame* frame = avcodec_alloc_frame();
- if (!frame)
- {
- std::cout << "Error allocating the frame" << std::endl;
- return false;
- }
-
- AVFormatContext* formatContext = NULL;
- if (avformat_open_input(&formatContext, filename.c_str(), NULL, NULL) != 0)
- {
- av_free(frame);
- std::cout << "Error opening the file" << std::endl;
- return false;
- }
-
-
- if (avformat_find_stream_info(formatContext, NULL) < 0)
- {
- av_free(frame);
- avformat_close_input(&formatContext);
- std::cout << "Error finding the stream info" << std::endl;
- return false;
- }
+ graph.duration=((float)loader.formatContext->duration)/AV_TIME_BASE;
- AVStream* audioStream = NULL;
- for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
- {
- if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- {
- audioStream = formatContext->streams[i];
- break;
- }
- }
-
- if (audioStream == NULL)
- {
- av_free(frame);
- avformat_close_input(&formatContext);
- std::cout << "Could not find any audio stream in the file" << std::endl;
- return false;
- }
-
- AVCodecContext* codecContext = audioStream->codec;
-
- codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
- if (codecContext->codec == NULL)
- {
- av_free(frame);
- 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);
- avformat_close_input(&formatContext);
- std::cout << "Couldn't open the context with the decoder" << std::endl;
- return false;
- }
-
- av_dump_format(formatContext, 0, 0, false); //avformat.h line 1256
- int samples = ((formatContext->duration + 5000)*codecContext->sample_rate)/AV_TIME_BASE;
- graph.duration=((float)formatContext->duration)/AV_TIME_BASE;
-
- std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<<samples <<" samples" << std::endl;
- std::cout << "The data is in format " <<codecContext->sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ")"<<std::endl;
- //std::cout << "Decoding to format " <<frame->format<< " at "<<frame->sample_rate<<" Hz"<<std::endl;
-
- //frame->sample_rate=codecContext->sample_rate;
+ 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(codecContext->channels,16,samples,codecContext->sample_rate) ){
+ if(!p->init(channels,bits,samples,rate) ){
cerr<<"Plugin failed to initialse"<<endl;
return false;
}
}
- AVPacket packet;
- av_init_packet(&packet);
+ AVFrame* frame=loader.get_frame();
int sample_processed=0;
- while (true)
+ while (frame)
{
- int ret=av_read_frame(formatContext, &packet);
- if (ret<0) {
- cerr << "finished with code "<<ret <<(ret==AVERROR_EOF?" ,EOF":"")<<endl;
- break;
+ //now we can pass the data to the processor(s)
+ for (auto p: processors) {
+ p->process_frame(frame->data[0],frame->nb_samples);
}
- if (packet.stream_index == audioStream->index)
- {
- // Try to decode the packet into a frame
- int frameFinished = 0;
- //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
- if (frameFinished)
- {
- // frame now has usable audio data in it. How it's stored in the frame depends on the format of
- // the audio. If it's packed audio, all the data will be in frame->data[0]. If it's in planar format,
- // the data will be in frame->data and possibly frame->extended_data. Look at frame->data, frame->nb_samples,
- // frame->linesize, and other related fields on the FFmpeg docs. I don't know how you're actually using
- // the audio data, so I won't add any junk here that might confuse you. Typically, if I want to find
- // documentation on an FFmpeg structure or function, I just type "<name> doxygen" into google (like
- // "AVFrame doxygen" for AVFrame's docs)
-
- //av_get_channel_layout_string (char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
+ sample_processed+=frame->nb_samples;
+ //mutex.lock();
+ progress=((float)sample_processed)/samples;
+ //mutex.unlock();
-
- //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;
- //mutex.unlock();
- }
- }
- // You *must* call av_free_packet() after each call to av_read_frame() or else you'll leak memory
- av_free_packet(&packet);
+ frame=loader.get_frame();
}
- // Some codecs will cause frames to be buffered up in the decoding process. If the CODEC_CAP_DELAY flag
- // is set, there can be buffered up frames that need to be flushed, so we'll do that
- if (codecContext->codec->capabilities & CODEC_CAP_DELAY)
- {
- av_init_packet(&packet);
- // Decode all the remaining frames in the buffer, until the end is reached
- int frameFinished = 0;
- int bytes = avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
- while (bytes >= 0 && frameFinished)
- {
- for (auto p: processors) {
- p->process_frame(frame->data[0],frame->nb_samples);
- }
- //mutex.lock();
- progress=((double)sample_processed)/samples;
- //mutex.unlock();
- }
- }
-
- cerr << "finished processing: "<<sample_processed << " samples of "<<samples<<", "<<((double)sample_processed*100)/samples<<"%"<< std::endl;
+ loader.close();
- // Clean up!
for (auto p: processors) {
p->cleanup();
p->print_summary();
}
-
- av_free(frame);
- avcodec_close(codecContext);
- avformat_close_input(&formatContext);
-
- return true;
+ cerr<<"Rotor: finished audio analysis"<<endl;
}
bool Render_context::load_video(const string &nodeID,const string &filename){
//this is a good standard example of how to find
diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp
index e38e8d3..da5614a 100755
--- a/rotord/rotor.cpp
+++ b/rotord/rotor.cpp
@@ -177,9 +177,9 @@ void Audio_analysis::print_features(){
}
cerr<<endl;
}
-
/*
-bool Video_output::render_encoder(const float duration, const float framerate,const string &output_filename,const string &audio_filename,float& progress){
+
+bool Video_output::render(const float duration, const float framerate,const string &output_filename,const string &audio_filename,float& progress){
//
//setup defaults
@@ -208,15 +208,17 @@ bool Video_output::render_encoder(const float duration, const float framerate,co
float vf=0.0f;
float af=0.0f;
while (vf<duration-vstep) {
- while (!fless(af,vf)) {
- //insert audio frames until we are ahead of the video
- //exporter->encodeFrame(audioloader.get_samples(exporter->get_audio_framesize()));
- //af+=exporter->get_audio_step();
- uint16_t *s=audioloader.get_samples(encoder.get_audio_framesize());
- encoder.write_frame(af,s); //crashes
- af+=encoder.get_audio_step();
- }
-
+ if (usingaudio) {
+ while (!fless(af,vf)) {
+ //insert audio frames until we are ahead of the video
+ //exporter->encodeFrame(audioloader.get_samples(exporter->get_audio_framesize()));
+ //af+=exporter->get_audio_step();
+ int fs=encoder.get_audio_framesize();
+ uint16_t *s=audioloader.get_samples(fs);
+ encoder.write_frame(af,s); //crashes - s seems to be 0x00
+ af+=encoder.get_audio_step();
+ }
+ }
Image* i=get_output(Frame_spec(vf,framerate,duration,outW,outH));
if (i) {
//exporter->encodeFrame(i->RGBdata);
@@ -234,7 +236,7 @@ bool Video_output::render_encoder(const float duration, const float framerate,co
// }
//}
- return false;
+ //return false;
}
*/
@@ -247,17 +249,22 @@ bool Video_output::render(const float duration, const float framerate,const stri
int bitRate=4000000;
int frameRate=25;
AVCodecID codecId=AV_CODEC_ID_H264; //MPEG4;
- std::string container ="mov";
+ std::string container ="mp4";
- bool usingaudio=audioloader.setup(audio_filename);
- //at the moment it crashes if you render before audio is loaded
+
+ //at the moment it crashes if you render before audio is loaded and also on 2nd render
+ libav::exporter exporter;
float spct=100.0f/duration;
- if (exporter->setup(outW,outH,bitRate,frameRate,container)) { //codecId,
- if (exporter->record(output_filename)) {
+ if (exporter.setup(outW,outH,bitRate,frameRate,container)) { //codecId,
+ if (exporter.record(output_filename)) {
+
+ libav::audioloader audioloader;
- cerr << "Rotor: Video_output rendering " << duration << " seconds at " << framerate << " fps, audio frame size: " << exporter->get_audio_framesize()<<endl;
+ bool usingaudio=audioloader.setup(audio_filename);
+
+ cerr << "Rotor: Video_output rendering " << duration << " seconds at " << framerate << " fps, audio frame size: " << exporter.get_audio_framesize()<<endl;
//25fps video and 43.06640625fps audio? hmm
//how to get the timecodes correct for the interleaved files
@@ -266,44 +273,44 @@ bool Video_output::render(const float duration, const float framerate,const stri
float vf=0.0f;
float af=0.0f;
while (vf<duration){ //-vstep) {
- while (!fless(af,vf)) {
- //insert audio frames until we are ahead of the video
- exporter->encodeFrame(audioloader.get_samples(exporter->get_audio_framesize()));
- af+=exporter->get_audio_step();
-
- }
-
- /*
- [mp3 @ 0x7fffe40330e0] max_analyze_duration 5000000 reached at 5015510 microseconds
- [mp3 @ 0x7fffe4033ec0] Insufficient thread locking around avcodec_open/close()
- [mp3 @ 0x7fffe40330e0] Estimating duration from bitrate, this may be inaccurate
- [libx264 @ 0x7fffe8003940] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2
- [libx264 @ 0x7fffe8003940] profile High, level 3.0
- [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
- */
+ if (usingaudio) {
+ while (!fless(af,vf)) {
+ //insert audio frames until we are ahead of the video
+ exporter.encodeFrame(audioloader.get_samples(exporter.get_audio_framesize()));
+ af+=exporter.get_audio_step();
+
+ }
+ }
+
+
+ //[mp3 @ 0x7fffe40330e0] max_analyze_duration 5000000 reached at 5015510 microseconds
+ //[mp3 @ 0x7fffe4033ec0] Insufficient thread locking around avcodec_open/close()
+ //[mp3 @ 0x7fffe40330e0] Estimating duration from bitrate, this may be inaccurate
+ //[libx264 @ 0x7fffe8003940] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2
+ //[libx264 @ 0x7fffe8003940] profile High, level 3.0
+ //[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
+
Image* i=get_output(Frame_spec(vf,framerate,duration,outW,outH));
if (i) {
- exporter->encodeFrame(i->RGBdata);
+ exporter.encodeFrame(i->RGBdata);
}
vf+=vstep;
progress=vf/duration;
}
- exporter->finishRecord();
+ exporter.finishRecord();
cerr << "Rotor: Video_output finished "<< endl;
- audioloader.close();
+ if (usingaudio) audioloader.close();
return true;
}
}
- audioloader.close();
-
return false;
}
@@ -324,6 +331,10 @@ bool Video_loader::load(const string &filename){
return true;
}
*/
+ if (isLoaded) {
+ player.cleanup(); ///should be in decoder class?
+ isLoaded=false;
+ }
Poco::Path path;
string uri="file://"+filename;
isLoaded=player.open(uri);
diff --git a/rotord/rotor.h b/rotord/rotor.h
index 7ebde45..a0a310f 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -685,9 +685,8 @@ namespace Rotor {
Video_output(){};
Video_output(map<string,string> &settings) {
base_settings(settings);
- exporter=new libav::exporter();
};
- ~Video_output(){ delete exporter; };
+ ~Video_output(){ };
Image *output(const Frame_spec &frame){
if (image_inputs[0]->connection) {
return ((Image_node*)(image_inputs[0]->connection))->get_output(frame);
@@ -698,10 +697,7 @@ namespace Rotor {
bool render(const float duration, const float framerate,const string &output_filename,const string &audio_filename,float& progress);
private:
- //ofxMovieExporter *exporter;
- libav::exporter *exporter;
- libav::audioloader audioloader;
- //libav::encoder encoder;
+
};
class Video_loader: public Image_node {
public:
@@ -1162,6 +1158,7 @@ namespace Rotor {
void cancel(); //interrupt locking process
int make_preview(int nodeID, float time); //starts a frame preview - returns status code - how to retrieve?
bool load_audio(const string &filename,vector<Base_audio_processor*> processors);
+ bool _load_audio(const string &filename,vector<Base_audio_processor*> processors);
Render_requirements get_requirements();
bool load_video(const string &nodeID,const string &filename);//can be performance or clip
private:
@@ -1177,13 +1174,11 @@ namespace Rotor {
std::string output_dir;
Audio_thumbnailer *audio_thumb;
- //vampHost::QMAnalyser audio_analyser;
Graph graph;
Node_factory factory;
float output_framerate;
bool audio_loaded;
- //libav::audioloader audioloader;
};
}