summaryrefslogtreecommitdiff
path: root/rotord/libavwrapper_guarded.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/libavwrapper_guarded.cpp')
-rwxr-xr-xrotord/libavwrapper_guarded.cpp144
1 files changed, 108 insertions, 36 deletions
diff --git a/rotord/libavwrapper_guarded.cpp b/rotord/libavwrapper_guarded.cpp
index 8e40145..829a07f 100755
--- a/rotord/libavwrapper_guarded.cpp
+++ b/rotord/libavwrapper_guarded.cpp
@@ -61,7 +61,7 @@ int readFunction(void* opaque, uint8_t* buf, int buf_size)
{
//QIODevice* stream = (QIODevice*)opaque;
ifstream* stream = (ifstream*)opaque;
- //int numBytes =
+ //int numBytes =
stream->read((char*)buf, (streamsize)buf_size);
return stream->gcount(); //?? is this right
//numBytes; //TODO work out
@@ -159,9 +159,7 @@ decoder::decoder(QUrl url, PixelFormat pixelFormat)
}
*/
-/* virtual */
-libav::decoder::~decoder()
-{
+void libav::decoder::cleanup(){
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
if (NULL != Sctx) {
@@ -203,8 +201,15 @@ libav::decoder::~decoder()
//if (reply != NULL) {
// reply->deleteLater();
// reply = NULL;
- //}
+ //}
// Don't need to free pCodec?
+
+}
+
+/* virtual */
+libav::decoder::~decoder()
+{
+ cleanup();
}
/*
bool decoder::open(QUrl url, enum PixelFormat formatParam)
@@ -584,7 +589,7 @@ libav::encoder::encoder(const char * file_name, int width, int height, float _fr
fmt->video_codec = codec_id;
// fmt->video_codec = CODEC_ID_H264; // fails to write
- AVStream * video_st = avformat_new_stream(container, NULL);
+ video_st = avformat_new_stream(container, NULL);
pCtx = video_st->codec;
pCtx->codec_id = fmt->video_codec;
@@ -696,19 +701,54 @@ libav::encoder::encoder(const char * file_name, int width, int height, float _fr
//
//
// added audio init
- AVCodec * acodec = avcodec_find_encoder(AV_CODEC_ID_AAC);
- int ret = avcodec_open2(pCtx, acodec, NULL);
+ fmt->audio_codec = AV_CODEC_ID_MP3;
+ // fmt->video_codec = CODEC_ID_H264; // fails to write
+
+ audio_st = avformat_new_stream(container, NULL);
+
+ aCtx = audio_st->codec;
+ aCtx->codec_id = fmt->audio_codec;
+ aCtx->codec_type = AVMEDIA_TYPE_AUDIO;
+
+ aCtx->sample_fmt=AV_SAMPLE_FMT_S16P; //s16p is invalid or not supported by aac: S16 not by mp3
+ aCtx->channels=2;
+ aCtx->sample_rate=44100;
+ aCtx->channel_layout=AV_CH_LAYOUT_STEREO;
+ aCtx->bit_rate = 64000;
+
+
+
+ AVCodec * acodec = avcodec_find_encoder(aCtx->codec_id);
+ mutex.lock();
+ int ret = avcodec_open2(aCtx, acodec, NULL);
+ mutex.unlock();
if (ret < 0) {
throw std::runtime_error("Could not open audio codec:");
-
+
}
- if (pCtx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
+ if (aCtx->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?
+ audio_input_frame_size = aCtx->frame_size; //is coming out at 0?
+
+ cerr<<"audio codec frame size is "<<audio_input_frame_size<<endl;
+
+ //if (audio_input_frame_size ==0) { can't do this
+ // audio_input_frame_size =10000;
+ //}
+
+ // [mpeg4 @ 0x7f02f00200e0] nb_samples (10000) != frame_size (0) (avcodec_encode_audio2) - quits thread
+ // why is frame size 0?
+ // should there be a seperate pCtx for audio?
+
+ if (container->oformat->flags & AVFMT_GLOBALHEADER)
+ aCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+
+ audiostep=((float)audio_input_frame_size)/(aCtx->sample_rate);
+
- audiostep=((float)audio_input_frame_size)/(pCtx->sample_rate);
// are we supposed to use the same codeccontext?
@@ -716,7 +756,7 @@ libav::encoder::encoder(const char * file_name, int width, int height, float _fr
/* open the output file */
if (!(fmt->flags & AVFMT_NOFILE))
- {
+ {
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
if (avio_open(&container->pb, file_name, AVIO_FLAG_WRITE) < 0)
@@ -747,7 +787,7 @@ void libav::encoder::write_frame(float seconds,uint8_t *rgbdata)
/* encode the image */
// use non-deprecated avcodec_encode_video2(...)
- AVPacket packet;
+ AVPacket packet={0};
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
@@ -755,13 +795,17 @@ void libav::encoder::write_frame(float seconds,uint8_t *rgbdata)
//no time stamps as is
//http://dranger.com/ffmpeg/tutorial07.html
- picture_yuv->pts=(uint64_t)(seconds*timebase);
+ picture_yuv->pts=(uint64_t)(seconds*timebase); //
int got_packet;
int ret = avcodec_encode_video2(pCtx,
&packet,
picture_yuv,
&got_packet);
+
+ //packet.pts=(uint64_t)(seconds*timebase); //added 0606
+ packet.stream_index = video_st->index;; //added 0606
+
if (ret < 0)
throw std::runtime_error("Video encoding failed");
if (got_packet)
@@ -778,7 +822,7 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
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;
+ int bufsize=audio_input_frame_size * av_get_bytes_per_sample(aCtx->sample_fmt) *aCtx->channels;
if (audiodata) {
sampleptr=(uint8_t*)audiodata;
}
@@ -787,15 +831,21 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
memset(sampleptr,0,bufsize);
}
- avcodec_fill_audio_frame(audio_frame, pCtx->channels, pCtx->sample_fmt,
+ audio_frame->pts=(uint64_t)(seconds*timebase); //
+
+ avcodec_fill_audio_frame(audio_frame, aCtx->channels, aCtx->sample_fmt,
sampleptr,
audio_input_frame_size *
- av_get_bytes_per_sample(pCtx->sample_fmt) *
- pCtx->channels, 0); //;
+ av_get_bytes_per_sample(aCtx->sample_fmt) *
+ aCtx->channels, 0); //;
+
+
+
+ ret = avcodec_encode_audio2(aCtx, &pkt, audio_frame, &got_packet);
- audio_frame->pts=(uint64_t)(seconds*timebase);
+ pkt.stream_index = audio_st->index; //hardcoded stream index added 0606
+ //pkt.pts=(uint64_t)(seconds*timebase); //added 060613
- ret = avcodec_encode_audio2(pCtx, &pkt, audio_frame, &got_packet);
if (!audiodata) {
delete[] sampleptr;
}
@@ -806,7 +856,7 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
if (!got_packet)
return;
- // ? pkt.stream_index = st->index;
+ // ? pkt.stream_index = st->index;
ret = av_interleaved_write_frame(container, &pkt);
avcodec_free_frame(&audio_frame);
@@ -815,33 +865,43 @@ void libav::encoder::write_frame(float seconds,uint16_t *audiodata){
/* virtual */
libav::encoder::~encoder()
{
+
+ //avcodec_flush_buffers(pCtx); ???? from exporter version
+
+
int result = av_write_frame(container, NULL); // flush
result = av_write_trailer(container);
- {
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
avio_close(container->pb);
mutex.unlock();
+
+ //added 0706
+ video_st=nullptr;
+ audio_st=nullptr;
+ //
+
+ for (int i = 0; i < container->nb_streams; ++i) {
+ av_freep(container->streams[i]); //CRASHING HERE ON STREAM 1, OUTPUT IS VALID BUT AUDIO INAUDIBLE - 060613
}
- for (int i = 0; i < container->nb_streams; ++i)
- av_freep(container->streams[i]);
av_free(container);
- container = NULL;
-
- {
+ container = nullptr;
//QMutexLocker lock(&decoder::mutex);
mutex.lock();
+ avcodec_close(aCtx);
avcodec_close(pCtx);
mutex.unlock();
- }
av_free(pCtx);
pCtx = NULL;
+ av_free(aCtx);
+ aCtx=nullptr;
av_free(picture_yuv->data[0]);
av_free(picture_yuv);
picture_yuv = NULL;
av_free(picture_rgb->data[0]);
av_free(picture_rgb);
picture_rgb = NULL;
+
}
bool libav::exporter::setup(int w,int h, int bitRate, int frameRate, std::string container){
@@ -875,6 +935,8 @@ bool libav::exporter::record(std::string filename){
video_st = NULL;
audio_st = NULL;
+ fmt->video_codec=AV_CODEC_ID_MPEG4;
+
if (fmt->video_codec != AV_CODEC_ID_NONE) {
video_st = add_stream(oc, &video_codec, fmt->video_codec);
}
@@ -1007,7 +1069,7 @@ void libav::exporter::finishRecord(){
close_audio(oc, audio_st);
if (!(fmt->flags & AVFMT_NOFILE)) {
- // Close the output file. //
+ // Close the output file. //
mutex.lock();
avio_close(oc->pb);
mutex.unlock();
@@ -1102,6 +1164,7 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
// allocate and init a re-usable frame //
frame = avcodec_alloc_frame();
+ // moved to constructor and freeing in destructor -- stills crashes the same
if (!frame) {
//fprintf(stderr, "Could not allocate video frame\n");
exit(1);
@@ -1192,7 +1255,7 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
sampleptr=new uint8_t[bufsize];
memset(sampleptr,0,bufsize);
}
-
+
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
sampleptr,
audio_input_frame_size *
@@ -1351,6 +1414,10 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
av_init_packet(&pkt);
// encode the image //
+
+ // 2nd time you render it crashes right after here
+
+ // where the hell is frame being allocated? is the problem caused by it being freed? (see removeal of avframe_free in cleanup)
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
//fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
@@ -1388,7 +1455,10 @@ void libav::exporter::open_video(AVFormatContext *oc, AVCodec *codec, AVStream *
avcodec_close(st->codec);
av_free(src_picture.data[0]);
av_free(dst_picture.data[0]);
- av_free(frame);
+ av_free(frame); //removed to explore crash 2nd time render
+ //gives *** Error in `./rotord': corrupted double-linked list: 0x00007fd8b005bd60 ***
+ //where is frame initialised???
+ //moved to destructor
av_free(outPixels); //SIGSEV here???
mutex.unlock();
}
@@ -1450,7 +1520,7 @@ bool libav::audioloader::setup(const std::string &filename){
mutex.lock();
if (codecContext->codec == NULL)
{
-
+
av_free(frame);
avformat_close_input(&formatContext);
std::cout << "Couldn't find a proper decoder" << std::endl;
@@ -1458,7 +1528,7 @@ bool libav::audioloader::setup(const std::string &filename){
}
else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
{
-
+
av_free(frame);
avformat_close_input(&formatContext);
mutex.lock();
@@ -1609,6 +1679,8 @@ bool libav::audioloader::close() {
avcodec_close(codecContext);
avformat_close_input(&formatContext);
mutex.unlock();
-
+ ready=false;
+ sample_start=0;
+ sample_end=0;
return true;
-} \ No newline at end of file
+}