diff options
| -rwxr-xr-x | rotord/libavwrapper_guarded.cpp | 144 | ||||
| -rwxr-xr-x | rotord/libavwrapper_guarded.h | 14 | ||||
| -rw-r--r-- | rotord/rendercontext.cpp | 182 | ||||
| -rwxr-xr-x | rotord/rotor.cpp | 89 | ||||
| -rwxr-xr-x | rotord/rotor.h | 11 |
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; }; } |
