summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2013-04-22 19:21:42 +0100
committerComment <tim@gray.(none)>2013-04-22 19:21:42 +0100
commit4b3aad507aaf75263f5b8c719768b24ba688c31e (patch)
tree602d4d2dc89d3e39c5b76d112452e0249d3ab7f5
parentb05e391e126f2bba2a4bd2915786d93731d2dbc9 (diff)
audio output corruption
-rw-r--r--rotord/libavaudioloader.cpp61
-rw-r--r--rotord/libavaudioloader.h21
-rw-r--r--rotord/libavexporter.cpp19
-rw-r--r--rotord/libavexporter.h24
-rwxr-xr-xrotord/rotor.cpp4
-rwxr-xr-xrotord/rotor.h6
-rw-r--r--rotord/rotord.cbp2
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" />