diff options
| author | Comment <tim@gray.(none)> | 2013-04-22 19:21:42 +0100 |
|---|---|---|
| committer | Comment <tim@gray.(none)> | 2013-04-22 19:21:42 +0100 |
| commit | 4b3aad507aaf75263f5b8c719768b24ba688c31e (patch) | |
| tree | 602d4d2dc89d3e39c5b76d112452e0249d3ab7f5 | |
| parent | b05e391e126f2bba2a4bd2915786d93731d2dbc9 (diff) | |
audio output corruption
| -rw-r--r-- | rotord/libavaudioloader.cpp | 61 | ||||
| -rw-r--r-- | rotord/libavaudioloader.h | 21 | ||||
| -rw-r--r-- | rotord/libavexporter.cpp | 19 | ||||
| -rw-r--r-- | rotord/libavexporter.h | 24 | ||||
| -rwxr-xr-x | rotord/rotor.cpp | 4 | ||||
| -rwxr-xr-x | rotord/rotor.h | 6 | ||||
| -rw-r--r-- | 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 "<<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; av_init_packet(&packet); - sample_processed=0; + //sample_processed=0; ready=true; return true; } - AVFrame* libav::audioloader::get_frame() { + AVFrame* libav::Audioloader::get_frame() { if (!ready) return nullptr; @@ -124,10 +124,51 @@ bool libav::audioloader::setup(const std::string &filename){ cerr << "finished processing: "<<sample_processed << " samples of "<<samples<<", "<<((double)sample_processed*100)/samples<<"%"<< std::endl; */ - bool libav::audioloader::close() { - av_free(frame); - avcodec_close(codecContext); - avformat_close_input(&formatContext); +uint16_t* libav::Audioloader::get_samples(int num){ //presumes 16bpc here + //std::cerr << "request "<<num<<" samples: "<<(ready?"ready":"not ready")<<std::endl; + if(!ready) return nullptr; + //shuffle down samples + if (sample_start>0){ + for (int i=0;i<sample_end-sample_start;i++){ + for (int j=0;j<frame->channels;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_end<num) { + frame=get_frame(); + if (((sample_end+frame->nb_samples)*frame->channels)>buffer.size()){ + buffer.reserve((sample_end+frame->nb_samples)*frame->channels); + } + if (!frame) { + for (int i=0;i<num*frame->channels;i++){ + buffer[sample_end+i]=0; + } - return true; - }
\ No newline at end of file + } + for (int i=0;i<frame->nb_samples;i++) { + for (int j=0;j<frame->channels;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 <string> #include <math.h> #include <iostream> +#include <vector> extern "C" { #include <libavutil/mathematics.h> @@ -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<num) { - AVFrame *frame=get_frame(); - if (frame==nullptr) return nullptr; - frame.nb_samples* - - } - } + uint16_t* get_samples(int num); bool close(); bool ready; private: + std::vector<uint16_t> 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 "<<size<<" frame size"<<std::endl; av_dump_format(oc, 0, filename.c_str(), 1); @@ -81,7 +84,7 @@ bool libav::exporter::record(std::string filename){ return true; } -bool libav::exporter::encodeFrame(unsigned char *pixels){ +bool libav::Exporter::encodeFrame(unsigned char *pixels,uint16_t *samples){ // Compute current audio and video time. // if (audio_st) audio_pts = (double)audio_st->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;f<duration;f+=step) { - if (!exporter->encodeFrame(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"<<endl; break; } diff --git a/rotord/rotor.h b/rotord/rotor.h index d27914e..8e04271 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -399,7 +399,7 @@ namespace Rotor { Video_output(){}; Video_output(map<string,string> &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 @@ </Compiler> <Unit filename="Makefile" /> <Unit filename="avCodec.h" /> + <Unit filename="libavaudioloader.cpp" /> + <Unit filename="libavaudioloader.h" /> <Unit filename="libavexporter.cpp" /> <Unit filename="libavexporter.h" /> <Unit filename="ofUtils.cpp" /> |
