diff options
Diffstat (limited to 'intern/ffmpeg/ffmpeg_compat.h')
-rw-r--r-- | intern/ffmpeg/ffmpeg_compat.h | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index 9c06c8a6d67..1eb6c3ba2dc 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -48,6 +48,16 @@ #include <libswscale/swscale.h> +/* Stupid way to distinguish FFmpeg from Libav: + * - FFmpeg's MICRO version starts from 100 and goes up, while + * - Libav's micro is always below 100. + */ +#if LIBAVCODEC_VERSION_MICRO >= 100 +# define AV_USING_FFMPEG +#else +# define AV_USING_LIBAV +#endif + #if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105)) # define FFMPEG_HAVE_AVIO 1 #endif @@ -428,8 +438,45 @@ void av_frame_free(AVFrame **frame) #endif FFMPEG_INLINE -AVRational av_get_r_frame_rate_compat(const AVStream *stream) +const char* av_get_metadata_key_value(AVDictionary *metadata, const char *key) { + if (metadata == NULL) { + return NULL; + } + AVDictionaryEntry *tag = NULL; + while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + if (!strcmp(tag->key, key)) { + return tag->value; + } + } + return NULL; +} + +FFMPEG_INLINE +bool av_check_encoded_with_ffmpeg(AVFormatContext *ctx) +{ + const char* encoder = av_get_metadata_key_value(ctx->metadata, "ENCODER"); + if (encoder != NULL && !strncmp(encoder, "Lavf", 4)) { + return true; + } + return false; +} + +FFMPEG_INLINE +AVRational av_get_r_frame_rate_compat(AVFormatContext *ctx, + const AVStream *stream) +{ + /* If the video is encoded with FFmpeg and we are decoding with FFmpeg + * as well it seems to be more reliable to use r_frame_rate (tbr). + * + * For other cases we fall back to avg_frame_rate (fps) when possible. + */ +#ifdef AV_USING_FFMPEG + if (av_check_encoded_with_ffmpeg(ctx)) { + return stream->r_frame_rate; + } +#endif + #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 23, 1) /* For until r_frame_rate was deprecated use it. */ return stream->r_frame_rate; |