From 52137ceed09a99a53dfe28bd94712cffb1b9d2ef Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Mon, 4 Mar 2013 16:37:19 -0500 Subject: [PATCH 1/2] Allow encoding with libx264 via ffmpeg to work Add a call to avcodec_get_context_defaults3, this sets per-codec default values and in the case of libx264 will stop VideoWriter::open (with fourcc=x264) from failing due to libx264 complaining about broken ffmpeg default settings. Set some additional libx264 encoder parameters. --- modules/highgui/src/cap_ffmpeg_impl.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/highgui/src/cap_ffmpeg_impl.hpp b/modules/highgui/src/cap_ffmpeg_impl.hpp index 642ece177..54b8db409 100644 --- a/modules/highgui/src/cap_ffmpeg_impl.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl.hpp @@ -59,6 +59,7 @@ extern "C" { #include "ffmpeg_codecs.hpp" +#include #include #ifdef WIN32 @@ -1114,6 +1115,12 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, c->codec_type = AVMEDIA_TYPE_VIDEO; + // Set per-codec defaults + AVCodecID c_id = c->codec_id; + avcodec_get_context_defaults3(c, codec); + // avcodec_get_context_defaults3 erases codec_id for some reason + c->codec_id = c_id; + /* put sample parameters */ int64_t lbit_rate = (int64_t)bitrate; lbit_rate += (bitrate / 2); @@ -1176,6 +1183,16 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */ c->mb_decision=2; } + /* Some settings for libx264 encoding, restore dummy values for gop_size + and qmin since they will be set to reasonable defaults by the libx264 + preset system. Also, use a crf encode with the default quality rating, + this seems easier than finding an appropriate default bitrate. */ + if (c->codec_id == AV_CODEC_ID_H264) { + c->gop_size = -1; + c->qmin = -1; + c->bit_rate = 0; + av_opt_set(c->priv_data,"crf","23", 0); + } #if LIBAVCODEC_VERSION_INT>0x000409 // some formats want stream headers to be seperate if(oc->oformat->flags & AVFMT_GLOBALHEADER) From c02f94392bba54fb31f397231ba364e1c939dded Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Mon, 4 Mar 2013 22:06:05 -0500 Subject: [PATCH 2/2] Add version checks to previous modifications to ffmpeg_cap_impl.hpp Add version checks around uses of AVCodecID and av_opt_set, since these aren't defined for older versions of ffmpeg. --- modules/highgui/src/cap_ffmpeg_impl.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/highgui/src/cap_ffmpeg_impl.hpp b/modules/highgui/src/cap_ffmpeg_impl.hpp index 54b8db409..cfb2e4fa1 100644 --- a/modules/highgui/src/cap_ffmpeg_impl.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl.hpp @@ -1115,11 +1115,13 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, c->codec_type = AVMEDIA_TYPE_VIDEO; +#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0) // Set per-codec defaults AVCodecID c_id = c->codec_id; avcodec_get_context_defaults3(c, codec); // avcodec_get_context_defaults3 erases codec_id for some reason c->codec_id = c_id; +#endif /* put sample parameters */ int64_t lbit_rate = (int64_t)bitrate; @@ -1183,16 +1185,20 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */ c->mb_decision=2; } + +#if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0) /* Some settings for libx264 encoding, restore dummy values for gop_size and qmin since they will be set to reasonable defaults by the libx264 preset system. Also, use a crf encode with the default quality rating, this seems easier than finding an appropriate default bitrate. */ - if (c->codec_id == AV_CODEC_ID_H264) { + if (c->codec_id == CODEC_ID_H264) { c->gop_size = -1; c->qmin = -1; c->bit_rate = 0; av_opt_set(c->priv_data,"crf","23", 0); } +#endif + #if LIBAVCODEC_VERSION_INT>0x000409 // some formats want stream headers to be seperate if(oc->oformat->flags & AVFMT_GLOBALHEADER)