20 #ifndef GUIVideoEncoder_h
21 #define GUIVideoEncoder_h
33 #define __STDC_CONSTANT_MACROS
37 #pragma warning(disable: 4244) // do not warn about integer conversions
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wpedantic"
42 #pragma GCC diagnostic ignored "-Wvariadic-macros"
46 #include <libavutil/opt.h>
47 #include <libavutil/imgutils.h>
48 #include <libavcodec/avcodec.h>
49 #include <libavformat/avformat.h>
50 #include <libswscale/swscale.h>
56 #pragma GCC diagnostic pop
72 GUIVideoEncoder(
const char*
const out_file,
const int width,
const int height,
double frameDelay) {
81 if (frameDelay > 0.) {
82 framerate = (int)(1000. / frameDelay);
88 video_st->time_base.num = 1;
89 video_st->time_base.den = framerate;
91 const AVCodec*
const codec = avcodec_find_encoder(
myFormatContext->oformat->video_codec);
92 if (codec ==
nullptr) {
98 throw ProcessError(
"Could not allocate video codec context!");
123 if (
myCodecCtx->codec_id == AV_CODEC_ID_H264) {
124 av_opt_set(
myCodecCtx->priv_data,
"preset",
"slow", 0);
129 if (
myCodecCtx->codec_id == AV_CODEC_ID_HEVC) {
130 av_opt_set(
myCodecCtx->priv_data,
"preset",
"ultrafast", 0);
131 av_opt_set(
myCodecCtx->priv_data,
"tune",
"zero-latency", 0);
133 if (avcodec_open2(
myCodecCtx, codec,
nullptr) < 0) {
144 if (av_frame_get_buffer(
myFrame, 32) < 0) {
145 throw ProcessError(
"Could not allocate the video frame data!");
160 myPkt = av_packet_alloc();
161 if (
myPkt ==
nullptr) {
168 if (!(
myCodecCtx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
171 if (avcodec_send_frame(
myCodecCtx,
nullptr) < 0) {
177 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
179 }
else if (ret < 0) {
184 av_packet_unref(
myPkt);
194 av_packet_free(&
myPkt);
199 if (av_frame_make_writable(
myFrame) < 0) {
202 uint8_t* inData[1] = { buffer };
203 int inLinesize[1] = { 4 *
myCodecCtx->width };
210 av_strerror(r, errbuf, 64);
211 throw ProcessError(
"Error sending frame for encoding!");
216 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
218 }
else if (ret < 0) {
223 myPkt->stream_index = 0;
225 av_packet_unref(
myPkt);