diff options
Diffstat (limited to 'rotord/libavexporter.cpp')
| -rw-r--r-- | rotord/libavexporter.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/rotord/libavexporter.cpp b/rotord/libavexporter.cpp new file mode 100644 index 0000000..a46de5a --- /dev/null +++ b/rotord/libavexporter.cpp @@ -0,0 +1,124 @@ +#include "libavexporter.h" + +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(); + + this->w=w; + this->h=h; + this->bitRate=bitRate; + this->frameRate=frameRate; + this->container=container; + + return true; +} +bool libav::exporter::record(std::string filename){ + + // allocate the output media context // + avformat_alloc_output_context2(&oc, NULL, NULL, filename.c_str()); + if (!oc) { + printf("Could not deduce output format from file extension: using MPEG.\n"); + avformat_alloc_output_context2(&oc, NULL, "mpeg", filename.c_str()); + } + if (!oc) { + return false; + } + fmt = oc->oformat; + + // Add the audio and video streams using the default format codecs + // * and initialize the codecs. // + video_st = NULL; + audio_st = NULL; + + if (fmt->video_codec != AV_CODEC_ID_NONE) { + video_st = add_stream(oc, &video_codec, fmt->video_codec); + } + if (fmt->audio_codec != AV_CODEC_ID_NONE) { + audio_st = add_stream(oc, &audio_codec, fmt->audio_codec); + } + + //set initial video params + video_st->codec->width=w; + video_st->codec->height=h; + video_st->codec->time_base.num = 1;//codecCtx->ticks_per_frame; + video_st->codec->time_base.den = frameRate; + video_st->time_base = video_st->codec->time_base; + //audioStream->time_base = codecCtx->time_base; //???has the capability of crashing + + video_st->codec->gop_size = 10; /* emit one intra frame every ten frames */ + video_st->codec->pix_fmt = PIX_FMT_YUV420P; + + // Now that all the parameters are set, we can open the audio and + // * video codecs and allocate the necessary encode buffers. // + if (video_st) + open_video(oc, video_codec, video_st); + if (audio_st) + open_audio(oc, audio_codec, audio_st); + + av_dump_format(oc, 0, filename.c_str(), 1); + + // open the output file, if needed // + if (!(fmt->flags & AVFMT_NOFILE)) { + int ret = avio_open(&oc->pb, filename.c_str(), AVIO_FLAG_WRITE); + if (ret < 0) { + std::cerr <<"Could not open " << filename.c_str() << std::endl; + return false; + } + } + + // Write the stream header, if any. // + int ret = avformat_write_header(oc, NULL); + if (ret < 0) { + //std::cerr <<"Error occurred when opening output file:" << av_err2str(ret) << std::endl; + return false; + } + + frame=0; + return true; +} +bool libav::exporter::encodeFrame(unsigned char *pixels){ + // 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; + else + audio_pts = 0.0; + + if (video_st) + video_pts = (double)video_st->pts.val * video_st->time_base.num / + video_st->time_base.den; + 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); + } else { + write_video_frame(oc, video_st, 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(){ + // Close each codec. // + if (video_st) + close_video(oc, video_st); + if (audio_st) + close_audio(oc, audio_st); + + if (!(fmt->flags & AVFMT_NOFILE)) + // Close the output file. // + avio_close(oc->pb); + + // free the stream // + avformat_free_context(oc); +}
\ No newline at end of file |
