summaryrefslogtreecommitdiff
path: root/ffms2/include
diff options
context:
space:
mode:
Diffstat (limited to 'ffms2/include')
-rw-r--r--ffms2/include/ffms.h403
-rw-r--r--ffms2/include/ffmscompat.h104
2 files changed, 507 insertions, 0 deletions
diff --git a/ffms2/include/ffms.h b/ffms2/include/ffms.h
new file mode 100644
index 0000000..3a01e3c
--- /dev/null
+++ b/ffms2/include/ffms.h
@@ -0,0 +1,403 @@
+// Copyright (c) 2007-2011 Fredrik Mellbin
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFMS_H
+#define FFMS_H
+
+// Version format: major - minor - micro - bump
+#define FFMS_VERSION ((2 << 24) | (19 << 16) | (0 << 8) | 0)
+
+#include <stdint.h>
+
+
+/********
+* The following preprocessor voodoo ensures that all API symbols are exported
+* as intended on all supported platforms, that non-API symbols are hidden (where possible),
+* and that the correct calling convention and extern declarations are used.
+* The end result should be that linking to FFMS2 Just Works.
+********/
+
+// Convenience for C++ users.
+#if defined(__cplusplus)
+# define FFMS_EXTERN_C extern "C"
+#else
+# define FFMS_EXTERN_C
+#endif
+
+// On win32, we need to ensure we use stdcall with all compilers.
+#if defined(_WIN32)
+# define FFMS_CC __stdcall
+#else
+# define FFMS_CC
+#endif
+
+// compiler-specific deprecation attributes
+#ifndef FFMS_EXPORTS
+# if defined(__GNUC__) && (__GNUC__ >= 4)
+# define FFMS_DEPRECATED __attribute__((deprecated))
+# elif defined(_MSC_VER)
+# define FFMS_DEPRECATED __declspec(deprecated)
+# endif
+#endif
+
+#ifndef FFMS_DEPRECATED
+// Define as empty if the compilter doesn't support deplcation attributes or
+// if we're building FFMS2 itself
+# define FFMS_DEPRECATED
+#endif
+
+// And now for some symbol hide-and-seek...
+#if defined(_WIN32) // MSVC
+# if defined(FFMS_EXPORTS) // building the FFMS2 library itself, with visible API symbols
+# define FFMS_API(ret) FFMS_EXTERN_C __declspec(dllexport) ret FFMS_CC
+# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED __declspec(dllexport) ret FFMS_CC
+# else // building something that depends on FFMS2
+# define FFMS_API(ret) FFMS_EXTERN_C __declspec(dllimport) ret FFMS_CC
+# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED __declspec(dllimport) ret FFMS_CC
+# endif // defined(FFMS_EXPORTS)
+// GCC 4 or later: export API symbols only. Some GCC 3.x versions support the visibility attribute too,
+// but we don't really care enough about that to add compatibility defines for it.
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define FFMS_API(ret) FFMS_EXTERN_C __attribute__((visibility("default"))) ret FFMS_CC
+# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED __attribute__((visibility("default"))) ret FFMS_CC
+#else // fallback for everything else
+# define FFMS_API(ret) FFMS_EXTERN_C ret FFMS_CC
+# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED ret FFMS_CC
+#endif // defined(_MSC_VER)
+
+
+// we now return you to your regularly scheduled programming.
+
+typedef struct FFMS_ErrorInfo {
+ int ErrorType;
+ int SubType;
+ int BufferSize;
+ char *Buffer;
+} FFMS_ErrorInfo;
+
+typedef struct FFMS_VideoSource FFMS_VideoSource;
+typedef struct FFMS_AudioSource FFMS_AudioSource;
+typedef struct FFMS_Indexer FFMS_Indexer;
+typedef struct FFMS_Index FFMS_Index;
+typedef struct FFMS_Track FFMS_Track;
+
+typedef enum FFMS_Errors {
+ // No error
+ FFMS_ERROR_SUCCESS = 0,
+
+ // Main types - where the error occurred
+ FFMS_ERROR_INDEX = 1, // index file handling
+ FFMS_ERROR_INDEXING, // indexing
+ FFMS_ERROR_POSTPROCESSING, // video postprocessing (libpostproc)
+ FFMS_ERROR_SCALING, // image scaling (libswscale)
+ FFMS_ERROR_DECODING, // audio/video decoding
+ FFMS_ERROR_SEEKING, // seeking
+ FFMS_ERROR_PARSER, // file parsing
+ FFMS_ERROR_TRACK, // track handling
+ FFMS_ERROR_WAVE_WRITER, // WAVE64 file writer
+ FFMS_ERROR_CANCELLED, // operation aborted
+ FFMS_ERROR_RESAMPLING, // audio resampling (libavresample)
+
+ // Subtypes - what caused the error
+ FFMS_ERROR_UNKNOWN = 20, // unknown error
+ FFMS_ERROR_UNSUPPORTED, // format or operation is not supported with this binary
+ FFMS_ERROR_FILE_READ, // cannot read from file
+ FFMS_ERROR_FILE_WRITE, // cannot write to file
+ FFMS_ERROR_NO_FILE, // no such file or directory
+ FFMS_ERROR_VERSION, // wrong version
+ FFMS_ERROR_ALLOCATION_FAILED, // out of memory
+ FFMS_ERROR_INVALID_ARGUMENT, // invalid or nonsensical argument
+ FFMS_ERROR_CODEC, // decoder error
+ FFMS_ERROR_NOT_AVAILABLE, // requested mode or operation unavailable in this binary
+ FFMS_ERROR_FILE_MISMATCH, // provided index does not match the file
+ FFMS_ERROR_USER // problem exists between keyboard and chair
+} FFMS_Errors;
+
+typedef enum FFMS_Sources {
+ FFMS_SOURCE_DEFAULT = 0x00,
+ FFMS_SOURCE_LAVF = 0x01,
+ FFMS_SOURCE_MATROSKA = 0x02,
+ FFMS_SOURCE_HAALIMPEG = 0x04,
+ FFMS_SOURCE_HAALIOGG = 0x08
+} FFMS_Sources;
+
+typedef enum FFMS_CPUFeatures {
+ FFMS_CPU_CAPS_MMX = 0x01,
+ FFMS_CPU_CAPS_MMX2 = 0x02,
+ FFMS_CPU_CAPS_3DNOW = 0x04,
+ FFMS_CPU_CAPS_ALTIVEC = 0x08,
+ FFMS_CPU_CAPS_BFIN = 0x10,
+ FFMS_CPU_CAPS_SSE2 = 0x20
+} FFMS_CPUFeatures;
+
+typedef enum FFMS_SeekMode {
+ FFMS_SEEK_LINEAR_NO_RW = -1,
+ FFMS_SEEK_LINEAR = 0,
+ FFMS_SEEK_NORMAL = 1,
+ FFMS_SEEK_UNSAFE = 2,
+ FFMS_SEEK_AGGRESSIVE = 3
+} FFMS_SeekMode;
+
+typedef enum FFMS_IndexErrorHandling {
+ FFMS_IEH_ABORT = 0,
+ FFMS_IEH_CLEAR_TRACK = 1,
+ FFMS_IEH_STOP_TRACK = 2,
+ FFMS_IEH_IGNORE = 3
+} FFMS_IndexErrorHandling;
+
+typedef enum FFMS_TrackType {
+ FFMS_TYPE_UNKNOWN = -1,
+ FFMS_TYPE_VIDEO,
+ FFMS_TYPE_AUDIO,
+ FFMS_TYPE_DATA,
+ FFMS_TYPE_SUBTITLE,
+ FFMS_TYPE_ATTACHMENT
+} FFMS_TrackType;
+
+typedef enum FFMS_SampleFormat {
+ FFMS_FMT_U8 = 0,
+ FFMS_FMT_S16,
+ FFMS_FMT_S32,
+ FFMS_FMT_FLT,
+ FFMS_FMT_DBL
+} FFMS_SampleFormat;
+
+typedef enum FFMS_AudioChannel {
+ FFMS_CH_FRONT_LEFT = 0x00000001,
+ FFMS_CH_FRONT_RIGHT = 0x00000002,
+ FFMS_CH_FRONT_CENTER = 0x00000004,
+ FFMS_CH_LOW_FREQUENCY = 0x00000008,
+ FFMS_CH_BACK_LEFT = 0x00000010,
+ FFMS_CH_BACK_RIGHT = 0x00000020,
+ FFMS_CH_FRONT_LEFT_OF_CENTER = 0x00000040,
+ FFMS_CH_FRONT_RIGHT_OF_CENTER = 0x00000080,
+ FFMS_CH_BACK_CENTER = 0x00000100,
+ FFMS_CH_SIDE_LEFT = 0x00000200,
+ FFMS_CH_SIDE_RIGHT = 0x00000400,
+ FFMS_CH_TOP_CENTER = 0x00000800,
+ FFMS_CH_TOP_FRONT_LEFT = 0x00001000,
+ FFMS_CH_TOP_FRONT_CENTER = 0x00002000,
+ FFMS_CH_TOP_FRONT_RIGHT = 0x00004000,
+ FFMS_CH_TOP_BACK_LEFT = 0x00008000,
+ FFMS_CH_TOP_BACK_CENTER = 0x00010000,
+ FFMS_CH_TOP_BACK_RIGHT = 0x00020000,
+ FFMS_CH_STEREO_LEFT = 0x20000000,
+ FFMS_CH_STEREO_RIGHT = 0x40000000
+} FFMS_AudioChannel;
+
+typedef enum FFMS_Resizers {
+ FFMS_RESIZER_FAST_BILINEAR = 0x0001,
+ FFMS_RESIZER_BILINEAR = 0x0002,
+ FFMS_RESIZER_BICUBIC = 0x0004,
+ FFMS_RESIZER_X = 0x0008,
+ FFMS_RESIZER_POINT = 0x0010,
+ FFMS_RESIZER_AREA = 0x0020,
+ FFMS_RESIZER_BICUBLIN = 0x0040,
+ FFMS_RESIZER_GAUSS = 0x0080,
+ FFMS_RESIZER_SINC = 0x0100,
+ FFMS_RESIZER_LANCZOS = 0x0200,
+ FFMS_RESIZER_SPLINE = 0x0400
+} FFMS_Resizers;
+
+typedef enum FFMS_AudioDelayModes {
+ FFMS_DELAY_NO_SHIFT = -3,
+ FFMS_DELAY_TIME_ZERO = -2,
+ FFMS_DELAY_FIRST_VIDEO_TRACK = -1
+} FFMS_AudioDelayModes;
+
+typedef enum FFMS_ColorSpaces {
+ FFMS_CS_RGB = 0,
+ FFMS_CS_BT709 = 1,
+ FFMS_CS_UNSPECIFIED = 2,
+ FFMS_CS_FCC = 4,
+ FFMS_CS_BT470BG = 5,
+ FFMS_CS_SMPTE170M = 6,
+ FFMS_CS_SMPTE240M = 7
+} FFMS_ColorSpaces;
+
+typedef enum FFMS_ColorRanges {
+ FFMS_CR_UNSPECIFIED = 0,
+ FFMS_CR_MPEG = 1, // 219*2^(n-8), i.e. 16-235 with 8-bit samples
+ FFMS_CR_JPEG = 2 // 2^n-1, or "fullrange"
+} FFMS_ColorRanges;
+
+typedef enum FFMS_MixingCoefficientType {
+ FFMS_MIXING_COEFFICIENT_Q8 = 0,
+ FFMS_MIXING_COEFFICIENT_Q15 = 1,
+ FFMS_MIXING_COEFFICIENT_FLT = 2
+} FFMS_MixingCoefficientType;
+
+typedef enum FFMS_MatrixEncoding {
+ FFMS_MATRIX_ENCODING_NONE = 0,
+ FFMS_MATRIX_ENCODING_DOBLY = 1,
+ FFMS_MATRIX_ENCODING_PRO_LOGIC_II = 2
+} FFMS_MatrixEncoding;
+
+typedef enum FFMS_ResampleFilterType {
+ FFMS_RESAMPLE_FILTER_CUBIC = 0,
+ FFMS_RESAMPLE_FILTER_SINC = 1,
+ FFMS_RESAMPLE_FILTER_KAISER = 2
+} FFMS_ResampleFilterType;
+
+typedef enum FFMS_AudioDitherMethod {
+ FFMS_RESAMPLE_DITHER_NONE = 0,
+ FFMS_RESAMPLE_DITHER_RECTANGULAR = 1,
+ FFMS_RESAMPLE_DITHER_TRIANGULAR = 2,
+ FFMS_RESAMPLE_DITHER_TRIANGULAR_HIGHPASS = 3,
+ FFMS_RESAMPLE_DITHER_TRIANGULAR_NOISESHAPING = 4
+} FFMS_AudioDitherMethod;
+
+typedef struct FFMS_ResampleOptions {
+ int64_t ChannelLayout;
+ FFMS_SampleFormat SampleFormat;
+ int SampleRate;
+ FFMS_MixingCoefficientType MixingCoefficientType;
+ double CenterMixLevel;
+ double SurroundMixLevel;
+ double LFEMixLevel;
+ int Normalize;
+ int ForceResample;
+ int ResampleFilterSize;
+ int ResamplePhaseShift;
+ int LinearInterpolation;
+ double CutoffFrequencyRatio;
+ FFMS_MatrixEncoding MatrixedStereoEncoding;
+ FFMS_ResampleFilterType FilterType;
+ int KaiserBeta;
+ FFMS_AudioDitherMethod DitherMethod;
+} FFMS_ResampleOptions;
+
+
+typedef struct FFMS_Frame {
+ uint8_t *Data[4];
+ int Linesize[4];
+ int EncodedWidth;
+ int EncodedHeight;
+ int EncodedPixelFormat;
+ int ScaledWidth;
+ int ScaledHeight;
+ int ConvertedPixelFormat;
+ int KeyFrame;
+ int RepeatPict;
+ int InterlacedFrame;
+ int TopFieldFirst;
+ char PictType;
+ int ColorSpace;
+ int ColorRange;
+} FFMS_Frame;
+
+typedef struct FFMS_TrackTimeBase {
+ int64_t Num;
+ int64_t Den;
+} FFMS_TrackTimeBase;
+
+typedef struct FFMS_FrameInfo {
+ int64_t PTS;
+ int RepeatPict;
+ int KeyFrame;
+} FFMS_FrameInfo;
+
+typedef struct FFMS_VideoProperties {
+ int FPSDenominator;
+ int FPSNumerator;
+ int RFFDenominator;
+ int RFFNumerator;
+ int NumFrames;
+ int SARNum;
+ int SARDen;
+ int CropTop;
+ int CropBottom;
+ int CropLeft;
+ int CropRight;
+ int TopFieldFirst;
+ FFMS_DEPRECATED int ColorSpace;
+ FFMS_DEPRECATED int ColorRange;
+ double FirstTime;
+ double LastTime;
+} FFMS_VideoProperties;
+
+typedef struct FFMS_AudioProperties {
+ int SampleFormat;
+ int SampleRate;
+ int BitsPerSample;
+ int Channels;
+ int64_t ChannelLayout; // should probably be a plain int, none of the constants are >32 bits long
+ int64_t NumSamples;
+ double FirstTime;
+ double LastTime;
+} FFMS_AudioProperties;
+
+typedef int (FFMS_CC *TIndexCallback)(int64_t Current, int64_t Total, void *ICPrivate);
+typedef int (FFMS_CC *TAudioNameCallback)(const char *SourceFile, int Track, const FFMS_AudioProperties *AP, char *FileName, int FNSize, void *Private);
+
+// Most functions return 0 on success
+// Functions without error message output can be assumed to never fail in a graceful way
+FFMS_API(void) FFMS_Init(int CPUFeatures, int UseUTF8Paths);
+FFMS_API(int) FFMS_GetVersion();
+FFMS_API(int) FFMS_GetLogLevel();
+FFMS_API(void) FFMS_SetLogLevel(int Level);
+FFMS_API(FFMS_VideoSource *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, int Threads, int SeekMode, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(void) FFMS_DestroyVideoSource(FFMS_VideoSource *V);
+FFMS_API(void) FFMS_DestroyAudioSource(FFMS_AudioSource *A);
+FFMS_API(const FFMS_VideoProperties *) FFMS_GetVideoProperties(FFMS_VideoSource *V);
+FFMS_API(const FFMS_AudioProperties *) FFMS_GetAudioProperties(FFMS_AudioSource *A);
+FFMS_API(const FFMS_Frame *) FFMS_GetFrame(FFMS_VideoSource *V, int n, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(const FFMS_Frame *) FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_SetOutputFormatV2(FFMS_VideoSource *V, const int *TargetFormats, int Width, int Height, int Resizer, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (3 << 8) | 0) */
+FFMS_API(void) FFMS_ResetOutputFormatV(FFMS_VideoSource *V);
+FFMS_API(int) FFMS_SetInputFormatV(FFMS_VideoSource *V, int ColorSpace, int ColorRange, int Format, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (17 << 16) | (1 << 8) | 0) */
+FFMS_API(void) FFMS_ResetInputFormatV(FFMS_VideoSource *V);
+FFMS_API(FFMS_ResampleOptions *) FFMS_CreateResampleOptions(FFMS_AudioSource *A); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (4 << 8) | 0) */
+FFMS_API(int) FFMS_SetOutputFormatA(FFMS_AudioSource *A, const FFMS_ResampleOptions*options, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (4 << 8) | 0) */
+FFMS_API(void) FFMS_DestroyResampleOptions(FFMS_ResampleOptions *options); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (4 << 8) | 0) */
+FFMS_API(void) FFMS_DestroyIndex(FFMS_Index *Index);
+FFMS_API(int) FFMS_GetSourceType(FFMS_Index *Index);
+FFMS_API(int) FFMS_GetSourceTypeI(FFMS_Indexer *Indexer);
+FFMS_API(int) FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_GetNumTracks(FFMS_Index *Index);
+FFMS_API(int) FFMS_GetNumTracksI(FFMS_Indexer *Indexer);
+FFMS_API(int) FFMS_GetTrackType(FFMS_Track *T);
+FFMS_API(int) FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track);
+FFMS_API(FFMS_IndexErrorHandling) FFMS_GetErrorHandling(FFMS_Index *Index);
+FFMS_API(const char *) FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track);
+FFMS_API(const char *) FFMS_GetFormatNameI(FFMS_Indexer *Indexer);
+FFMS_API(int) FFMS_GetNumFrames(FFMS_Track *T);
+FFMS_API(const FFMS_FrameInfo *) FFMS_GetFrameInfo(FFMS_Track *T, int Frame);
+FFMS_API(FFMS_Track *) FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track);
+FFMS_API(FFMS_Track *) FFMS_GetTrackFromVideo(FFMS_VideoSource *V);
+FFMS_API(FFMS_Track *) FFMS_GetTrackFromAudio(FFMS_AudioSource *A);
+FFMS_API(const FFMS_TrackTimeBase *) FFMS_GetTimeBase(FFMS_Track *T);
+FFMS_API(int) FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(FFMS_Index *) FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, int ErrorHandling, TIndexCallback IC, void *ICPrivate, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const FFMS_AudioProperties *AP, char *FileName, int FNSize, void *Private);
+FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer(const char *SourceFile, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(FFMS_Indexer *) FFMS_CreateIndexerWithDemuxer(const char *SourceFile, int Demuxer, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(FFMS_Index *) FFMS_DoIndexing(FFMS_Indexer *Indexer, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, int ErrorHandling, TIndexCallback IC, void *ICPrivate, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(void) FFMS_CancelIndexing(FFMS_Indexer *Indexer);
+FFMS_API(FFMS_Index *) FFMS_ReadIndex(const char *IndexFile, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFMS_Index *Index, FFMS_ErrorInfo *ErrorInfo);
+FFMS_API(int) FFMS_GetPixFmt(const char *Name);
+FFMS_API(int) FFMS_GetPresentSources();
+FFMS_API(int) FFMS_GetEnabledSources();
+#endif
diff --git a/ffms2/include/ffmscompat.h b/ffms2/include/ffmscompat.h
new file mode 100644
index 0000000..c43186e
--- /dev/null
+++ b/ffms2/include/ffmscompat.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2007-2011 Fredrik Mellbin
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef FFMSCOMPAT_H
+#define FFMSCOMPAT_H
+
+// Defaults to libav compatibility, uncomment (when building with msvc) to force ffmpeg compatibility.
+//#define FFMS_USE_FFMPEG_COMPAT
+
+// Attempt to auto-detect whether or not we are using ffmpeg. Newer versions of ffmpeg have their micro versions 100+
+#if LIBAVFORMAT_VERSION_MICRO > 99 || LIBAVUTIL_VERSION_MICRO > 99 || LIBAVCODEC_VERSION_MICRO > 99 || LIBSWSCALE_VERSION_MICRO > 99
+# ifndef FFMS_USE_FFMPEG_COMPAT
+# define FFMS_USE_FFMPEG_COMPAT
+# endif
+#endif
+
+// Helper to handle checking for different versions in libav and ffmpeg
+// First version is required libav versio, second is required ffmpeg version
+#ifdef FFMS_USE_FFMPEG_COMPAT
+# define VERSION_CHECK(LIB, cmp, u1, u2, u3, major, minor, micro) ((LIB) cmp (AV_VERSION_INT(major, minor, micro)))
+#else
+# define VERSION_CHECK(LIB, cmp, major, minor, micro, u1, u2, u3) ((LIB) cmp (AV_VERSION_INT(major, minor, micro)))
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW64_VERSION_MAJOR)
+# define snprintf _snprintf
+# ifdef __MINGW32__
+# define fseeko fseeko64
+# define ftello ftello64
+# else
+# define fseeko _fseeki64
+# define ftello _ftelli64
+# endif
+#endif
+
+// Compatibility with older/newer ffmpegs
+#ifdef LIBAVFORMAT_VERSION_INT
+# if VERSION_CHECK(LIBAVFORMAT_VERSION_INT, <, 53, 17, 0, 53, 25, 0)
+# define avformat_close_input(c) av_close_input_file(*c)
+# endif
+# if (LIBAVFORMAT_VERSION_INT) < (AV_VERSION_INT(54,2,0))
+# define AV_DISPOSITION_ATTACHED_PIC 0xBEEFFACE
+# endif
+#endif
+
+#ifdef LIBAVCODEC_VERSION_INT
+# undef SampleFormat
+# define FFMS_CALCULATE_DELAY (CodecContext->has_b_frames + (CodecContext->thread_count - 1))
+# if VERSION_CHECK(LIBAVCODEC_VERSION_INT, <, 54, 25, 0, 54, 51, 100)
+# define FFMS_ID(x) (CODEC_ID_##x)
+# define FFMS_CodecID CodecID
+# else
+# define FFMS_ID(x) (AV_CODEC_ID_##x)
+# define FFMS_CodecID AVCodecID
+# undef CodecID
+# endif
+# if VERSION_CHECK(LIBAVCODEC_VERSION_INT, <, 54, 28, 0, 54, 59, 100)
+static void avcodec_free_frame(AVFrame **frame) { av_freep(frame); }
+# endif
+#endif
+
+#ifdef LIBAVUTIL_VERSION_INT
+# if VERSION_CHECK(LIBAVUTIL_VERSION_INT, <, 51, 27, 0, 51, 46, 100)
+# define av_get_packed_sample_fmt(fmt) (fmt < AV_SAMPLE_FMT_U8P ? fmt : fmt - (AV_SAMPLE_FMT_U8P - AV_SAMPLE_FMT_U8))
+# endif
+# if VERSION_CHECK(LIBAVUTIL_VERSION_INT, <, 51, 44, 0, 51, 76, 100)
+# include <libavutil/pixdesc.h>
+
+# if VERSION_CHECK(LIBAVUTIL_VERSION_INT, <, 51, 42, 0, 51, 74, 100)
+# define AVPixelFormat PixelFormat
+# define AV_PIX_FMT_NB PIX_FMT_NB
+# endif
+
+static const AVPixFmtDescriptor *av_pix_fmt_desc_get(AVPixelFormat pix_fmt) {
+ if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
+ return NULL;
+
+ return &av_pix_fmt_descriptors[pix_fmt];
+}
+
+# endif
+# if VERSION_CHECK(LIBAVUTIL_VERSION_INT, <, 52, 9, 0, 52, 20, 100)
+# define av_frame_alloc avcodec_alloc_frame
+# endif
+#endif
+
+#endif // FFMSCOMPAT_H