FFmpegSource2 (FFMS2) is a wrapper library around ffmpeg, plus some additional components to deal with file formats libavformat has (or used to have) problems with. It gives you a convenient way to say "open and decompress this media file for me, I don't care how you do it", without having to bother with the sometimes less than straightforward and less than perfectly documented ffmpeg internals. May be frame accurate on good days. The source is MIT licensed and can be obtained from http://svn.aegisub.net/trunk/aegisub/FFmpegSource2/.
FFMS2 does not mux or encode anything. FFMS2 does not give you fine control over codec internals. FFMS2 does not let you demux raw compressed data, you get it decompressed or not at all. FFMS2 does not provide you with a good solution for realtime playback, since it needs to index the input file before you can retreive frames or audio samples. FFMS2 does not handle subtitles and is unlikely to ever do so.
Compiling the library itself is fairly straightforward, although you do need to note that some parts of the library are Windows-only, and that the source contains (in addition to the library itself) code for an Avisynth source filter and a standalone indexing application. Take a look in Makefile.am if you are confused as to which files you need to compile and which ones you can ignore.
If you are compiling with Microsoft Visual C++, you will probably want to #define FFMS_EXPORTS somewhere. You may also #define HAALISOURCE if you wish to use the MPEG-TS and OGM reading parts. Note that this part of the library is Windows-only and that using it requires that the user has the Haali Media Splitter DirectShow filter installed.
Most functions that can fail in one way or another (as well as some that should but currenlty don't) support error reporting using the ErrorMsg and MsgSize parameters. Example:
char err[1024]; unsigned errsize = sizeof(err); const AVFrameLite *frame = FFMS_GetFrame(vb, frameno, err, errsize); /* failure? */ if (frame == NULL) { printf("failed to get frame number %d, error message: %s", frameno, err); /* etc... */ }How many characters you want to allocate to the error message is up to you; if you allocate too few the messages may get truncated. 1024 should be enough for anyone.
void FFMS_Init()Initializes the FFMS2 library. This function must be called once at the start of your program, before doing any other FFMS2 function calls.
void FFMS_NoLog()Suppresses all further STDOUT/STDERR output from ffmpeg (various warnings, diagnostic messages, etc) by setting the message level to AV_LOG_QUIET (see the ffmpeg documentation for details). There is no corresponding FFMS_YesLog() function.
VideoBase *FFMS_CreateVideoSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize)Creates a VideoBase object with the given properties. The VideoBase object represents a video stream, and can be passed to other functions to retreive frames and metadata from said stream. The video stream in question must be indexed first (see the indexing functions).
const char *SourceFile
The source file to open. Can be an absolute or relative path.
int Track
The track number of the video track to open, as seen by the relevant demuxer. See FFMS_GetNumTracks, FFMS_GetTrackType and FFMS_GetFirstTrackOfType for further information on how to determine this.
FrameIndex *TrackIndices
A pointer to a FrameIndex object containing indexing information for the track you want to open.
const char *PP
A string describing the desired postprocessing. See the "PP string format" section below for details. Pass an empty string ("") to disable postprocessing.
int Threads
The number of decoding threads to use. Passing funny values like 0 or -1 may lead to undefined behavior so you better sanity check the input if you let the user set this. Values >1 have no effect if ffmpeg was not compiled with threading support.
int SeekMode
Controls how seeking (random access) is handled and hence affects frame accuracy. You will almost always want FFMS_SEEK_NORMAL. Has no effect on Matroska files, where the equivalent of FFMS_SEEK_NORMAL is always used. Valid values are:
char *ErrorMsg, unsigned MsgSize
See above.
Returns a pointer to the created VideoBase object on success. Returns NULL and sets ErrorMsg on failure.
AudioBase *FFMS_CreateAudioSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize)Does exactly the same thing as FFMS_CreateVideoSource, but for audio tracks. Arguments and return values are identical. Do note that audio support is somewhat experimental and not guaranteed to be sample-accurate.
void FFMS_DestroyVideoSource(VideoBase *VB)Deallocates the given VideoBase object and frees the memory allocated by FFMS_CreateVideoSource.
void FFMS_DestroyAudioSource(AudioBase *AB)Deallocates the given AudioBase object and frees the memory allocated by FFMS_CreateAudioSource.
const VideoProperties *FFMS_GetVideoProperties(VideoBase *VB)Retreives the video properties from the given VideoBase object and stores them in the VideoProperties struct (see the "Data Structures" section below). Returns a pointer to said struct.
const AudioProperties *FFMS_GetAudioProperties(AudioBase *AB)Retreives the audio properties from the given AudioBase object and stores them in the AudioProperties struct (see the "Data Structures" section below). Returns a pointer to said struct.
const AVFrameLite *FFMS_GetFrame(VideoBase *VB, int n, char *ErrorMsg, unsigned MsgSize)Gets a video frame from the video stream represented by the given VideoBase object and stores it in the AVFrameLite structure.
VideoBase *VB
A pointer to the VideoBase object that represents the video stream you want to retrieve a frame from.
int n
The frame number to get. Starts from 0 so the first frame is number 0, not 1. The last frame is number VideoProperties->NumFrames minus 1. Requesting a frame number beyond the stream end or before the stream start (i.e. negative) may cause undefined behavior.
char *ErrorMsg, unsigned MsgSize
See above.
Returns a pointer to the AVFrameLite on success. Returns NULL and sets ErrorMsg on failure.
const AVFrameLite *FFMS_GetFrameByTime(VideoBase *VB, double Time, char *ErrorMsg, unsigned MsgSize)Does the exact same thing as FFMS_GetFrame except instead of giving it a frame number you give it a timestamp, in seconds, and it will retrieve the frame that starts closest to that timestamp.
int FFMS_GetAudio(AudioBase *AB, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize)Decodes the requested audio samples from the audio stream represented by the given AudioBase object and stores them in the given buffer.
AudioBase *AB
A pointer to the AudioBase object that represents the audio stream you want to get samples from.
void *Buf
A pointer to the buffer where the decoded samples will end up. You are responsible for allocating and freeing this buffer yourself, so you better check the AudioProperties for the number of bits per sample, number of channels etc first, so you know how much memory you need to allocate.
int64_t Start, int64_t Count
The range of samples you want decoded. The output is Count samples long, starting from Start (inclusive). Sample numbers start from zero and end with AudioProperties->NumSamples minus 1. Requesting samples beyond the stream end or before the stream start may result in undefined behavior.
char *ErrorMsg, unsigned MsgSize
See above.
Returns 0 on success. Returns non-0 and sets ErrorMsg on failure, but you don't need to worry about that right now, because currently it has no error handling and will never fail even if the decoding breaks.
int FFMS_SetOutputFormat(VideoBase *VB, int TargetFormat, int Width, int Height, char *ErrorMsg, unsigned MsgSize)Changes the colorspace and frame dimensions to be used for output of frames from the given VideoBase by further calls to FFMS_GetFrame and FFMS_GetFrameByTime. You can change this between one frame and next without having to reinitialize anything. Can be used to convert the video to grayscale or monochrome if you are so inclined.
VideoBase *VB
A pointer to the VideoBase object that represents the video stream you want to change the output format for.
int TargetFormat
The desired output colorspace. Valid values (from libavutil/pixfmt.h):
PIX_FMT_NONE= -1, PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) PIX_FMT_GRAY8, ///< Y , 8bpp PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG) PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) PIX_FMT_BGR4, ///< packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb) PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) PIX_FMT_RGB4, ///< packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb) PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV PIX_FMT_NV21, ///< as above, but U and V bytes are swapped PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG) PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1
int Width, int Height
The desired image dimensions, in pixels. If you do not want to resize just pass the input dimensions. Passing invalid dimensions (like 0 or negative) has undefined behavior.
char *ErrorMsg, unsigned MsgSize
See above.
Returns 0 on success. Returns non-0 and sets ErrorMsg on failure.
void FFMS_ResetOutputFormat(VideoBase *VB)Resets the output format for the given VideoBase so that no conversion takes place. Is a shorthand way of saying FFMS_SetOutputFormat(VB, VideoProperties->VPixelFormat, VideoProperties->Width, VideoProperties->Height, ErrorMsg, MsgSize).
void FFMS_DestroyFrameIndex(FrameIndex *FI)Deallocates the given FrameIndex object and frees the memory that was allocated when it was created.
int FFMS_GetFirstTrackOfType(FrameIndex *TrackIndices, int TrackType, char *ErrorMsg, unsigned MsgSize)Finds the first track of the given TrackType in the given FrameIndex and returns its track number, suitable for use as an argument to FFMS_CreateVideoSource or FFMS_CreateAudioSource.
FrameIndex *TrackIndices
A pointer to the FrameIndex object that represents the media file you want to look for tracks in.
int TrackType
The track type to look for. Valid values are FFMS_TYPE_VIDEO (video track) and FFMS_TYPE_AUDIO (audio track).
char *ErrorMsg, unsigned MsgSize
See above.
Returns the track number (a number greater than or equal to 0) on success. Returns -1 and sets ErrorMsg on failure (i.e. if no track of the given type was found).
int FFMS_GetNumTracks(FrameIndex *TrackIndices)Returns the total number of tracks in the media file represented by the given FrameIndex.
int FFMS_GetTrackType(FrameInfoVector *FIV)Returns the TrackType (FFMS_TYPE_VIDEO or FFMS_TYPE_AUDIO) of the track whose indexing data is stored in the given FrameInfoVector.
int FFMS_GetNumFrames(FrameInfoVector *FIV)Returns the number of frames in the track whose indexing data is stored in the given FrameInfoVector. For a video track this is the number of video frames, which can be useful; for an audio track it's the number of "packets", which is almost never useful. A return value of 0 indicates the track has not been indexed.
const FrameInfo *FFMS_GetFrameInfo(FrameInfoVector *FIV, int Frame, char *ErrorMsg, unsigned MsgSize)Gets information about the given frame from the indexing information in the given FrameInfoVector and stores it in the FrameInfo struct. See the Data Structures section below for more information. Using this function on a FrameInfoVector containing indexing information about a non-video track has undefined behavior.
FrameInfoVector *FIV
A pointer to the FrameInfoVector object that represents the video track containing the frame you want to get information about.
int Frame
The frame number to get information about. Starts from 0 as usual. Requesting information about a frame before the start or after the end of the video track may result in undefined behavior, so don't do that.
char *ErrorMsg, unsigned MsgSize
See above.
Returns a pointer to the FrameInfo struct on success. Returns NULL and sets ErrorMsg on failure.
FrameInfoVector *FFMS_GetTITrackIndex(FrameIndex *TrackIndices, int Track, char *ErrorMsg, unsigned MsgSize)Gets indexing information about a given track from the given FrameIndex object, stores it in a FrameInfoVector object and returns it. Use this function if you don't want to (or cannot) open the track with FFMS_CreateVideoSource or FFMS_CreateAudioSource first; if you already have a VideoBase or AudioBase object it's safer to use FFMS_GetVSTrackIndex or FFMS_GetASTrackIndex (see below) instead.
FrameIndex *TrackIndices
A pointer to the FrameIndex object that represents the media file containing the track whose index information you want to get.
int Track
The track number, as seen by the relevant demuxer (see FFMS_GetNumTracks, FFMS_GetTrackType and FFMS_GetFirstTrackOfType).
char *ErrorMsg, unsigned MsgSize
See above.
Returns the FrameInfoVector on success. Returns NULL and sets ErrorMsg on failure. Note that requesting indexing information for a track that has not been indexed is not an error, it will just return an empty FrameInfoVector (check for >0 frames to see if the returned object actually contains indexing information).
FrameInfoVector *FFMS_GetVSTrackIndex(VideoBase *VB) FrameInfoVector *FFMS_GetASTrackIndex(AudioBase *AB)Gets indexing information about the track represented by the given VideoBase or AudioBase object and returns a FrameInfoVector containing said information. It's generally safer to use these functions instead of FFMS_GetTITrackIndex, since unlike that function they cannot fail or return a FrameInfoVector that doesn't actually contain any indexing information.
int FFMS_FindClosestKeyFrame(FrameInfoVector *FIV, int Frame, char *ErrorMsg, unsigned MsgSize)Searches the video track indexed by the given FrameInfoVector for the closest keyframe before the given frame and returns that keyframe's frame number. Giving this function a FrameInfoVector containing indexing information about a non-video track has undefined behavior. It would be pretty simple to implement this function yourself using a simple for loop and FFMS_GetFrameInfo; this function exists so that you won't have to do that.
FrameInfoVector *FIV
A pointer to the FrameInfoVector object that represents the video track you want to find a keyframe in.
int Frame
The frame number near which you want to find a keyframe.
char *ErrorMsg, unsigned MsgSize
See above.
Returns the frame number of the keyframe on success. Returns -1 on failure (like if you specified an out-of-bounds frame number).
const TrackTimeBase *FFMS_GetTimeBase(FrameInfoVector *FIV)Finds the time base for the track represented by the given FrameInfoVector, stores it in the TrackTimeBase struct and returns a pointer to said struct. See the Data Structures section for information about the time base; note that it is only meaningful for video tracks.
int FFMS_WriteTimecodes(FrameInfoVector *FIV, const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize)Writes Matroska v2 timecodes for the track represented by the given FrameInfoVector to the given file. Only meaningful for video tracks.
FrameInfoVector *FIV
A pointer to the FrameInfoVector object that represents the video track you want to write timecodes for.
const char *TimecodeFile
The filename to write to. Can be a relative or absolute path. The file will be truncated and overwritten if it already exists.
char *ErrorMsg, unsigned MsgSize
See above.
Returns 0 on success. Returns non-0 and sets ErrorMsg on failure.
FrameIndex *FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, const char *AudioFile, bool IgnoreDecodeErrors, IndexCallback IP, void *Private, char *ErrorMsg, unsigned MsgSize)Indexes all video tracks and the given audio tracks in the given media file and returns a FrameIndex object representing the file in question. Can also decode and write audio tracks to Wave64 files on disk while indexing.
const char *SourceFile
The filename of the media file to index. Can be a relative or absolute path.
int IndexMask, int DumpMask
Binary masks of the track numbers of the audio tracks to index and decode to disk, respectively. Pass 0 to index/decode no audio tracks, or -1 to index/decode all. Decoding a track means it will automatically be indexed regardless of what the IndexMask says, but indexing a track does not automatically mean that it will be decoded.
const char *AudioFile
The base filename of the audio file(s) to which audio will be decoded (each track will get its own file, and delay information will also be stored in the filename(s)). Can be a relative or absolute path. If the DumpMask is 0, you may pass an empty string here.
bool IgnoreDecodeErrors
If true, audio decoding errors will not cause indexing to fail. Tracks that cannot be decoded will not be indexed, however. Has no effect if the DumpMask is non-zero, in which case audio decoding errors will always cause the indexing to fail.
IndexCallback IP
A function pointer to a callback function that can be used to update progress. See Callbacks below for details.
void *Private
A pointer to an object of your choice that will be passed as an argument to the callback function. See Callbacks below for details.
char *ErrorMsg, unsigned MsgSize
See above.
This function can, if you so desire, call your code back intermittently so you can see how the indexing is progressing. This is accomplished using a function pointer to a function with the following signature:
static int FFMS_CC FunctionName(int State, int64_t Current, int64_t Total, void *Private)The callback function's arguments are as follows:
Returns a pointer to the created FrameIndex on success. Returns NULL and sets ErrorMsg on failure.
FrameIndex *FFMS_ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize)Attempts to read indexing information from the given index file. Returns the FrameIndex on success; returns NULL and sets ErrorMsg on failure.
int FFMS_WriteIndex(const char *IndexFile, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize)Writes the indexing information from the given FrameIndex to the given index file (which can be an absolute or relative path; it will be truncated and overwritten if it already exists). Returns 0 on success; returns non-0 and sets ErrorMsg on failure.
here be dragons
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, };Used in FFMS_CreateVideoSource to control the way seeking is handled. See the documentation of that function for details.
enum FFMS_TrackType { FFMS_TYPE_VIDEO = 0, FFMS_TYPE_AUDIO = 1, };Used for determining if a track contains audio or video. See FFMS_GetTrackType and FFMS_GetFirstTrackOfType.
Available postprocessing filters: Filters Options short long name short long option Description * * a autoq CPU power dependent enabler c chrom chrominance filtering enabled y nochrom chrominance filtering disabled n noluma luma filtering disabled hb hdeblock (2 threshold) horizontal deblocking filter 1. difference factor: default=32, higher -> more deblocking 2. flatness threshold: default=39, lower -> more deblocking the h & v deblocking filters share these so you can't set different thresholds for h / v vb vdeblock (2 threshold) vertical deblocking filter ha hadeblock (2 threshold) horizontal deblocking filter va vadeblock (2 threshold) vertical deblocking filter h1 x1hdeblock experimental h deblock filter 1 v1 x1vdeblock experimental v deblock filter 1 dr dering deringing filter al autolevels automatic brightness / contrast f fullyrange stretch luminance to (0..255) lb linblenddeint linear blend deinterlacer li linipoldeint linear interpolating deinterlace ci cubicipoldeint cubic interpolating deinterlacer md mediandeint median deinterlacer fd ffmpegdeint ffmpeg deinterlacer l5 lowpass5 FIR lowpass deinterlacer de default hb:a,vb:a,dr:a fa fast h1:a,v1:a,dr:a ac ha:a:128:7,va:a,dr:a tn tmpnoise (3 threshold) temporal noise reducer 1. <= 2. <= 3. larger -> stronger filtering fq forceQuantforce quantizer Usage: [: