From 42121590f4bfd65f26e8ec705a660f4cc1bd826e Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Fri, 27 May 2011 23:33:40 +0000 Subject: [PATCH] == FFMPEG == Added central compatibility header file, which enables blender to compile against very old ffmpeg versions as well as very new versions using the *NEW* API. (Old API functions are simulated using macros and inline functions) Added a whole lot of additional checks, tested against 6 different versions down the timeline, hopefully, now finally all is well. --- intern/audaspace/CMakeLists.txt | 1 + intern/audaspace/SConscript | 2 +- intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp | 1 + intern/ffmpeg/ffmpeg_compat.h | 133 ++++++++++++++++++ source/blender/blenkernel/CMakeLists.txt | 1 + source/blender/blenkernel/SConscript | 1 + .../blender/blenkernel/intern/writeffmpeg.c | 41 +----- source/blender/imbuf/CMakeLists.txt | 1 + source/blender/imbuf/SConscript | 2 +- source/blender/imbuf/intern/anim_movie.c | 50 +------ source/blender/imbuf/intern/util.c | 8 +- source/gameengine/VideoTexture/CMakeLists.txt | 1 + source/gameengine/VideoTexture/SConscript | 1 + source/gameengine/VideoTexture/VideoFFmpeg.h | 11 +- 14 files changed, 152 insertions(+), 102 deletions(-) create mode 100644 intern/ffmpeg/ffmpeg_compat.h diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt index 74f483eab05..a2468d0071e 100644 --- a/intern/audaspace/CMakeLists.txt +++ b/intern/audaspace/CMakeLists.txt @@ -26,6 +26,7 @@ set(INC FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC} + ../ffmpeg ) set(SRC diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript index ecc94987185..67f859b0e5f 100644 --- a/intern/audaspace/SConscript +++ b/intern/audaspace/SConscript @@ -8,7 +8,7 @@ defs = [] if env['WITH_BF_FFMPEG']: sources += env.Glob('ffmpeg/*.cpp') - incs += ' ffmpeg ' + env['BF_FFMPEG_INC'] + incs += ' ffmpeg #/intern/ffmpeg ' + env['BF_FFMPEG_INC'] defs.append('WITH_FFMPEG') if env['WITH_BF_SDL']: diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp index e748235e40e..4597432e7d1 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp @@ -39,6 +39,7 @@ extern "C" { #include #include +#include "ffmpeg_compat.h" } int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer) diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h new file mode 100644 index 00000000000..834df3d7055 --- /dev/null +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -0,0 +1,133 @@ +#ifndef __ffmpeg_compat_h_included__ +#define __ffmpeg_compat_h_included__ 1 + +/* + * $Id$ + * + * compatibility macros to make every ffmpeg installation appear + * like the most current installation (wrapping some functionality sometimes) + * it also includes all ffmpeg header files at once, no need to do it + * seperately. + * + * Copyright (c) 2011 Peter Schlaile + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + +#include +#include +#include + +#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) +#define FFMPEG_HAVE_PARSE_UTILS 1 +#include +#endif + +#include +#include + +#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105)) +#define FFMPEG_HAVE_AVIO 1 +#endif + +#if (LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR >= 53) && (LIBAVFORMAT_VERSION_MINOR >= 1)) +#define FFMPEG_HAVE_DEFAULT_VAL_UNION 1 +#endif + +#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) +#define FFMPEG_HAVE_AV_DUMP_FORMAT 1 +#endif + +#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 45)) +#define FFMPEG_HAVE_AV_GUESS_FORMAT 1 +#endif + +#if (LIBAVCODEC_VERSION_MAJOR > 52) || ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 23)) +#define FFMPEG_HAVE_DECODE_AUDIO3 1 +#define FFMPEG_HAVE_DECODE_VIDEO2 1 +#endif + +#if (LIBAVCODEC_VERSION_MAJOR > 52) || ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 64)) +#define FFMPEG_HAVE_AVMEDIA_TYPES 1 +#endif + +#if (LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29) && \ + (LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10) +#define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT +#endif + +#ifndef FFMPEG_HAVE_AVIO +#define AVIO_FLAG_WRITE URL_WRONLY +#define avio_open url_fopen +#define avio_tell url_ftell +#define avio_close url_fclose +#endif + +/* there are some version inbetween, which have avio_... functions but no + AVIO_FLAG_... */ +#ifndef AVIO_FLAG_WRITE +#define AVIO_FLAG_WRITE URL_WRONLY +#endif + +#ifndef AV_PKT_FLAG_KEY +#define AV_PKT_FLAG_KEY PKT_FLAG_KEY +#endif + +#ifndef FFMPEG_HAVE_AV_DUMP_FORMAT +#define av_dump_format dump_format +#endif + +#ifndef FFMPEG_HAVE_AV_GUESS_FORMAT +#define av_guess_format guess_format +#endif + +#ifndef FFMPEG_HAVE_PARSE_UTILS +#define av_parse_video_rate av_parse_video_frame_rate +#endif + +#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION +#define FFMPEG_DEF_OPT_VAL_INT(OPT) OPT->default_val.i64 +#define FFMPEG_DEF_OPT_VAL_DOUBLE(OPT) OPT->default_val.dbl +#else +#define FFMPEG_DEF_OPT_VAL_INT(OPT) OPT->default_val +#define FFMPEG_DEF_OPT_VAL_DOUBLE(OPT) OPT->default_val +#endif + +#ifndef FFMPEG_HAVE_AVMEDIA_TYPES +#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO +#define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO +#endif + +#ifndef FFMPEG_HAVE_DECODE_AUDIO3 +static inline +int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, AVPacket *avpkt) +{ + return avcodec_decode_audio2(avctx, samples, + frame_size_ptr, avpkt->data, + avpkt->size); +} +#endif + +#ifndef FFMPEG_HAVE_DECODE_VIDEO2 +static inline +int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt) +{ + return avcodec_decode_video(avctx, picture, got_picture_ptr, + avpkt->data, avpkt->size); +} +#endif + +#endif diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 2831636361f..44d20b6c651 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -44,6 +44,7 @@ set(INC ../editors/include ../render/extern/include ../../../intern/audaspace/intern + ../../../intern/ffmpeg ../../../intern/bsp/extern ../blenfont ../../../intern/decimation/extern ../../../intern/elbeem/extern diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index ea19b51c044..b5f845acacb 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -14,6 +14,7 @@ incs += ' ../gpu #/extern/glew/include' incs += ' #/intern/smoke/extern' incs += ' #/intern/mikktspace' incs += ' #/intern/audaspace/intern' +incs += ' #/intern/ffmpeg' incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 48930ae2eb8..c729565533f 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -61,34 +61,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105)) -#define FFMPEG_HAVE_AVIO 1 -#endif - -#if (LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR >= 53) && (LIBAVFORMAT_VERSION_MINOR >= 1)) -#define FFMPEG_HAVE_DEFAULT_VAL_UNION 1 -#endif - -#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) -#define FFMPEG_HAVE_AV_DUMP_FORMAT 1 -#endif - -#ifndef FFMPEG_HAVE_AVIO -#define AVIO_FLAG_WRITE URL_WRONLY -#define avio_open url_fopen -#define avio_tell url_ftell -#define avio_close url_fclose -#endif - -/* make OpenSuSe special "in-between" ffmpeg 0.6.2 version(tm) happy... - Arrrrgh */ -#ifndef AVIO_FLAG_WRITE -#define AVIO_FLAG_WRITE URL_WRONLY -#endif - -#ifndef FFMPEG_HAVE_AV_DUMP_FORMAT -#define av_dump_format dump_format -#endif +#include "ffmpeg_compat.h" extern void do_init_ffmpeg(void); @@ -1080,20 +1053,12 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int switch (o->type) { case FF_OPT_TYPE_INT: case FF_OPT_TYPE_INT64: -#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION - val.i = o->default_val.i64; -#else - val.i = o->default_val; -#endif + val.i = FFMPEG_DEF_OPT_VAL_INT(o); idp_type = IDP_INT; break; case FF_OPT_TYPE_DOUBLE: case FF_OPT_TYPE_FLOAT: -#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION - val.f = o->default_val.dbl; -#else - val.f = o->default_val; -#endif + val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o); idp_type = IDP_FLOAT; break; case FF_OPT_TYPE_STRING: diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 6404ae3de75..2522bcfed92 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -38,6 +38,7 @@ set(INC ../makesdna ../../../intern/memutil ../../../intern/guardedalloc + ../../../intern/ffmpeg ${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index ecb9a89c274..a80f92b4421 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c') incs = '. ../makesdna #/intern/guardedalloc #/intern/memutil ../blenlib' incs += ' ../avi ../blenkernel ../blenloader' - +incs += ' #/intern/ffmpeg' incs += ' ' + env['BF_JPEG_INC'] incs += ' ' + env['BF_PNG_INC'] diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index a0051d85c5b..919b0eb0c29 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -97,24 +97,7 @@ #include #include -#if LIBAVFORMAT_VERSION_INT < (49 << 16) -#define FFMPEG_OLD_FRAME_RATE 1 -#else -#define FFMPEG_CODEC_IS_POINTER 1 -#endif - -#if (LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29) && \ - (LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10) -#define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT -#endif - -#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) -#define FFMPEG_HAVE_AV_DUMP_FORMAT 1 -#endif - -#ifndef FFMPEG_HAVE_AV_DUMP_FORMAT -#define av_dump_format dump_format -#endif +#include "ffmpeg_compat.h" #endif //WITH_FFMPEG @@ -528,18 +511,6 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) { extern void do_init_ffmpeg(void); -#ifdef FFMPEG_CODEC_IS_POINTER -static AVCodecContext* get_codec_from_stream(AVStream* stream) -{ - return stream->codec; -} -#else -static AVCodecContext* get_codec_from_stream(AVStream* stream) -{ - return &stream->codec; -} -#endif - static int startffmpeg(struct anim * anim) { int i, videoStream; @@ -573,7 +544,7 @@ static int startffmpeg(struct anim * anim) { /* Find the first video stream */ videoStream=-1; for(i=0; inb_streams; i++) - if(get_codec_from_stream(pFormatCtx->streams[i])->codec_type + if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStream=i; break; @@ -584,7 +555,7 @@ static int startffmpeg(struct anim * anim) { return -1; } - pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]); + pCodecCtx = pFormatCtx->streams[videoStream]->codec; /* Find the decoder for the video stream */ pCodec=avcodec_find_decoder(pCodecCtx->codec_id); @@ -600,19 +571,10 @@ static int startffmpeg(struct anim * anim) { return -1; } -#ifdef FFMPEG_OLD_FRAME_RATE - if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1) - pCodecCtx->frame_rate_base=1000; - - - anim->duration = pFormatCtx->duration * pCodecCtx->frame_rate - / pCodecCtx->frame_rate_base / AV_TIME_BASE; -#else anim->duration = ceil(pFormatCtx->duration * av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate) / AV_TIME_BASE); -#endif anim->params = 0; anim->x = pCodecCtx->width; @@ -866,15 +828,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { #endif if (position != anim->curposition + 1) { -#ifdef FFMPEG_OLD_FRAME_RATE - double frame_rate = - (double) anim->pCodecCtx->frame_rate - / (double) anim->pCodecCtx->frame_rate_base; -#else double frame_rate = av_q2d(anim->pFormatCtx->streams[anim->videoStream] ->r_frame_rate); -#endif double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base); long long pos; long long st_time = anim->pFormatCtx->start_time; diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 3eed69f4c52..6e5e87d7e5c 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -63,13 +63,7 @@ #include #include -#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) -#define FFMPEG_HAVE_AV_DUMP_FORMAT 1 -#endif - -#ifndef FFMPEG_HAVE_AV_DUMP_FORMAT -#define av_dump_format dump_format -#endif +#include "ffmpeg_compat.h" #endif diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt index fb10b619f17..b544139d4a7 100644 --- a/source/gameengine/VideoTexture/CMakeLists.txt +++ b/source/gameengine/VideoTexture/CMakeLists.txt @@ -45,6 +45,7 @@ set(INC ../../../intern/string ../../../intern/moto/include ../../../intern/guardedalloc + ../../../intern/ffmpeg ${GLEW_INCLUDE_PATH} ) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 5091082e87a..b39a59e4504 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -13,6 +13,7 @@ incs += ' #source/blender/editors/include #source/blender/blenlib #source/blende incs += ' #source/blender/makesdna #source/blender/imbuf #source/blender/python #source/blender/python/generic' incs += ' #source/blender/gpu #intern/string #intern/moto/include' incs += ' #intern/guardedalloc #intern/container #extern/glew/include' +incs += ' #intern/ffmpeg' defs = [] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc','win32-mingw'): diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index 70c7a840cb8..139b90dc463 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -31,20 +31,15 @@ http://www.gnu.org/copyleft/lesser.txt. extern "C" { #undef __cplusplus #include -#include -#include -#include -#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) -#include -#endif -#include + +#include "ffmpeg_compat.h" + #include "DNA_listBase.h" #include "BLI_threads.h" #include "BLI_blenlib.h" #define __cplusplus } - #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 #else