From fe0658dd36e20eb4f6efa0f83297c06cfc0965ef Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Sat, 1 Feb 2020 22:53:38 -0500 Subject: [PATCH] GUACAMOLE-465: resolved issues brought up in PR159 and added compatibility with recent versions of libavcodec --- src/guacenc/ffmpeg-compat.c | 12 ++++------ src/guacenc/ffmpeg-compat.h | 47 +++++++++++++++++++++++++++---------- src/guacenc/guacenc.c | 3 ++- src/guacenc/video.c | 4 ++-- src/guacenc/video.h | 3 ++- 5 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/guacenc/ffmpeg-compat.c b/src/guacenc/ffmpeg-compat.c index 632666a2..593c7b1e 100644 --- a/src/guacenc/ffmpeg-compat.c +++ b/src/guacenc/ffmpeg-compat.c @@ -55,7 +55,7 @@ static int guacenc_write_packet(guacenc_video* video, void* data, int size) { #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,1,0) AVPacket pkt; - /* have to create a packet around the encoded data we have */ + /* Have to create a packet around the encoded data we have */ av_init_packet(&pkt); if (video->context->coded_frame->pts != AV_NOPTS_VALUE) { @@ -207,9 +207,7 @@ AVCodecContext* guacenc_build_avcodeccontext(AVStream* stream, AVCodec* codec, stream->codec->qmin = qmin; stream->codec->pix_fmt = pix_fmt; stream->codec->time_base = time_base; -#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(55, 44, 100) - stream->codec->time_base = time_base; -#else +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(55, 44, 100) stream->time_base = time_base; #endif return stream->codec; @@ -234,12 +232,10 @@ AVCodecContext* guacenc_build_avcodeccontext(AVStream* stream, AVCodec* codec, int guacenc_open_avcodec(AVCodecContext *avcodec_context, AVCodec *codec, AVDictionary **options, AVStream* stream) { - int ret = 0; - ret = avcodec_open2(avcodec_context, codec, options); + int ret = avcodec_open2(avcodec_context, codec, options); #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 33, 100) - int codecpar_ret = 0; /* copy stream parameters to the muxer */ - codecpar_ret = avcodec_parameters_from_context(stream->codecpar, + int codecpar_ret = avcodec_parameters_from_context(stream->codecpar, avcodec_context); if (codecpar_ret < 0) { return codecpar_ret; diff --git a/src/guacenc/ffmpeg-compat.h b/src/guacenc/ffmpeg-compat.h index b6a95e28..e0542a43 100644 --- a/src/guacenc/ffmpeg-compat.h +++ b/src/guacenc/ffmpeg-compat.h @@ -52,6 +52,16 @@ #define av_packet_unref av_free_packet #endif +/* For libavcodec <= 56.41.100: Global header flag didn't have AV_ prefix. + * Guacenc defines its own flag here to avoid conflicts with libavcodec + * macros. + */ +#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(56,41,100) +#define GUACENC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER +#else +#define GUACENC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER +#endif + /* For libavutil < 51.42.0: AV_PIX_FMT_* was PIX_FMT_* */ #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,42,0) #define AV_PIX_FMT_RGB32 PIX_FMT_RGB32 @@ -80,7 +90,9 @@ int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame); /** * Creates and sets up the AVCodecContext for the appropriate version - * of libavformat installed + * of libavformat installed. The AVCodecContext will be built, but + * the AVStream will also be affected by having its time_base field + * set to the value passed into this function. * * @param stream * The open AVStream @@ -112,6 +124,9 @@ int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame); * @param time_base * The target time base for the encoded video * + * @return + * The pointer to the configured AVCodecContext + * */ AVCodecContext* guacenc_build_avcodeccontext(AVStream* stream, AVCodec* codec, int bitrate, int width, int height, int gop_size, int qmax, int qmin, @@ -125,19 +140,25 @@ AVCodecContext* guacenc_build_avcodeccontext(AVStream* stream, AVCodec* codec, * So this wrapper handles that. Otherwise, it's the * same as avcodec_open2(). * - * @param avcodec_context The context to initialize. - * @param codec The codec to open this context for. If a non-NULL codec has - * been previously passed to avcodec_alloc_context3() or - * for this context, then this parameter MUST be either NULL or - * equal to the previously passed codec. - * @param options A dictionary filled with AVCodecContext and codec-private - * options. On return this object will be filled with options - * that were not found. - * @param stream The stream for the codec context. - * Only used in libavformat >= 57.33.100. Can be NULL in - * lower versions + * @param avcodec_context + * The context to initialize. * - * @return zero on success, a negative value on error + * @param codec + * The codec to open this context for. If a non-NULL codec has + * been previously passed to avcodec_alloc_context3() or + * for this context, then this parameter MUST be either NULL or + * equal to the previously passed codec. + * + * @param options + * A dictionary filled with AVCodecContext and codec-private + * options. On return this object will be filled with options + * that were not found. + * + * @param stream + * The stream for the codec context. + * + * @return + * Zero on success, a negative value on error */ int guacenc_open_avcodec(AVCodecContext *avcodec_context, AVCodec *codec, AVDictionary **options, diff --git a/src/guacenc/guacenc.c b/src/guacenc/guacenc.c index 0bd72d5f..7662f916 100644 --- a/src/guacenc/guacenc.c +++ b/src/guacenc/guacenc.c @@ -81,8 +81,9 @@ int main(int argc, char* argv[]) { avcodec_register_all(); #endif - /* Prepare libavformat */ +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); +#endif /* Track number of overall failures */ int total_files = argc - optind; diff --git a/src/guacenc/video.c b/src/guacenc/video.c index 3f7fdc9b..2dd41f16 100644 --- a/src/guacenc/video.c +++ b/src/guacenc/video.c @@ -91,9 +91,9 @@ guacenc_video* guacenc_video_alloc(const char* path, const char* codec_name, goto fail_context; } - //if format needs global headers, write them + /* If format needs global headers, write them */ if (container_format_context->oformat->flags & AVFMT_GLOBALHEADER) { - avcodec_context->flags |= CODEC_FLAG_GLOBAL_HEADER; + avcodec_context->flags |= GUACENC_FLAG_GLOBAL_HEADER; } /* Open codec for use */ diff --git a/src/guacenc/video.h b/src/guacenc/video.h index 37099b13..ea0c1615 100644 --- a/src/guacenc/video.h +++ b/src/guacenc/video.h @@ -51,7 +51,8 @@ typedef struct guacenc_video { /** * AVStream for video output. - * Persists via the AVFormatContext. + * Frames sent to this stream are written into + * the output file in the specified container format. */ AVStream* output_stream;