summaryrefslogtreecommitdiff
path: root/rotord/libavwrapper.cpp
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-05-27 17:22:16 +0100
committerTim Redfern <tim@eclectronics.org>2013-05-27 17:22:16 +0100
commit14f3d350aa7c9abfd8bc394e87177d3f9e6b8d87 (patch)
tree0c6475fc6d320fbd1f718fd8eee5a5d87c67bfa7 /rotord/libavwrapper.cpp
parent12c7449bd73a49ede4dacb90a9b0b7f73eb2e287 (diff)
adding audio output to avwrapper
Diffstat (limited to 'rotord/libavwrapper.cpp')
-rwxr-xr-xrotord/libavwrapper.cpp83
1 files changed, 77 insertions, 6 deletions
diff --git a/rotord/libavwrapper.cpp b/rotord/libavwrapper.cpp
index 5cff8c9..1fe054e 100755
--- a/rotord/libavwrapper.cpp
+++ b/rotord/libavwrapper.cpp
@@ -368,7 +368,7 @@ bool libav::decoder::fetchFrame(int targetFrameIndex)
if (response < 0)
return false;
if (response!=targetFrameIndex){
- cerr<<"libav::decoder asked for "<<targetFrameIndex<<", got "<<response<<endl;
+ cerr<<"libav::decoder asked for "<<targetFrameIndex<<", got "<<response<<endl; //does not seem to be aware of wrong frame
}
}
previousFrameIndex = targetFrameIndex;
@@ -386,10 +386,10 @@ int libav::decoder::seekToFrame(int targetFrameIndex)
}
int result = avformat_seek_file( container, //format context
videoStream,//stream id
- 0, //min timestamp
+ 0, //min timestamp 0?
ts, //target timestamp
ts, //max timestamp
- 0); //AVSEEK_FLAG_ANY),//flags
+ 0);//flags AVSEEK_FLAG_ANY //doesn't seem to work great
if (result < 0)
return -1;
@@ -546,11 +546,14 @@ bool libav::decoder::b_is_one_time_inited = false;
///////////////////////////
-libav::encoder::encoder(const char * file_name, int width, int height, enum AVCodecID codec_id)
+libav::encoder::encoder(const char * file_name, int width, int height, float _framerate,enum AVCodecID codec_id)
: picture_yuv(NULL)
, picture_rgb(NULL)
, container(NULL)
{
+ //multiply float seconds by this to get pts
+ timebase=((float)AV_TIME_BASE_Q.den)/(AV_TIME_BASE_Q.num*_framerate*3.125f); //no idea where the 3.125 comes from
+
if (0 != (width % 2))
cerr << "WARNING: Video width is not a multiple of 2" << endl;
if (0 != (height % 2))
@@ -605,7 +608,7 @@ libav::encoder::encoder(const char * file_name, int width, int height, enum AVCo
// TODO
}
- pCtx->time_base = (AVRational){1, 25};
+ pCtx->time_base = (AVRational){1, 25}; /////TODO FIX TO SUPPORT OTHER RATES
// pCtx->time_base = (AVRational){1, 10};
pCtx->gop_size = 12; // emit one intra frame every twelve frames
// pCtx->max_b_frames = 0;
@@ -679,6 +682,27 @@ libav::encoder::encoder(const char * file_name, int width, int height, enum AVCo
SWS_BICUBIC,NULL,NULL,NULL)) )
throw std::runtime_error("");
+//
+//
+// added audio init
+ AVCodec * acodec = avcodec_find_encoder(AV_CODEC_ID_AAC);
+ int ret = avcodec_open2(pCtx, acodec, NULL);
+ if (ret < 0) {
+ throw std::runtime_error("Could not open audio codec:");
+
+ }
+
+ if (pCtx->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?
+
+ audiostep=((float)audio_input_frame_size)/(pCtx->sample_rate);
+
+
+// are we supposed to use the same codeccontext?
+//
+
/* open the output file */
if (!(fmt->flags & AVFMT_NOFILE))
{
@@ -695,8 +719,10 @@ void libav::encoder::setPixelIntensity(int x, int y, int c, uint8_t value)
*ptr = value;
}
-void libav::encoder::write_frame()
+void libav::encoder::write_frame(float seconds,uint8_t *rgbdata)
{
+ picture_rgb->data[0]=rgbdata;
+
// convert from RGB24 to YUV
sws_scale(Sctx, // sws context
picture_rgb->data, // src slice
@@ -713,6 +739,11 @@ void libav::encoder::write_frame()
packet.data = NULL;
packet.size = 0;
+ //no time stamps as is
+ //http://dranger.com/ffmpeg/tutorial07.html
+
+ picture_yuv->pts=(uint64_t)(seconds*timebase);
+
int got_packet;
int ret = avcodec_encode_video2(pCtx,
&packet,
@@ -727,6 +758,46 @@ void libav::encoder::write_frame()
av_destruct_packet(&packet);
}
}
+void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
+ audio_frame = avcodec_alloc_frame();
+ AVPacket pkt = { 0 }; // data and size must be 0;
+ int got_packet, ret;
+ 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;
+ if (audiodata) {
+ sampleptr=(uint8_t*)audiodata;
+ }
+ else {
+ sampleptr=new uint8_t[bufsize];
+ memset(sampleptr,0,bufsize);
+ }
+
+ avcodec_fill_audio_frame(audio_frame, pCtx->channels, pCtx->sample_fmt,
+ sampleptr,
+ audio_input_frame_size *
+ av_get_bytes_per_sample(pCtx->sample_fmt) *
+ pCtx->channels, 0); //;
+
+ audio_frame->pts=(uint64_t)(seconds*timebase);
+
+ ret = avcodec_encode_audio2(pCtx, &pkt, audio_frame, &got_packet);
+ if (!audiodata) {
+ delete[] sampleptr;
+ }
+ if (ret < 0) {
+ throw std::runtime_error("Audio encoding failed");
+ }
+
+ if (!got_packet)
+ return;
+
+ // ? pkt.stream_index = st->index;
+
+ ret = av_interleaved_write_frame(container, &pkt);
+ avcodec_free_frame(&audio_frame);
+}
/* virtual */
libav::encoder::~encoder()