diff options
Diffstat (limited to 'rotord/libavwrapper_guarded.cpp')
| -rwxr-xr-x | rotord/libavwrapper_guarded.cpp | 144 |
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 +} |
