Patch #33837: ffmpeg1.1 and libav9.1 compatibility update
Patch makes it possible to compile blender with recent ffmpeg and libav libraries, mainly by getting rid of deprecated API. Original patch by Campbell Barton with own modifications to support compilation with older ffmpeg versions. This patch could break compatibility of FFV1 videos playing back in older players, mainly because of alpha support changes. Preserving compatibility with such players became a headache and think it's high time to get rid of workarounds here.
This commit is contained in:
@@ -107,7 +107,7 @@ void AUD_FFMPEGReader::init()
|
||||
m_position = 0;
|
||||
m_pkgbuf_left = 0;
|
||||
|
||||
if(av_find_stream_info(m_formatCtx)<0)
|
||||
if(avformat_find_stream_info(m_formatCtx, NULL) < 0)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, streaminfo_error);
|
||||
|
||||
// find audio stream and codec
|
||||
@@ -133,7 +133,7 @@ void AUD_FFMPEGReader::init()
|
||||
if(!aCodec)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
|
||||
|
||||
if(avcodec_open(m_codecCtx, aCodec)<0)
|
||||
if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
|
||||
|
||||
// XXX this prints file information to stdout:
|
||||
@@ -236,14 +236,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer) :
|
||||
AUD_FFMPEGReader::~AUD_FFMPEGReader()
|
||||
{
|
||||
avcodec_close(m_codecCtx);
|
||||
|
||||
if(m_aviocontext)
|
||||
{
|
||||
avformat_close_input(&m_formatCtx);
|
||||
av_free(m_aviocontext);
|
||||
}
|
||||
else
|
||||
av_close_input_file(m_formatCtx);
|
||||
avformat_close_input(&m_formatCtx);
|
||||
}
|
||||
|
||||
int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
|
||||
|
@@ -55,10 +55,15 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
|
||||
{
|
||||
static const char* formats[] = { NULL, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
|
||||
|
||||
if(avformat_alloc_output_context2(&m_formatCtx, NULL, formats[format], filename.c_str()))
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, context_error);
|
||||
m_formatCtx = avformat_alloc_context();
|
||||
if (!m_formatCtx) AUD_THROW(AUD_ERROR_FFMPEG, context_error);
|
||||
|
||||
m_outputFmt = m_formatCtx->oformat;
|
||||
strcpy(m_formatCtx->filename, filename.c_str());
|
||||
m_outputFmt = m_formatCtx->oformat = av_guess_format(formats[format], filename.c_str(), NULL);
|
||||
if (!m_outputFmt) {
|
||||
avformat_free_context(m_formatCtx);
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, context_error);
|
||||
}
|
||||
|
||||
switch(codec)
|
||||
{
|
||||
@@ -116,7 +121,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
|
||||
if(m_outputFmt->audio_codec == CODEC_ID_NONE)
|
||||
AUD_THROW(AUD_ERROR_SPECS, codec_error);
|
||||
|
||||
m_stream = av_new_stream(m_formatCtx, 0);
|
||||
m_stream = avformat_new_stream(m_formatCtx, NULL);
|
||||
if(!m_stream)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, stream_error);
|
||||
|
||||
@@ -164,7 +169,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
|
||||
if(!codec)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
|
||||
|
||||
if(avcodec_open(m_codecCtx, codec))
|
||||
if(avcodec_open2(m_codecCtx, codec, NULL))
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
|
||||
|
||||
m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/rational.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
|
||||
#define FFMPEG_HAVE_PARSE_UTILS 1
|
||||
@@ -73,12 +74,68 @@
|
||||
|
||||
#if ((LIBAVUTIL_VERSION_MAJOR > 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 32))
|
||||
#define FFMPEG_FFV1_ALPHA_SUPPORTED
|
||||
#else
|
||||
static inline
|
||||
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
|
||||
{
|
||||
const AVOption *rv = NULL;
|
||||
av_set_string3(obj, name, val, 1, &rv);
|
||||
return rv != NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
|
||||
{
|
||||
const AVOption *rv = NULL;
|
||||
rv = av_set_int(obj, name, val);
|
||||
return rv != NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
|
||||
{
|
||||
const AVOption *rv = NULL;
|
||||
rv = av_set_double(obj, name, val);
|
||||
return rv != NULL;
|
||||
}
|
||||
|
||||
#define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
|
||||
#define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
|
||||
#define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
|
||||
#define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
|
||||
#define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
|
||||
#define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
|
||||
#endif
|
||||
|
||||
#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2)))
|
||||
#define avformat_close_input(x) av_close_input_file(*(x))
|
||||
#endif
|
||||
|
||||
#if ((LIBAVCODEC_VERSION_MAJOR < 53) || (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 42))
|
||||
static inline
|
||||
int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
|
||||
{
|
||||
/* TODO: no options are taking into account */
|
||||
return avcodec_open(avctx, codec);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 24))
|
||||
static inline
|
||||
AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
|
||||
{
|
||||
/* TODO: no codec is taking into account */
|
||||
return av_new_stream(s, 0);
|
||||
}
|
||||
|
||||
static inline
|
||||
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
|
||||
{
|
||||
/* TODO: no options are taking into account */
|
||||
return av_find_stream_info(ic);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && (LIBAVFORMAT_VERSION_MICRO >= 100)))
|
||||
static inline
|
||||
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
|
||||
|
@@ -373,7 +373,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
|
||||
{
|
||||
char name[128];
|
||||
char *param;
|
||||
const AVOption *rv = NULL;
|
||||
int fail = TRUE;
|
||||
|
||||
PRINT("FFMPEG expert option: %s: ", prop->name);
|
||||
|
||||
@@ -388,30 +388,30 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
|
||||
switch (prop->type) {
|
||||
case IDP_STRING:
|
||||
PRINT("%s.\n", IDP_String(prop));
|
||||
av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
|
||||
fail = av_opt_set(c, prop->name, IDP_String(prop), 0);
|
||||
break;
|
||||
case IDP_FLOAT:
|
||||
PRINT("%g.\n", IDP_Float(prop));
|
||||
rv = av_set_double(c, prop->name, IDP_Float(prop));
|
||||
fail = av_opt_set_double(c, prop->name, IDP_Float(prop), 0);
|
||||
break;
|
||||
case IDP_INT:
|
||||
PRINT("%d.\n", IDP_Int(prop));
|
||||
|
||||
if (param) {
|
||||
if (IDP_Int(prop)) {
|
||||
av_set_string3(c, name, param, 1, &rv);
|
||||
fail = av_opt_set(c, name, param, 0);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = av_set_int(c, prop->name, IDP_Int(prop));
|
||||
fail = av_opt_set_int(c, prop->name, IDP_Int(prop), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rv) {
|
||||
if (fail) {
|
||||
PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
|
||||
}
|
||||
}
|
||||
@@ -464,8 +464,9 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
|
||||
|
||||
error[0] = '\0';
|
||||
|
||||
st = av_new_stream(of, 0);
|
||||
st = avformat_new_stream(of, NULL);
|
||||
if (!st) return NULL;
|
||||
st->id = 0;
|
||||
|
||||
/* Set up the codec context */
|
||||
|
||||
@@ -541,16 +542,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
|
||||
}
|
||||
|
||||
if (codec_id == CODEC_ID_FFV1) {
|
||||
#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
|
||||
if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
|
||||
c->pix_fmt = PIX_FMT_RGB32;
|
||||
}
|
||||
else {
|
||||
c->pix_fmt = PIX_FMT_BGR0;
|
||||
}
|
||||
#else
|
||||
c->pix_fmt = PIX_FMT_RGB32;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (codec_id == CODEC_ID_QTRLE) {
|
||||
@@ -582,7 +574,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
|
||||
|
||||
set_ffmpeg_properties(rd, c, "video");
|
||||
|
||||
if (avcodec_open(c, codec) < 0) {
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
|
||||
return NULL;
|
||||
}
|
||||
@@ -619,8 +611,9 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
|
||||
|
||||
error[0] = '\0';
|
||||
|
||||
st = av_new_stream(of, 1);
|
||||
st = avformat_new_stream(of, NULL);
|
||||
if (!st) return NULL;
|
||||
st->id = 1;
|
||||
|
||||
c = st->codec;
|
||||
c->codec_id = codec_id;
|
||||
@@ -642,7 +635,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
|
||||
|
||||
set_ffmpeg_properties(rd, c, "audio");
|
||||
|
||||
if (avcodec_open(c, codec) < 0) {
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
//XXX error("Couldn't initialize audio codec");
|
||||
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
|
||||
return NULL;
|
||||
@@ -1151,7 +1144,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
|
||||
|
||||
val.i = 0;
|
||||
|
||||
avcodec_get_context_defaults(&c);
|
||||
avcodec_get_context_defaults3(&c, NULL);
|
||||
|
||||
o = c.av_class->option + opt_index;
|
||||
parent = c.av_class->option + parent_index;
|
||||
@@ -1182,23 +1175,23 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
|
||||
}
|
||||
|
||||
switch (o->type) {
|
||||
case FF_OPT_TYPE_INT:
|
||||
case FF_OPT_TYPE_INT64:
|
||||
case AV_OPT_TYPE_INT:
|
||||
case AV_OPT_TYPE_INT64:
|
||||
val.i = FFMPEG_DEF_OPT_VAL_INT(o);
|
||||
idp_type = IDP_INT;
|
||||
break;
|
||||
case FF_OPT_TYPE_DOUBLE:
|
||||
case FF_OPT_TYPE_FLOAT:
|
||||
case AV_OPT_TYPE_DOUBLE:
|
||||
case AV_OPT_TYPE_FLOAT:
|
||||
val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
|
||||
idp_type = IDP_FLOAT;
|
||||
break;
|
||||
case FF_OPT_TYPE_STRING:
|
||||
case AV_OPT_TYPE_STRING:
|
||||
val.string.str = (char *)" ";
|
||||
val.string.len = 80;
|
||||
/* val.str = (char *)" ";*/
|
||||
idp_type = IDP_STRING;
|
||||
break;
|
||||
case FF_OPT_TYPE_CONST:
|
||||
case AV_OPT_TYPE_CONST:
|
||||
val.i = 1;
|
||||
idp_type = IDP_INT;
|
||||
break;
|
||||
@@ -1238,7 +1231,7 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
|
||||
char *param;
|
||||
IDProperty *prop = NULL;
|
||||
|
||||
avcodec_get_context_defaults(&c);
|
||||
avcodec_get_context_defaults3(&c, NULL);
|
||||
|
||||
strncpy(name_, str, sizeof(name_));
|
||||
|
||||
@@ -1259,10 +1252,10 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
|
||||
if (!o) {
|
||||
return 0;
|
||||
}
|
||||
if (param && o->type == FF_OPT_TYPE_CONST) {
|
||||
if (param && o->type == AV_OPT_TYPE_CONST) {
|
||||
return 0;
|
||||
}
|
||||
if (param && o->type != FF_OPT_TYPE_CONST && o->unit) {
|
||||
if (param && o->type != AV_OPT_TYPE_CONST && o->unit) {
|
||||
p = my_av_find_opt(&c, param, o->unit, 0, 0);
|
||||
if (p) {
|
||||
prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option);
|
||||
|
@@ -486,7 +486,7 @@ static int startffmpeg(struct anim *anim)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (av_find_stream_info(pFormatCtx) < 0) {
|
||||
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
|
||||
av_close_input_file(pFormatCtx);
|
||||
return -1;
|
||||
}
|
||||
@@ -523,7 +523,7 @@ static int startffmpeg(struct anim *anim)
|
||||
|
||||
pCodecCtx->workaround_bugs = 1;
|
||||
|
||||
if (avcodec_open(pCodecCtx, pCodec) < 0) {
|
||||
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
|
||||
av_close_input_file(pFormatCtx);
|
||||
return -1;
|
||||
}
|
||||
|
@@ -496,7 +496,9 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
|
||||
|
||||
fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
|
||||
|
||||
rv->st = av_new_stream(rv->of, 0);
|
||||
rv->st = avformat_new_stream(rv->of, NULL);
|
||||
rv->st->id = 0;
|
||||
|
||||
rv->c = rv->st->codec;
|
||||
rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
rv->c->codec_id = CODEC_ID_MJPEG;
|
||||
@@ -531,8 +533,8 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
|
||||
/* there's no way to set JPEG quality in the same way as in AVI JPEG and image sequence,
|
||||
* but this seems to be giving expected quality result */
|
||||
ffmpeg_quality = (int)(1.0f + 30.0f * (1.0f - (float)quality / 100.0f) + 0.5f);
|
||||
av_set_int(rv->c, "qmin", ffmpeg_quality);
|
||||
av_set_int(rv->c, "qmax", ffmpeg_quality);
|
||||
av_opt_set_int(rv->c, "qmin", ffmpeg_quality, 0);
|
||||
av_opt_set_int(rv->c, "qmax", ffmpeg_quality, 0);
|
||||
|
||||
if (rv->of->flags & AVFMT_GLOBALHEADER) {
|
||||
rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
@@ -545,7 +547,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
|
||||
return 0;
|
||||
}
|
||||
|
||||
avcodec_open(rv->c, rv->codec);
|
||||
avcodec_open2(rv->c, rv->codec, NULL);
|
||||
|
||||
rv->video_buffersize = 2000000;
|
||||
rv->video_buffer = (uint8_t *)MEM_mallocN(
|
||||
@@ -758,7 +760,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (av_find_stream_info(context->iFormatCtx) < 0) {
|
||||
if (avformat_find_stream_info(context->iFormatCtx, NULL) < 0) {
|
||||
av_close_input_file(context->iFormatCtx);
|
||||
MEM_freeN(context);
|
||||
return NULL;
|
||||
@@ -797,7 +799,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
|
||||
|
||||
context->iCodecCtx->workaround_bugs = 1;
|
||||
|
||||
if (avcodec_open(context->iCodecCtx, context->iCodec) < 0) {
|
||||
if (avcodec_open2(context->iCodecCtx, context->iCodec, NULL) < 0) {
|
||||
av_close_input_file(context->iFormatCtx);
|
||||
MEM_freeN(context);
|
||||
return NULL;
|
||||
|
@@ -306,8 +306,8 @@ static int isffmpeg(const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (av_find_stream_info(pFormatCtx) < 0) {
|
||||
if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
|
||||
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
|
||||
if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
|
||||
av_close_input_file(pFormatCtx);
|
||||
return 0;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ static int isffmpeg(const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (avcodec_open(pCodecCtx, pCodec) < 0) {
|
||||
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
|
||||
av_close_input_file(pFormatCtx);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -174,7 +174,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
|
||||
if (avformat_open_input(&formatCtx, filename, inputFormat, formatParams)!=0)
|
||||
return -1;
|
||||
|
||||
if (av_find_stream_info(formatCtx)<0)
|
||||
if (avformat_find_stream_info(formatCtx, NULL) < 0)
|
||||
{
|
||||
av_close_input_file(formatCtx);
|
||||
return -1;
|
||||
@@ -209,7 +209,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
|
||||
return -1;
|
||||
}
|
||||
codecCtx->workaround_bugs = 1;
|
||||
if (avcodec_open(codecCtx, codec)<0)
|
||||
if (avcodec_open2(codecCtx, codec, NULL) < 0)
|
||||
{
|
||||
av_close_input_file(formatCtx);
|
||||
return -1;
|
||||
|
Reference in New Issue
Block a user