== 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.
This commit is contained in:
Peter Schlaile 2011-05-27 23:33:40 +00:00
parent a9467182fb
commit 42121590f4
14 changed files with 152 additions and 102 deletions

@ -26,6 +26,7 @@ set(INC
FX SRC FX SRC
${PTHREADS_INC} ${PTHREADS_INC}
${LIBSAMPLERATE_INC} ${LIBSAMPLERATE_INC}
../ffmpeg
) )
set(SRC set(SRC

@ -8,7 +8,7 @@ defs = []
if env['WITH_BF_FFMPEG']: if env['WITH_BF_FFMPEG']:
sources += env.Glob('ffmpeg/*.cpp') sources += env.Glob('ffmpeg/*.cpp')
incs += ' ffmpeg ' + env['BF_FFMPEG_INC'] incs += ' ffmpeg #/intern/ffmpeg ' + env['BF_FFMPEG_INC']
defs.append('WITH_FFMPEG') defs.append('WITH_FFMPEG')
if env['WITH_BF_SDL']: if env['WITH_BF_SDL']:

@ -39,6 +39,7 @@
extern "C" { extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include "ffmpeg_compat.h"
} }
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer) int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer)

@ -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 <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/rational.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
#define FFMPEG_HAVE_PARSE_UTILS 1
#include <libavutil/parseutils.h>
#endif
#include <libswscale/swscale.h>
#include <libavcodec/opt.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
#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

@ -44,6 +44,7 @@ set(INC
../editors/include ../editors/include
../render/extern/include ../render/extern/include
../../../intern/audaspace/intern ../../../intern/audaspace/intern
../../../intern/ffmpeg
../../../intern/bsp/extern ../blenfont ../../../intern/bsp/extern ../blenfont
../../../intern/decimation/extern ../../../intern/decimation/extern
../../../intern/elbeem/extern ../../../intern/elbeem/extern

@ -14,6 +14,7 @@ incs += ' ../gpu #/extern/glew/include'
incs += ' #/intern/smoke/extern' incs += ' #/intern/smoke/extern'
incs += ' #/intern/mikktspace' incs += ' #/intern/mikktspace'
incs += ' #/intern/audaspace/intern' incs += ' #/intern/audaspace/intern'
incs += ' #/intern/ffmpeg'
incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_OPENGL_INC']
incs += ' ' + env['BF_ZLIB_INC'] incs += ' ' + env['BF_ZLIB_INC']

@ -61,34 +61,7 @@
#include "IMB_imbuf_types.h" #include "IMB_imbuf_types.h"
#include "IMB_imbuf.h" #include "IMB_imbuf.h"
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105)) #include "ffmpeg_compat.h"
#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
extern void do_init_ffmpeg(void); 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) { switch (o->type) {
case FF_OPT_TYPE_INT: case FF_OPT_TYPE_INT:
case FF_OPT_TYPE_INT64: case FF_OPT_TYPE_INT64:
#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION val.i = FFMPEG_DEF_OPT_VAL_INT(o);
val.i = o->default_val.i64;
#else
val.i = o->default_val;
#endif
idp_type = IDP_INT; idp_type = IDP_INT;
break; break;
case FF_OPT_TYPE_DOUBLE: case FF_OPT_TYPE_DOUBLE:
case FF_OPT_TYPE_FLOAT: case FF_OPT_TYPE_FLOAT:
#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
val.f = o->default_val.dbl;
#else
val.f = o->default_val;
#endif
idp_type = IDP_FLOAT; idp_type = IDP_FLOAT;
break; break;
case FF_OPT_TYPE_STRING: case FF_OPT_TYPE_STRING:

@ -38,6 +38,7 @@ set(INC
../makesdna ../makesdna
../../../intern/memutil ../../../intern/memutil
../../../intern/guardedalloc ../../../intern/guardedalloc
../../../intern/ffmpeg
${JPEG_INCLUDE_DIR} ${JPEG_INCLUDE_DIR}
${PNG_INCLUDE_DIR} ${PNG_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}

@ -5,7 +5,7 @@ sources = env.Glob('intern/*.c')
incs = '. ../makesdna #/intern/guardedalloc #/intern/memutil ../blenlib' incs = '. ../makesdna #/intern/guardedalloc #/intern/memutil ../blenlib'
incs += ' ../avi ../blenkernel ../blenloader' incs += ' ../avi ../blenkernel ../blenloader'
incs += ' #/intern/ffmpeg'
incs += ' ' + env['BF_JPEG_INC'] incs += ' ' + env['BF_JPEG_INC']
incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_PNG_INC']

@ -97,24 +97,7 @@
#include <libavutil/rational.h> #include <libavutil/rational.h>
#include <libswscale/swscale.h> #include <libswscale/swscale.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16) #include "ffmpeg_compat.h"
#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
#endif //WITH_FFMPEG #endif //WITH_FFMPEG
@ -528,18 +511,6 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
extern void do_init_ffmpeg(void); 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) { static int startffmpeg(struct anim * anim) {
int i, videoStream; int i, videoStream;
@ -573,7 +544,7 @@ static int startffmpeg(struct anim * anim) {
/* Find the first video stream */ /* Find the first video stream */
videoStream=-1; videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++) for(i=0; i<pFormatCtx->nb_streams; i++)
if(get_codec_from_stream(pFormatCtx->streams[i])->codec_type if(pFormatCtx->streams[i]->codec->codec_type
== AVMEDIA_TYPE_VIDEO) { == AVMEDIA_TYPE_VIDEO) {
videoStream=i; videoStream=i;
break; break;
@ -584,7 +555,7 @@ static int startffmpeg(struct anim * anim) {
return -1; return -1;
} }
pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]); pCodecCtx = pFormatCtx->streams[videoStream]->codec;
/* Find the decoder for the video stream */ /* Find the decoder for the video stream */
pCodec=avcodec_find_decoder(pCodecCtx->codec_id); pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
@ -600,19 +571,10 @@ static int startffmpeg(struct anim * anim) {
return -1; 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 anim->duration = ceil(pFormatCtx->duration
* av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate) * av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate)
/ AV_TIME_BASE); / AV_TIME_BASE);
#endif
anim->params = 0; anim->params = 0;
anim->x = pCodecCtx->width; anim->x = pCodecCtx->width;
@ -866,15 +828,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
#endif #endif
if (position != anim->curposition + 1) { 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 = double frame_rate =
av_q2d(anim->pFormatCtx->streams[anim->videoStream] av_q2d(anim->pFormatCtx->streams[anim->videoStream]
->r_frame_rate); ->r_frame_rate);
#endif
double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base); double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base);
long long pos; long long pos;
long long st_time = anim->pFormatCtx->start_time; long long st_time = anim->pFormatCtx->start_time;

