diff options
| -rw-r--r-- | rotord/libavaudioloader.cpp | 2 | ||||
| -rw-r--r-- | rotord/libavexporter.cpp | 23 | ||||
| -rw-r--r-- | rotord/libavexporter.h | 8 | ||||
| -rwxr-xr-x | rotord/rotor.cpp | 33 |
4 files changed, 53 insertions, 13 deletions
diff --git a/rotord/libavaudioloader.cpp b/rotord/libavaudioloader.cpp index 0987928..03919f0 100644 --- a/rotord/libavaudioloader.cpp +++ b/rotord/libavaudioloader.cpp @@ -180,7 +180,7 @@ uint16_t* libav::Audioloader::get_samples(int num){ //presumes 16bpc here for (int i=0;i<frame->nb_samples;i++) { for (int j=0;j<av_frame_get_channels(frame);j++) { - //buffer[((sample_end+i)*frame->channels)+j]= ((uint16_t*) frame->buf[j]->data)[i]; + buffer[((sample_end+i)*frame->channels)+j]= ((uint16_t*) frame->buf[j]->data)[i]; //temporarily disabled audio as its is SIGSEV with audio from delorentos diff --git a/rotord/libavexporter.cpp b/rotord/libavexporter.cpp index 41238e7..d9faa5b 100644 --- a/rotord/libavexporter.cpp +++ b/rotord/libavexporter.cpp @@ -54,11 +54,14 @@ bool libav::Exporter::record(std::string filename){ // * video codecs and allocate the necessary encode buffers. // if (video_st) open_video(oc, video_codec, video_st); - if (audio_st) - size=open_audio(oc, audio_codec, audio_st); - - std::cerr << "opened audio codec with "<<size<<" frame size"<<std::endl; + if (audio_st) { + audioframesize=open_audio(oc, audio_codec, audio_st); + audiostep=((float)audio_st->r_frame_rate.den)/audio_st->r_frame_rate.num; + audiostep=((float)audioframesize)/44100.0f; //where to get the framesize from????? + std::cerr << "opened audio codec with "<<audioframesize<<" frame size and "<<audiostep<<" seconds per frame"<<std::endl; + } + av_dump_format(oc, 0, filename.c_str(), 1); // open the output file, if needed // @@ -138,6 +141,18 @@ bool libav::Exporter::encodeFrame(unsigned char *pixels,AVPacket *audio){ return true; } +bool libav::Exporter::encodeFrame(unsigned char *pixels){ + video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den; + write_video_frame(oc, video_st, pixels); + frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base); + outputframe++; + return true; +} +bool libav::Exporter::encodeFrame(uint16_t *samples){ + audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den; + write_audio_frame(oc, audio_st, samples); + return true; +} void libav::Exporter::finishRecord(){ av_write_trailer(oc); diff --git a/rotord/libavexporter.h b/rotord/libavexporter.h index 24b656c..d9d6f38 100644 --- a/rotord/libavexporter.h +++ b/rotord/libavexporter.h @@ -481,8 +481,11 @@ namespace libav { bool record(std::string filename); bool encodeFrame(unsigned char *pixels, uint16_t *samples); bool encodeFrame(unsigned char *pixels,AVPacket *audiopkt); + bool encodeFrame(unsigned char *pixels); + bool encodeFrame(uint16_t *samples); void finishRecord(); - int get_audio_framesize(){return size;}; + int get_audio_framesize(){return audioframesize;}; + float get_audio_step(){return audiostep;}; private: AVOutputFormat *fmt; @@ -491,7 +494,8 @@ namespace libav { AVCodec *audio_codec, *video_codec; double audio_pts, video_pts; - int size; + int audioframesize; + float audiostep; int w; int h; int bitRate; diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp index d295c9f..c79a9c7 100755 --- a/rotord/rotor.cpp +++ b/rotord/rotor.cpp @@ -6,6 +6,11 @@ bool fequal(const float u,const float v){ if (abs(u-v)<.001) return true; else return false; }; +bool flessorequal(const float u,const float v){ + //v is less or equal to u + if (u-v>-.001) return true; + else return false; +}; using namespace Rotor; @@ -175,13 +180,28 @@ bool Video_output::render(const float duration, const float framerate,const stri if (exporter->setup(outW,outH,bitRate,frameRate,container)) { //codecId, if (exporter->record(output_filename)) { - cerr << "Rotor: Video_output rendering " << duration << " seconds at " << framerate << " fps" << endl; - float step=1.0f/framerate; + 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 + + float vstep=1.0f/framerate; float v=0.0f; - for (float f=0.0f;f<duration;f+=step) { - uint16_t* s=audioloader.get_samples(exporter->get_audio_framesize()); - Image* i=get_output(Frame_spec(f,framerate,outW,outH)); - if (!exporter->encodeFrame(i->RGBdata,s)){ + float vf=0.0f; + float af=0.0f; + while (vf<duration) { //float f=0.0f;f<duration;f+=step) { + //seems to be that the audio frames have to be a little ahead + //and the frame->pts comes from video + while (flessorequal(vf,af)) { + //insert audio frames until we are ahead of the video + uint16_t* s=audioloader.get_samples(exporter->get_audio_framesize()); + exporter->encodeFrame(s); + af+=exporter->get_audio_step(); + } + Image* i=get_output(Frame_spec(vf,framerate,outW,outH)); + exporter->encodeFrame(i->RGBdata); + vf+=vstep; + /* + if (!exporter->encodeFrame(i->RGBdata)){ //if (!exporter->encodeFrame(get_output(Frame_spec(f,framerate,outW,outH))->RGBdata,audioloader.get_packet())){ cerr << "Rotor: video output failed"<<endl; break; @@ -193,6 +213,7 @@ bool Video_output::render(const float duration, const float framerate,const stri cerr<<"stop here"<<endl; } } + */ } exporter->finishRecord(); cerr << "Rotor: Video_output finished "<< endl; |
