From 4b3aad507aaf75263f5b8c719768b24ba688c31e Mon Sep 17 00:00:00 2001 From: Comment Date: Mon, 22 Apr 2013 19:21:42 +0100 Subject: audio output corruption --- rotord/libavaudioloader.cpp | 61 +++++++++++++++++++++++++++++++++++++-------- rotord/libavaudioloader.h | 21 +++++----------- rotord/libavexporter.cpp | 19 ++++++-------- rotord/libavexporter.h | 24 +++++++++++++++--- rotord/rotor.cpp | 4 +-- rotord/rotor.h | 6 ++--- rotord/rotord.cbp | 2 ++ 7 files changed, 92 insertions(+), 45 deletions(-) diff --git a/rotord/libavaudioloader.cpp b/rotord/libavaudioloader.cpp index 8a2d81a..133fcd4 100644 --- a/rotord/libavaudioloader.cpp +++ b/rotord/libavaudioloader.cpp @@ -1,6 +1,6 @@ #include "libavaudioloader.h" -bool libav::audioloader::setup(const std::string &filename){ +bool libav::Audioloader::setup(const std::string &filename){ av_register_all(); @@ -65,16 +65,16 @@ bool libav::audioloader::setup(const std::string &filename){ av_dump_format(formatContext, 0, 0, false); //avformat.h line 1256 int samples = ((formatContext->duration + 5000)*codecContext->sample_rate)/AV_TIME_BASE; - + std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ") "<0){ + for (int i=0;ichannels;j++) { + buffer[(i*frame->channels)+j]=buffer[((sample_start+i)*frame->channels)+j]; + } + } + sample_start=sample_end-sample_start; + } + sample_end=sample_start; + while (sample_endnb_samples)*frame->channels)>buffer.size()){ + buffer.reserve((sample_end+frame->nb_samples)*frame->channels); + } + if (!frame) { + for (int i=0;ichannels;i++){ + buffer[sample_end+i]=0; + } - return true; - } \ No newline at end of file + } + for (int i=0;inb_samples;i++) { + for (int j=0;jchannels;j++) { + buffer[((sample_end+i)*frame->channels)+j]= ((uint16_t*) frame->buf[0])[(i*frame->channels)+j]; + } + } + sample_end+=frame->nb_samples; + //avcodec_free_frame(&frame); + } + if (sample_end>num) { + sample_start=num; + } + else { + sample_start=0; + } + return (uint16_t*)(&buffer[0]); +} + +bool libav::Audioloader::close() { + av_free(frame); + avcodec_close(codecContext); + avformat_close_input(&formatContext); + + return true; +} diff --git a/rotord/libavaudioloader.h b/rotord/libavaudioloader.h index bacd6a9..5df583b 100644 --- a/rotord/libavaudioloader.h +++ b/rotord/libavaudioloader.h @@ -3,6 +3,7 @@ #include #include #include +#include extern "C" { #include @@ -12,32 +13,22 @@ extern "C" { namespace libav { - class audioloader{ + class Audioloader{ public: - audioloader(){ready=false;sample_start=0;}; + Audioloader(){ready=false;sample_start=0;sample_end=0;}; bool setup(const std::string &filename); AVFrame* get_frame(); - uint16_t* get_samples(int num){ - if(!ready) return nullptr; - if (sample_start>0){ - - } - while (i buffer; AVFrame* frame; AVFormatContext* formatContext; AVStream* audioStream; AVCodecContext* codecContext; AVPacket packet; - int sample_processed; + int sample_end; int sample_start; }; diff --git a/rotord/libavexporter.cpp b/rotord/libavexporter.cpp index 3e977a1..ed69cec 100644 --- a/rotord/libavexporter.cpp +++ b/rotord/libavexporter.cpp @@ -1,6 +1,7 @@ #include "libavexporter.h" -bool libav::exporter::setup(int w,int h, int bitRate, int frameRate, std::string container){ + +bool libav::Exporter::setup(int w,int h, int bitRate, int frameRate, std::string container){ // Initialize libavcodec, and register all codecs and formats. // av_register_all(); @@ -13,7 +14,7 @@ bool libav::exporter::setup(int w,int h, int bitRate, int frameRate, std::string return true; } -bool libav::exporter::record(std::string filename){ +bool libav::Exporter::record(std::string filename){ // allocate the output media context // avformat_alloc_output_context2(&oc, NULL, NULL, filename.c_str()); @@ -54,7 +55,9 @@ bool libav::exporter::record(std::string filename){ if (video_st) open_video(oc, video_codec, video_st); if (audio_st) - open_audio(oc, audio_codec, audio_st); + size=open_audio(oc, audio_codec, audio_st); + + std::cerr << "opened audio codec with "<pts.val * audio_st->time_base.num / audio_st->time_base.den; @@ -94,10 +97,6 @@ bool libav::exporter::encodeFrame(unsigned char *pixels){ else video_pts = 0.0; - uint16_t *samples = av_malloc(audio_input_frame_size * - av_get_bytes_per_sample(audio_st->codec->sample_fmt) * - audio_st->codec->channels); //dummy audio - // write interleaved audio and video frames // if (!video_st || (video_st && audio_st && audio_pts < video_pts)) { write_audio_frame(oc, audio_st, samples); @@ -107,14 +106,12 @@ bool libav::exporter::encodeFrame(unsigned char *pixels){ frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base); } - av_free(samples); - //std::cerr << "encoded frame " << outputframe << std::endl; outputframe++; return true; } -void libav::exporter::finishRecord(){ +void libav::Exporter::finishRecord(){ av_write_trailer(oc); // Close each codec. // diff --git a/rotord/libavexporter.h b/rotord/libavexporter.h index df28c90..9ff72d7 100644 --- a/rotord/libavexporter.h +++ b/rotord/libavexporter.h @@ -133,7 +133,7 @@ namespace libav { // audio output // - static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st) + static int open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st) { AVCodecContext *c; int ret; @@ -167,6 +167,7 @@ namespace libav { exit(1); } */ + return audio_input_frame_size; } // Prepare a 16 bit dummy audio frame of 'frame_size' samples and @@ -198,13 +199,25 @@ namespace libav { //get_audio_frame(samples, audio_input_frame_size, c->channels); frame->nb_samples = audio_input_frame_size; + uint8_t *sampleptr; + int bufsize=audio_input_frame_size * av_get_bytes_per_sample(c->sample_fmt) *c->channels; + if (samples) { + sampleptr=(uint8_t*)samples; + } + else { + sampleptr=new uint8_t[bufsize]; + memset(sampleptr,0,bufsize); + } avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, - (uint8_t *)samples, + sampleptr, audio_input_frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels, 1); ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet); + if (!samples) { + free(sampleptr); + } if (ret < 0) { //fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret)); exit(1); @@ -399,12 +412,13 @@ namespace libav { //av_free(outPixels); SIGSEV here } - class exporter { + class Exporter { public: bool setup(int w,int h, int bitRate, int frameRate, std::string container); bool record(std::string filename); - bool encodeFrame(unsigned char *pixels); + bool encodeFrame(unsigned char *pixels, uint16_t *samples); void finishRecord(); + int get_audio_framesize(){return size;}; private: AVOutputFormat *fmt; AVFormatContext *oc; @@ -412,6 +426,7 @@ namespace libav { AVCodec *audio_codec, *video_codec; double audio_pts, video_pts; + int size; int w; int h; int bitRate; @@ -419,6 +434,7 @@ namespace libav { std::string container; int outputframe; + }; //************************************************************// diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp index 787b943..a7c15ba 100755 --- a/rotord/rotor.cpp +++ b/rotord/rotor.cpp @@ -771,7 +771,7 @@ bool Video_output::render(const float duration, const float framerate,const stri std::string container ="mov"; std::string input ="01.wav"; - bool usingaudio=audio_loader.setup(input); + bool usingaudio=audioloader.setup(input); if (exporter->setup(outW,outH,bitRate,frameRate,container)) { //codecId, if (exporter->record(output_filename)) { @@ -780,7 +780,7 @@ bool Video_output::render(const float duration, const float framerate,const stri float step=1.0f/framerate; float v=0.0f; for (float f=0.0f;fencodeFrame(get_output(Frame_spec(f,framerate,outW,outH))->RGBdata)){ + if (!exporter->encodeFrame(get_output(Frame_spec(f,framerate,outW,outH))->RGBdata,audioloader.get_samples(exporter->get_audio_framesize()))){ cerr << "Rotor: video output failed"< &settings) { base_settings(settings); - exporter=new libav::exporter(); + exporter=new libav::Exporter(); }; ~Video_output(){ delete exporter; }; Image *get_output(const Frame_spec &frame){ @@ -413,8 +413,8 @@ namespace Rotor { private: //ofxMovieExporter *exporter; - libav::exporter *exporter; - libav::audioloader audio_loader; + libav::Exporter *exporter; + libav::Audioloader audioloader; }; //------------------------------------------------------------------- class Node_factory{ diff --git a/rotord/rotord.cbp b/rotord/rotord.cbp index 76c5b1e..1a45db2 100644 --- a/rotord/rotord.cbp +++ b/rotord/rotord.cbp @@ -50,6 +50,8 @@ + + -- cgit v1.2.3