@ -63,13 +63,7 @@
#include <libavdevice/avdevice.h> #include <libavdevice/avdevice.h>
#include <libavutil/log.h> #include <libavutil/log.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101)) #include "ffmpeg_compat.h"
#define FFMPEG_HAVE_AV_DUMP_FORMAT 1
#endif
#ifndef FFMPEG_HAVE_AV_DUMP_FORMAT
#define av_dump_format dump_format
#endif
#endif #endif

@ -45,6 +45,7 @@ set(INC
../../../intern/string ../../../intern/string
../../../intern/moto/include ../../../intern/moto/include
../../../intern/guardedalloc ../../../intern/guardedalloc
../../../intern/ffmpeg
${GLEW_INCLUDE_PATH} ${GLEW_INCLUDE_PATH}
) )

@ -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/makesdna #source/blender/imbuf #source/blender/python #source/blender/python/generic'
incs += ' #source/blender/gpu #intern/string #intern/moto/include' incs += ' #source/blender/gpu #intern/string #intern/moto/include'
incs += ' #intern/guardedalloc #intern/container #extern/glew/include' incs += ' #intern/guardedalloc #intern/container #extern/glew/include'
incs += ' #intern/ffmpeg'
defs = [] defs = []
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc','win32-mingw'): if env['OURPLATFORM'] in ('win32-vc', 'win64-vc','win32-mingw'):

@ -31,20 +31,15 @@ http://www.gnu.org/copyleft/lesser.txt.
extern "C" { extern "C" {
#undef __cplusplus #undef __cplusplus
#include <pthread.h> #include <pthread.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h> #include "ffmpeg_compat.h"
#include <libavutil/rational.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
#include <libavutil/parseutils.h>
#endif
#include <libswscale/swscale.h>
#include "DNA_listBase.h" #include "DNA_listBase.h"
#include "BLI_threads.h" #include "BLI_threads.h"
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#define __cplusplus #define __cplusplus
} }
#if LIBAVFORMAT_VERSION_INT < (49 << 16) #if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1 #define FFMPEG_OLD_FRAME_RATE 1
#else #else