21 #ifndef GUIVideoEncoder_h 22 #define GUIVideoEncoder_h 34 #define __STDC_CONSTANT_MACROS 38 #pragma warning(disable: 4244) // do not warn about integer conversions 41 #pragma GCC diagnostic push 42 #pragma GCC diagnostic ignored "-Wpedantic" 43 #pragma GCC diagnostic ignored "-Wvariadic-macros" 47 #include <libavutil/opt.h> 48 #include <libavutil/imgutils.h> 49 #include <libavcodec/avcodec.h> 50 #include <libavformat/avformat.h> 51 #include <libswscale/swscale.h> 57 #pragma GCC diagnostic pop 73 GUIVideoEncoder(
const char*
const out_file,
const int width,
const int height,
double frameDelay) {
82 if (frameDelay > 0.) {
83 framerate = (int)(1000. / frameDelay);
89 video_st->time_base.num = 1;
90 video_st->time_base.den = framerate;
92 const AVCodec*
const codec = avcodec_find_encoder(
myFormatContext->oformat->video_codec);
93 if (codec ==
nullptr) {
99 throw ProcessError(
"Could not allocate video codec context!");
124 if (
myCodecCtx->codec_id == AV_CODEC_ID_H264) {
125 av_opt_set(
myCodecCtx->priv_data,
"preset",
"slow", 0);
130 if (
myCodecCtx->codec_id == AV_CODEC_ID_HEVC) {
131 av_opt_set(
myCodecCtx->priv_data,
"preset",
"ultrafast", 0);
132 av_opt_set(
myCodecCtx->priv_data,
"tune",
"zero-latency", 0);
134 if (avcodec_open2(
myCodecCtx, codec,
nullptr) < 0) {
145 if (av_frame_get_buffer(
myFrame, 32) < 0) {
146 throw ProcessError(
"Could not allocate the video frame data!");
161 myPkt = av_packet_alloc();
162 if (
myPkt ==
nullptr) {
169 if (!(
myCodecCtx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
172 if (avcodec_send_frame(
myCodecCtx,
nullptr) < 0) {
178 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
180 }
else if (ret < 0) {
185 av_packet_unref(
myPkt);
195 av_packet_free(&
myPkt);
200 if (av_frame_make_writable(
myFrame) < 0) {
203 uint8_t* inData[1] = { buffer };
204 int inLinesize[1] = { 4 *
myCodecCtx->width };
211 av_strerror(r, errbuf, 64);
212 throw ProcessError(
"Error sending frame for encoding!");
217 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
219 }
else if (ret < 0) {
224 myPkt->stream_index = 0;
226 av_packet_unref(
myPkt);
AVFormatContext * myFormatContext
void writeFrame(uint8_t *buffer)
#define WRITE_WARNING(msg)
GUIVideoEncoder(const char *const out_file, const int width, const int height, double frameDelay)
A simple video encoder from RGBA pics to anything ffmpeg can handle.
AVCodecContext * myCodecCtx
SwsContext * mySwsContext