diff options
Diffstat (limited to 'ffms2/doc')
| -rw-r--r-- | ffms2/doc/ffms2-api.html | 1029 | ||||
| -rw-r--r-- | ffms2/doc/ffms2-avisynth.html | 388 | ||||
| -rw-r--r-- | ffms2/doc/ffms2-changelog.html | 288 | ||||
| -rw-r--r-- | ffms2/doc/style.css | 60 |
4 files changed, 1765 insertions, 0 deletions
diff --git a/ffms2/doc/ffms2-api.html b/ffms2/doc/ffms2-api.html new file mode 100644 index 0000000..7cac8a9 --- /dev/null +++ b/ffms2/doc/ffms2-api.html @@ -0,0 +1,1029 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="content-type" content="text/html; charset=utf-8" /> +<title> +FFmpegSource2 API Documentation +</title> +<link href="style.css" media="screen" rel="Stylesheet" type="text/css" /> +</head> +<body> +<div class="maincontent"> +<h1>FFmpegSource2 API Documentation</h1> +<p> +FFmpegSource2 (FFMS2) is a wrapper library around Libav/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 Libav/FFmpeg internals. May be frame and/or sample accurate on good days. The library is written in C++, but the public API is C-friendly and it is possible to simply include and link directly with a pure C application.</p> + +<p>The source is MIT licensed and can be obtained from the Google Code project SVN; see <a href="http://code.google.com/p/ffmpegsource/source/checkout">http://code.google.com/p/ffmpegsource/source/checkout</a>. +</p> + + +<h2>Limitations</h2> +<p> +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 currently handle things like subtitles, file attachments or chapters. FFMS2's video frame and audio sample retrieval functions are not threadsafe; you may only have one request going at a time. +</p> + + +<h2>Compilation</h2> +<p>FFMS2 has the following dependencies:</p> +<ul> +<li><b><a href="http://www.libav.org">Libav</a></b> (sure, you can use the <b><a href="http://www.ffmpeg.org">FFmpeg</a></b> branch too if you really want) +<ul><li>At least 0.8 for libav and 0.9 for FFmpeg</li> +<li>Further recommended configuration options: <tt>--disable-debug --disable-muxers --disable-encoders --disable-filters --disable-hwaccels --disable-network --disable-devices --enable-runtime-cpudetect</tt> (runtime cpudetect in particular is a good idea if you are planning on distributing the library; not disabling debug results in a gigantic dll).</li> +</ul> +</li> +<li><b><a href="http://www.zlib.net/">zlib</a></b></li> +</ul> +<p> +Compiling the library itself is fairly straightforward. For the basics, just add the <tt>include</tt> folder to your include paths and compile everything in <tt>src/core</tt>; everything else can be skipped. <tt>src/avisynth</tt> contains code for some Avisynth filters (optional and Windows-only); <tt>src/config</tt> is some (mostly autogenerated) configuration headers; and <tt>src/index</tt> is a stand-alone indexing application (built separately and linked against the main FFMS2 library). +</p> +<h3>Windows-specific compilation notes</h3> +<p> +If you're compiling the library on Windows, it is suggested that you use the Microsoft Visual Studio 2008 solution file from SVN. Any version of MSVC2008 and MSVC2010 should work for compiling it, including the free Express Edition (but if you use that you must undefine HAALISOURCE or find a copy of the ATL libraries). The project file in question assumes that you have compiled Libav with MinGW (guides on how to do that are easy to find) and want to link FFMS2 with it statically (linking it dynamically is possible but not recommended since it usually leads to DLL hell). If you're using FFmpeg (as opposed to Libav), uncomment #define FFMS_USE_FFMPEG_COMPAT in ffmscompat.h, as this is not always automatically detected. Add your mingw/include and mingw/lib folders to MSVC's respective global directory settings (Tools menu -> Options -> Projects and Solutions -> VC++ Directories) and you should be good to go. +</p> +<p> +Targetting x64 from msvc requires a little extra work. Building libav for x64 is much like for 32-bit, except with the relevant prefix information (which will be along the lines of --prefix=/mingw/x86_64-w64-mingw32/ --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32), and --extra-cflags="-D_SYSCRT" is <b>required</b> for the end result to be linkable from msvc. Note that you'll probably need to add /usr/local/x86_64-w64-mingw32/... to MSVC's directories rather than the usual paths. +</p> +<p> +If you're using anything else, you're on your own. It's possible to build the library using MinGW; there is an avisynth plugin available that uses the avisynth_c interface originally developed to target 64-bit avisynth (it is available in <tt>branches/c_plugin</tt> in svn). If you're rolling your own MSVC solution file, remember that you need to <tt>#define FFMS_EXPORTS</tt> somewhere when compiling the library. You may also <tt>#define HAALISOURCE</tt> if you want to make the library able to open MPEG TS/PS and OGM files using Haali's DirectShow splitter (if you do not define it, those files will be opened with libavformat instead, and that usually doesn't work out all that well). Note that if you do so, opening those files will fail unless the user has the <a href="http://haali.cs.msu.ru/mkv/">Haali Media Splitter</a> DirectShow filter installed. Both those defines are enabled by default in the solution file in SVN. +</p> + + +<h2>Quickstart guide for impatient people</h2> +<p> +If you don't want to know anything about anything and just want to open some video with FFMS2 in the absolutely simplest possible manner, without selective indexing, progress reporting, saved index files, keyframe or timecode reading or anything like that, here's how to do it with the absolutely bare minimum of code.</p> + +<pre> +#include <ffms.h> +#ifdef _WIN32 +#include <objbase.h> +#endif + +int main (...) { + /* If you are on Windows you should first initialize COM, or all MPEG-TS/PS and OGM + files may return an error when you try to open them (if the library was built + with HAALISOURCE defined). All other formats will work normally. */ +#ifdef _WIN32 + bool com_inited = false; + HRESULT res = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (SUCCEEDED(res)) + com_inited = true; + else if (res != RPC_E_CHANGED_MODE) { + /* com initialization failed, handle error */ + } +#endif + + /* Initialize the library itself. */ + FFMS_Init(0, 0); + + /* Index the source file. Note that this example does not index any audio tracks. */ + char errmsg[1024]; + FFMS_ErrorInfo errinfo; + errinfo.Buffer = errmsg; + errinfo.BufferSize = sizeof(errmsg); + errinfo.ErrorType = FFMS_ERROR_SUCCESS; + errinfo.SubType = FFMS_ERROR_SUCCESS; + const char *sourcefile = "somefilename"; + FFMS_Index *index = FFMS_MakeIndex(sourcefile, 0, 0, NULL, NULL, FFMS_IEH_ABORT, NULL, NULL, &errinfo); + if (index == NULL) { + /* handle error (print errinfo.Buffer somewhere) */ + } + + /* Retrieve the track number of the first video track */ + int trackno = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &errinfo); + if (trackno < 0) { + /* no video tracks found in the file, this is bad and you should handle it */ + /* (print the errmsg somewhere) */ + } + + /* We now have enough information to create the video source object */ + FFMS_VideoSource *videosource = FFMS_CreateVideoSource(sourcefile, trackno, index, 1, FFMS_SEEK_NORMAL, &errinfo); + if (videosource == NULL) { + /* handle error (you should know what to do by now) */ + } + + /* Since the index is copied into the video source object upon its creation, + we can and should now destroy the index object. */ + FFMS_DestroyIndex(index); + + /* Retrieve video properties so we know what we're getting. + As the lack of the errmsg parameter indicates, this function cannot fail. */ + const FFMS_VideoProperties *videoprops = FFMS_GetVideoProperties(videosource); + + /* Now you may want to do something with the info, like check how many frames the video has */ + int num_frames = videoprops->NumFrames; + + /* Get the first frame for examination so we know what we're getting. This is required + because resolution and colorspace is a per frame property and NOT global for the video. */ + const FFMS_Frame *propframe = FFMS_GetFrame(videosource, 0, &errinfo); + + /* Now you may want to do something with the info; particularly interesting values are: + propframe->EncodedWidth; (frame width in pixels) + propframe->EncodedHeight; (frame height in pixels) + propframe->EncodedPixelFormat; (actual frame colorspace) + */ + + /* If you want to change the output colorspace or resize the output frame size, + now is the time to do it. IMPORTANT: This step is also required to prevent + resolution and colorspace changes midstream. You can you can always tell a frame's + original properties by examining the Encoded* properties in FFMS_Frame. */ + /* See libavutil/pixfmt.h for the list of pixel formats/colorspaces. + To get the name of a given pixel format, strip the leading PIX_FMT_ + and convert to lowercase. For example, PIX_FMT_YUV420P becomes "yuv420p". */ + + /* A -1 terminated list of the acceptable output formats. */ + int pixfmts[2]; + pixfmts[0] = FFMS_GetPixFmt("bgra"); + pixfmts[1] = -1; + + if (FFMS_SetOutputFormatV2(videosource, pixfmts, propframe->EncodedWidth, propframe->EncodedHeight, FFMS_RESIZER_BICUBIC, &errinfo)) { + /* handle error */ + } + + /* now we're ready to actually retrieve the video frames */ + int framenumber = 0; /* valid until next call to FFMS_GetFrame* on the same video object */ + const FFMS_Frame *curframe = FFMS_GetFrame(videosource, framenumber, &errinfo); + if (curframe == NULL) { + /* handle error */ + } + /* do something with curframe */ + /* continue doing this until you're bored, or something */ + + /* now it's time to clean up */ + FFMS_DestroyVideoSource(videosource); +#ifdef _WIN32 + if (com_inited) + CoUninitialize(); +#endif + + return 0; +} +</pre> + +<p> +And that's pretty much it. Easy, ain't it? +</p> + + +<h2>Indexing and You</h2> +<p> +Before opening a media file with FFMS2, you <b>must</b> index it. This is to ensure that keyframe positions, timecode data and other interesting things are known so that frame-accurate seeking is easily possible. +</p> +<p> +There are two ways to index a media file. The first one is really a backwards compatibility thing and uses <tt>FFMS_MakeIndex</tt>. You call the function with the source filename, a binary mask representing which audio tracks you want to index (all video tracks are always automatically indexed since the operation can't fail and takes no additional time), another binary mask representing which audio tracks you want to dump to Wave64 files on disk, an optional progress reporting callback and a likewise optional audio dump filename generation callback; and it will create an index object. With this method there is no way of telling ahead of time how many tracks the file has and hence the only two masks that are useful in practice are 0 (index nothing) and -1 (index everything). If you want to index only certain tracks you will have to redo the indexing after examining the index. This indexing method may be used if you only want to index video tracks, or if you want all the audio tracks regardless of how many they are, or if you already know the track layout of the file you're going to open. +</p> +<p> +The other method is a bit more sophisticated. First, you create an indexer object using <tt>FFMS_CreateIndexer</tt> and the source filename. You can then examine the indexer using <tt>FFMS_GetNumTracksI</tt>, <tt>FFMS_GetTrackTypeI</tt> and <tt>FFMS_GetCodecNameI</tt> to determine how many tracks there are and what their respective types are. When you have done so, you call <tt>FFMS_DoIndexing</tt>, which is exactly like <tt>FFMS_MakeIndex</tt> except you pass it the indexer object instead of the source filename. Since you now know the track layout, you are free to pass a more restrictive track mask to index only the tracks relevant to your interests. As with <tt>FFMS_MakeIndex</tt>, all video tracks are always indexed; the trackmask only applies to audio tracks. If you change your mind and decide there are no tracks interesting to you in the file, call <tt>FFMS_CancelIndexing</tt>. Both <tt>FFMS_DoIndexing</tt> and <tt>FFMS_CancelIndexing</tt> destroys the indexer object and frees its memory. +</p> +<p> +When you have indexed the file you can write the index object to a disk file using <tt>FFMS_WriteIndex</tt>, which is useful if you expect to open the same file more than once, since it saves you from reindexing it every time. It can be particularly time-saving with very large files or files with a lot of audio tracks, since both of those can take quite some time to index. +</p> +<p> +To create an index object from a saved disk file, use <tt>FFMS_ReadIndex</tt>. Note that the index file written has an internal version number; if you have a version of FFMS2 that isn't the same as the one that created the index, it will most likely not accept the index at all (the read function will fail). If you want to verify that a given index file actually is an index of the source file you think it is, use <tt>FFMS_IndexBelongsToFile</tt>. +</p> + + + +<h2>Function Reference</h2> +<p>Most functions that can fail in one way or another (as well as some that should be able to but currently don't) support error reporting using the <tt>ErrorInfo</tt> parameter. Example:</p> +<pre>char errmsg[1024]; +FFMS_ErrorInfo errinfo; +errinfo.Buffer = errmsg; +errinfo.BufferSize = sizeof(errmsg); +errinfo.ErrorType = FFMS_ERROR_SUCCESS; +errinfo.SubType = FFMS_ERROR_SUCCESS; + +const FFMS_Frame *frame = FFMS_GetFrame(vb, frameno, &errinfo); +/* failure? */ +if (frame == NULL) { + printf("failed to get frame number %d, error message: %s", frameno, errinfo.Buffer); + /* etc... */ +}</pre> +<p> +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. +</p> + +<h3>FFMS_Init - initializes the library</h3> +<pre>void FFMS_Init(int CPUFeatures, int UseUTF8Paths)</pre> +<p>Initializes the FFMS2 library. This function must be called once at the start of your program, before doing any other FFMS2 function calls.</p> +<p>If you are on Windows, you should also initialize COM before calling this function, since the library might have been built with <tt>HAALISOURCE</tt>. If it was indeed built with <tt>HAALISOURCE</tt> but you do not intialize COM, all MPEG-TS/PS and OGM files will cause an error when you try to open them. All other file types will work normally. Typically, you'd initialize COM something like the following:</p> +<pre>#include <objbase.h> +/* later on, in the actual code... */ +bool com_inited = false; +HRESULT res = CoInitializeEx(NULL, COINIT_MULTITHREADED); +if (SUCCEEDED(res)) + com_inited = true; +else if (res != RPC_E_CHANGED_MODE) { + /* com initialization failed, handle error */ +} +/* your code goes here */ +/* and after you're done: */ +if (com_inited) + CoUninitialize(); +</pre> +<h4>Arguments</h4> +<p><b><tt>int CPUFeatures</tt></b><br /> +This argument is no longer used and is left only for API/ABI compatibility. Pass 0. +<p><b><tt>int UseUTF8Paths</tt></b><br /> +Controls filename handling on Windows; on all other operating systems this parameter does nothing and should be ignored.<br /> +On Windows, setting this parameter to a true value will make FFMS assume that all filename strings passed to it are UTF-8 encoded; setting it to false will make it assume filenames are in the system default codepage for non-Unicode programs. Setting this to true is one of two known ways to make FFMS2 open files with filenames containing characters that are not expressible in said codepage; the other is using the short (DOS 8.3 notation) filename. You can use the Win32 API function <tt>WideCharToMultiByte()</tt> to convert your <tt>wchar_t*</tt> Unicode strings to UTF-8 in <tt>char*</tt>, if necessary.<br /> +<b>NOTE:</b> setting this parameter to true will break most file open operations if you compiled FFMS in MinGW, because MinGW's <tt>std::fstream</tt> implementation doesn't support Unicode filenames.<br /> +Prior to API version 2.14.0.0 this functionality was a compile-time option and was controlled via <tt>FFMS_USE_UTF8_PATHS</tt>.</p> + +<h3>FFMS_GetLogLevel - gets FFmpeg message level</h3> +<pre>int FFMS_GetLogLevel()</pre> +<p>Retrieves FFmpeg's current logging/message level (i.e. how much diagnostic noise it prints to <tt>STDERR</tt>). If you want to make any sense of the returned value you'd better <tt>#include <libavutil/log.h></tt> from the FFmpeg source tree to get the relevant constant definitions. Alternatively, just copy the relevant constant definitions into your own code and hope the FFmpeg devs doesn't change them randomly for no particular reason like they do with everything else. +</p> + +<h3>FFMS_SetLogLevel - sets FFmpeg message level</h3> +<pre>void FFMS_SetLogLevel(int Level)</pre> +<p>Sets FFmpeg's logging/message level; see <tt>FFMS_GetLogLevel()</tt> for details.</p> + +<h3>FFMS_CreateVideoSource - creates a video source object</h3> +<pre>FFMS_VideoSource *FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, + int Threads, int SeekMode, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Creates a <tt>FFMS_VideoSource</tt> object with the given properties. The <tt>FFMS_VideoSource</tt> 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). Note that the index object is copied into the <tt>FFMS_VideoSource</tt> object upon its creation, so once you've created the video source you can generally destroy the index object immediately, since all info you can retrieve from it is also retrievable from the <tt>FFMS_VideoSource</tt> object. +</p> +<h4>Arguments</h4> +<p><b><tt>const char *SourceFile</tt></b><br /> +The source file to open. Can be an absolute or relative path.</p> +<p><b><tt>int Track</tt></b><br /> +The track number of the video track to open, as seen by the relevant demuxer. See <tt>FFMS_GetNumTracks</tt>, <tt>FFMS_GetTrackType</tt>, <tt>FFMS_GetFirstTrackOfType</tt> and their variants for further information on how to determine this.</p> +<p><b><tt>FFMS_Index *Index</tt></b><br /> +A pointer to a FFMS_Index object containing indexing information for the track you want to open.</p> +<p><b><tt>int Threads</tt></b><br /> +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.</p> +<p><b><tt>int SeekMode</tt></b><br /> +Controls how seeking (random access) is handled and hence affects frame accuracy. You will almost always want to use <tt>FFMS_SEEK_NORMAL</tt>. Has no effect on Matroska files, where the equivalent of <tt>FFMS_SEEK_NORMAL</tt> is always used. For a list of valid values, see the Constants and Preprocessor Definitions section. <tt>FFMS_SEEK_LINEAR_NO_RW</tt> may come in handy if you want to open images.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns a pointer to the created <tt>FFMS_VideoSource</tt> object on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_CreateAudioSource - creates an audio source object</h3> +<pre>FFMS_AudioSource *FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, + FFMS_ErrorInfo *ErrorInfo)</pre> +<p> +Does exactly the same thing as <tt>FFMS_CreateVideoSource</tt>, but for audio tracks. Except for DelayMode, arguments and return values are identical. +</p> +<h4>Arguments</h4> +<p><b><tt>int DelayMode</tt></b></p> +<p>Controls how audio with a non-zero first PTS is handled; in other words what FFMS does about audio delay. Possible arguments are:</p> +<ul> + <li><b>FFMS_DELAY_NO_SHIFT:</b> No adjustment is made; the first decodable audio sample becomes the first sample in the output. May lead to audio/video desync.</li> + <li><b>FFMS_DELAY_TIME_ZERO:</b> Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at time zero.</li> + <li><b>FFMS_DELAY_FIRST_VIDEO_TRACK:</b> Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at the same time as frame 0 of the first video track. This is what most users want and is a sane default.</li> + <li><b>Any integer >= 0:</b> Identical to <tt>FFMS_DELAY_FIRST_VIDEO_TRACK</tt>, but interprets the argument as a track number and adjusts the audio relative to the video track with that number (if the given track number isn't a video track, audio source creation will fail).</li> +</ul> + +<h3>FFMS_DestroyVideoSource, FFMS_DestroyAudioSource - deallocates a video or audio source object</h3> +<pre>void FFMS_DestroyVideoSource(FFMS_VideoSource *V) +void FFMS_DestroyAudioSource(FFMS_AudioSource *A)</pre> +<p> +Deallocates the given <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object and frees the memory allocated by <tt>FFMS_CreateVideoSource</tt> or <tt>FFMS_CreateAudioSource</tt>, respectively. +</p> + +<h3>FFMS_GetVideoProperties - retrieves video properties</h3> +<pre>const FFMS_VideoProperties *FFMS_GetVideoProperties(FFMS_VideoSource *V)</pre> +<p> +Retreives the video properties from the given <tt>FFMS_VideoSource</tt> object and stores them in a <tt>FFMS_VideoProperties</tt> struct (see the Data Structures section below). Returns a pointer to said struct. +</p> + +<h3>FFMS_GetAudioProperties - retrieves audio properties</h3> +<pre>const FFMS_AudioProperties *FFMS_GetAudioProperties(FFMS_AudioSource *A)</pre> +<p>Does the exact same thing as <tt>FFMS_GetVideoProperties</tt>, but for an <tt>FFMS_AudioSource</tt> object. +</p> + +<h3>FFMS_GetFrame - retrieves a given video frame</h3> +<pre>const FFMS_Frame *FFMS_GetFrame(FFMS_VideoSource *V, int n, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Gets and decodes a video frame from the video stream represented by the given <tt>FFMS_VideoSource</tt> object and stores it in a <tt>FFMS_Frame</tt> struct. The colorspace and resolution of the frame can be changed by calling <tt>FFMS_SetOutputFormatV2</tt> with the appropriate parameters before calling this function. Note that this function is not threadsafe (you can only request one frame at a time from a given <tt>FFMS_VideoSource</tt> object) and that the returned pointer to the FFMS_Frame is a <i>const</i> pointer. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_VideoSource *V</tt></b><br /> +A pointer to the <tt>FFMS_VideoSource</tt> object that represents the video stream you want to retrieve a frame from.</p> +<p><b><tt>int n</tt></b><br /> +The frame number to get. Frame numbering starts from zero, and hence the first frame is number 0 (not 1) and the last frame is number <tt>FFMS_VideoProperties->NumFrames</tt> minus 1. Requesting a frame number beyond the stream end or before the stream start (i.e. negative) may cause undefined behavior.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns a pointer to the <tt>FFMS_Frame</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p> +<p>The returned frame is owned by the given <tt>FFMS_VideoSource</tt>, and remains valid until the video source is destroyed, a different frame is requested from the video source, or the video source's input or output format is changed. Note that while FFMS_GetFrame tends to return the same pointer with each call, it is not safe to rely on this as the output frame will sometimes be reallocated.</p> + +<h3>FFMS_GetFrameByTime - retrieves a video frame at a given timestamp</h3> +<pre>const FFMS_Frame *FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Does the exact same thing as <tt>FFMS_GetFrame</tt> 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. This function exists for the people who are too lazy to build and traverse a mapping between frame numbers and timestamps themselves. +</p> + +<h3>FFMS_GetAudio - decodes a number of audio samples</h3> +<pre>int FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Decodes the requested audio samples from the audio stream represented by the given <tt>FFMS_AudioSource</tt> object and stores them in the given buffer. Note that this function is not threadsafe; you can only request one decoding operation at a time from a given <tt>FFMS_AudioSource</tt> object. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_AudioSource *A</tt></b><br /> +A pointer to the <tt>FFMS_AudioSource</tt> object that represents the audio stream you want to get samples from.</p> +<p><b><tt>void *Buf</tt></b><br /> +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 <tt>FFMS_AudioProperties</tt> for the sample format, number of channels, channel layout etc first, so you know how much memory you need to allocate. The formula to calculate the required size of the buffer is (obviously) <tt>num_bytes = bytes_per_sample * num_channels * num_samples</tt>.</p> +<p><b><tt>int64_t Start, int64_t Count</tt></b><br /> +The range of samples you want decoded. The output is <tt>Count</tt> samples long, starting from <tt>Start</tt> (inclusive). Like video frame numbers, sample numbers start from zero and hence the last sample in the stream is number <tt>FFMS_AudioProperties->NumSamples</tt> minus 1. Requesting samples beyond the stream end or before the stream start may result in undefined behavior. +</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_SetOutputFormatV2 - sets the output format for video frames</h3> +<pre>int FFMS_SetOutputFormatV2(FFMS_VideoSource *V, int *TargetFormats, int Width, int Height, int Resizer, + FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Sets the colorspace and frame dimensions to be used for output of frames from the given <tt>FFMS_VideoSource</tt> by all further calls to <tt>FFMS_GetFrame</tt> and <tt>FFMS_GetFrameByTime</tt>, until next time you call <tt>FFMS_SetOutputFormatV2</tt> or <tt>FFMS_ResetOutputFormatV</tt>. You can change the output format at any time without having to reinitialize the <tt>FFMS_VideoSource</tt> object or anything else. Can be used to convert the video to grayscale or monochrome if you are so inclined. If you provided a list of more than one colorspace/pixelformat, you should probably check the <tt>FFMS_Frame</tt> properties afterwards to see which one got selected. And remember to do so for EVERY frame or you may get a nasty surprise. Added in version 2.16.3.0 and replaces <tt>FFMS_SetOutputFormatV</tt>. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_VideoSource *V</tt></b><br /> +A pointer to the <tt>FFMS_VideoSource</tt> object that represents the video stream you want to change the output format for.</p> +<p><b><tt>int *TargetFormats</tt></b><br /> +The desired output colorspace(s). It is a -1 terminated list of acceptable output colorspace to choose from. The destination that gives the least lossy conversion from the source colorspace will automatically be selected. ON A FRAME BASIS. To get the integer constant representing a given colorspace, see <tt>FFMS_GetPixFmt</tt>. +<br />Example:<pre>int targetformats[3]; +targetformats[0] = pixfmt1; +targetformats[1] = pixfmt2; +targetformats[2] = -1;</pre></p> +<p><b><tt>int Width, int Height</tt></b><br /> +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.</p> +<p><b><tt>int Resizer</tt></b><br /> +The desired image resizing algorithm, represented by an integer as enumerated in <tt>FFMS_Resizers</tt> (see the Constants and Preprocessor Definitions section). You must choose one even if you're not actually rescaling the image, because the video may change resolution mid-stream and then you will be using a resizer whether you want it or not (you will only know that the resolution changed after you actually decoded a frame with a new resolution), and it may also get used for rescaling subsampled chroma planes.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_ResetOutputFormatV - resets the video output format</h3> +<pre>void FFMS_ResetOutputFormatV(FFMS_VideoSource *V)</pre> +<p> +Resets the output format for the given <tt>FFMS_VideoSource</tt> object so that no conversion takes place. Note that the results of this function may vary wildly, particularly if the video changes resolution mid-stream. If you call it, you'd better call <tt>FFMS_GetFrame</tt> afterwards and examine the properties to see what you actually ended up with. +</p> + +<h3>FFMS_SetInputFormatV - override the source format for video frames</h3> +<pre>int FFMS_SetInputFormatV(FFMS_VideoSource *V, int ColorSpace, int ColorRange, int PixelFormat, + FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Override the source colorspace passed to SWScale for conversions and resizing for all further calls to <tt>FFMS_GetFrame</tt> and <tt>FFMS_GetFrameByTime</tt>, until next time you call <tt>FFMS_SetInputFormatV</tt> or <tt>FFMS_ResetInputFormatV</tt>. You can change the input format at any time without having to reinitialize the <tt>FFMS_VideoSource</tt> object or anything else. This is intended primarily for compatibility with programs which use the wrong YUV colorspace when converting to or from RGB, but can also be useful for files which have incorrect colorspace flags. Values passed are not checked for sanity; if you wish you may tell FFMS2 to pretend that a RGB files is actually YUV using this function, but doing so is unlikely to have useful results. This function only has an effect if the output format is also set with <tt>FFMS_SetOutputFormatV2</tt>. Added in version 2.17.1.0. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_VideoSource *V</tt></b><br /> +A pointer to the <tt>FFMS_VideoSource</tt> object that represents the video stream you want to change the input format for.</p> +<p><b><tt>int ColorSpace</tt></b><br /> +The desired input colorspace, or FFMS_CS_UNSPECIFIED to leave it unchanged.</p> +<p><b><tt>int ColorRange</tt></b><br /> +The desired input colorrange, or FFMS_CR_UNSPECIFIED to leave it unchanged.</p> +<p><b><tt>int PixelFormat</tt></b><br /> +The desired input pixel format; see <tt>FFMS_GetPixFmt</tt>. <tt>FFMS_GetPixFmt("")</tt> will leave the pixel format unchanged.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_ResetInputFormatV - resets the video input format</h3> +<pre>void FFMS_ResetInputFormatV(FFMS_VideoSource *V)</pre> +<p> +Resets the input format for the given <tt>FFMS_VideoSource</tt> object to the values specified in the source file. +</p> + +<h3>FFMS_DestroyIndex - deallocates an index object</h3> +<pre>void FFMS_DestroyFFMS_Index(FFMS_Index *Index)</pre> +<p>Deallocates the given <tt>FFMS_Index</tt> object and frees the memory that was allocated when it was created. +</p> + +<h3>FFMS_GetSourceType - gets which source module was used to open the given index</h3> +<pre>int FFMS_GetSourceType(FFMS_Index *Index)</pre> +<p> +Checks which source module (libavformat, Haali's Matroska parsing library, or Haali's DirectShow splitter) was used when opening the file represented by the given <tt>FFMS_Index</tt> and returns an integer (as enumerated in <tt>FFMS_Sources</tt>; see the Constants and Preprocessor Definitions section below) that represents it. +</p> + +<h3>FFMS_GetSourceTypeI - gets which source module was used to open the given indexer</h3> +<pre>int FFMS_GetSourceTypeI(FFMS_Index *Indexer)</pre> +<p> +Does the same thing as <tt>FFMS_GetSourceType</tt>, but takes an indexer instead of an index. +</p> + +<h3>FFMS_GetErrorHandling - gets which error handling mode was used when creating the given index</h3> +<pre>int FFMS_GetErrorHandling(FFMS_Index *Index)</pre> +<p> +Returns the value of the ErrorHandling parameter which was passed to FFMS_DoIndexing or FFMS_MakeIndex. +</p> + +<h3>FFMS_GetFirstTrackOfType - gets the track number of the first track of a given type</h3> +<pre>int FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Finds the first track of the given <tt>FFMS_TrackType</tt> in the given <tt>FFMS_Index</tt> and returns its track number, suitable for use as an argument to <tt>FFMS_CreateVideoSource</tt> or <tt>FFMS_CreateAudioSource</tt>, as well as to some other functions. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_Index *Index</tt></b><br /> +A pointer to the <tt>FFMS_Index</tt> object that represents the media file you want to look for tracks in.</p> +<p><b><tt>int TrackType</tt></b><br /> +The track type to look for. See <tt>FFMS_TrackType</tt> in the Constants and Preprocessor Definitions" section for valid values.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns the track number (an integer greater than or equal to 0) on success. Returns a negative integer and sets ErrorMsg on failure (i.e. if no track of the given type was found).</p> + +<h3>FFMS_GetFirstIndexedTrackOfType - gets the track number of the first track of a given type</h3> +<pre>int FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Does the exact same thing as <tt>FFMS_GetFirstTrackOfType</tt> but ignores tracks that have not been indexed. +</p> + +<h3>FFMS_GetNumTracks - gets the number of tracks in a given index</h3> +<pre>int FFMS_GetNumTracks(FFMS_Index *Index)</pre> +<p>Returns the total number of tracks in the media file represented by the given <tt>FFMS_Index</tt>. +</p> + +<h3>FFMS_GetNumTracksI - gets the number of tracks in a given indexer</h3> +<pre>int FFMS_GetNumTracksI(FFMS_Indexer *Indexer)</pre> +<p>Returns the total number of tracks in the media file represented by the given <tt>FFMS_Indexer</tt>. In other words, does the same thing as <tt>FFMS_GetNumTracks</tt> but does not require indexing the entire file first. +</p> + +<h3>FFMS_GetTrackType - gets the track type of a given track</h3> +<pre>int FFMS_GetTrackType(FFMS_Track *T)</pre> +<p>Returns an integer representing the <tt>FFMS_TrackType</tt> (see the Constants and Preprocessor Definitions section) of the track represented by the given <tt>FFMS_Track</tt> object. +</p> + +<h3>FFMS_GetTrackTypeI - gets the track type of a given track</h3> +<pre>int FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track)</pre> +<p>Returns an integer representing the <tt>FFMS_TrackType</tt> (see the Constants and Preprocessor Definitions section) of the track number <tt>Track</tt> in the media file represented by the given <tt>FFMS_Indexer</tt>. In other words, does the same thing as <tt>FFMS_GetTrackType</tt>, but does not require having indexed the file first. If you have indexed the file, use <tt>FFMS_GetTrackType</tt> instead since the <tt>FFMS_Indexer</tt> object is destructed when the index is created. Note that specifying an invalid track number may lead to undefined behavior. +</p> + +<h3>FFMS_GetCodecNameI - gets the name of the codec used for a given track</h3> +<pre>const char *FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track)</pre> +<p>Returns the human-readable name ("long name" in FFmpeg terms) of the codec used in the given track number in the media file represented by the given <tt>FFMS_Indexer</tt> object. Useful if you want to, say, pop up a menu asking the user which tracks he or she wishes to index. Note that specifying an invalid track number may lead to undefined behavior. +</p> + +<h3>FFMS_GetFormatNameI - gets the name of the container format used in the given indexer</h3> +<pre>const char *FFMS_GetFormatNameI(FFMS_Indexer *Indexer)</pre> +<p>Returns the human-readable name ("long name" in FFmpeg terms) of the container format used by the file represented by the given <tt>FFMS_Indexer</tt>. +</p> + +<h3>FFMS_GetNumFrames - gets the number of frames in a given track</h3> +<pre>int FFMS_GetNumFrames(FFMS_Track *T)</pre> +<p>Returns the number of frames in the track represented by the given <tt>FFMS_Track</tt>. 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, since nothing in the API exposes those. A return value of 0 indicates the track has not been indexed. +</p> + +<h3>FFMS_GetFrameInfo - gets information about a given frame</h3> +<pre>const FFMS_FrameInfo *FFMS_GetFrameInfo(FFMS_Track *T, int Frame)</pre> +<p>Gets information about the given frame (identified by its frame number) from the indexing information in the given <tt>FFMS_Track</tt> and stores it in a <tt>FFMS_FrameInfo</tt> struct. See the Data Structures section below for more information. Using this function on a <tt>FFMS_Track</tt> representing a non-video track has undefined behavior. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_Track *T</tt></b><br /> +A pointer to the <tt>FFMS_Track</tt> object that represents the video track containing the frame you want to get information about.</p> +<p><b><tt>int Frame</tt></b><br /> +The frame number to get information about. See <tt>FFMS_GetFrame</tt> for information about frame numbers. 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.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns a pointer to the <tt>FFMS_FrameInfo</tt> struct on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_GetTrackFromIndex - retrieves track info from an index</h3> +<pre>FFMS_Track *FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track)</pre> +<p>Gets track data for the given track number from the given <tt>FFMS_Index</tt> object, stores it in a <tt>FFMS_Track</tt> object and returns a pointer to it. Use this function if you don't want to (or cannot) open the track with <tt>FFMS_CreateVideoSource</tt> or <tt>FFMS_CreateAudioSource</tt> first. If you already have a <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object it's safer to use <tt>FFMS_GetTrackFromVideo</tt> or <tt>FFMS_GetTrackFromAudio</tt> (see below) instead. Note that specifying a nonexistent or invalid track number leads to undefined behavior (usually an access violation). Also note that the returned <tt>FFMS_Track</tt> object is only valid until its parent <tt>FFMS_Index</tt> object is destroyed. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_Index *Index</tt></b><br /> +A pointer to the <tt>FFMS_Index</tt> object that represents the media file containing the track whose index information you want to get.</p> +<p><b><tt>int Track</tt></b><br /> +The track number, as seen by the relevant demuxer (see <tt>FFMS_GetNumTracks</tt>, <tt>FFMS_GetTrackType</tt>, <tt>FFMS_GetFirstTrackOfType</tt> and their variants).</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns the <tt>FFMS_Track</tt> on success. Note that requesting indexing information for a track that has not been indexed will not cause an error, it will just return an empty <tt>FFMS_Track</tt> (check for >0 frames using <tt>FFMS_GetNumFrames</tt> to see if the returned object actually contains indexing information).</p> + +<h3>FFMS_GetTrackFromVideo, FFMS_GetTrackFromAudio - retrieves track info from audio or video source</h3> +<pre>FFMS_Track *FFMS_GetTrackFromVideo(FFMS_VideoSource *V) +FFMS_Track *FFMS_GetTrackFromAudio(FFMS_AudioSource *A)</pre> +<p>Gets information about the track represented by the given <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object and returns a pointer to a <tt>FFMS_Track</tt> object containing said information. It's generally safer to use these functions instead of <tt>FFMS_GetTrackFromIndex</tt>, since unlike that function they cannot cause access violations if you specified an nonexistent tracknumber, return a <tt>FFMS_Track</tt> that doesn't actually contain any indexing information, or return an object that ceases to be valid when the index is destroyed. Note that the returned <tt>FFMS_Track</tt> object is only valid until its parent <tt>FFMS_VideoSource</tt> or <tt>FFMS_AudioSource</tt> object is destroyed. +</p> + +<h3>FFMS_GetTimeBase - retrieves the time base for the given track</h3> +<pre>const FFMS_TrackTimeBase *FFMS_GetTimeBase(FFMS_Track *T)</pre> +<p>Finds the basic time unit for the track represented by the given <tt>FFMS_Track</tt>, stores it in a <tt>FFMS_TrackTimeBase</tt> 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. +</p> + +<h3>FFMS_WriteTimecodes - writes timecodes for the given track to disk</h3> +<pre>int FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Writes Matroska v2 timecodes for the track represented by the given <tt>FFMS_Track</tt> to the given file. Only meaningful for video tracks. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_Track *T</tt></b><br /> +A pointer to the <tt>FFMS_Track</tt> object that represents the video track you want to write timecodes for.</p> +<p><b><tt>const char *TimecodeFile</tt></b><br /> +The filename to write to. Can be a relative or absolute path. The file will be truncated and overwritten if it already exists.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Return values</h4> +<p>Returns 0 on success. Returns non-0 and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_MakeIndex - indexes a given source file</h3> +<pre>FFMS_Index *FFMS_MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, + TAudioNameCallback ANC, void *ANCPrivate, int ErrorHandling, + TIndexCallback IC, void *ICPrivate, FFMS_ErrorInfo *ErrorInfo);</pre> +<p>Indexes all video tracks and the given audio tracks in the given media file and returns a <tt>FFMS_Index</tt> object representing the file in question. Can also decode and write audio tracks to Wave64 files on disk while indexing. +</p> +<h4>Arguments</h4> +<p><b><tt>const char *SourceFile</tt></b><br /> +The filename of the media file to index. Can be a relative or absolute path.</p> +<p><b><tt>int IndexMask, int DumpMask</tt></b><br /> +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 <tt>IndexMask</tt> says, but indexing a track does not automatically mean that it will be decoded.</p> +<p><b><tt>TAudioNameCallback ANC</tt></b><br /> +A function pointer to a callback function that will generate the filename(s) for the dumped audio tracks. To get the default filename(s), pass <tt>&FFMS_DefaultAudioFilename</tt>. See <i>Callbacks</i> below for details if you want to write your own function. If the <tt>DumpMask</tt> is 0, you may pass <tt>NULL</tt> here. +</p> +<p><b><tt>void *ANCPrivate</tt></b><br /> +A pointer of your choice that will be passed as an argument to the audio filename generation callback function. See <i>Callbacks</i> below for details. If <tt>DumpMask</tt> is 0, you may pass <tt>NULL</tt> here. If you are using <tt>FFMS_DefaultAudioFilename</tt>, you must pass a format string here. See the Audio Filename Format Strings section for details. +</p> +<p><b><tt>int ErrorHandling</tt></b><br /> +Depending on the setting audio decoding errors will have different results. Use the FFMS_IEH_* constants to select the between the possible behaviors. FFMS_IEH_STOP_TRACK should be the best default to just make it work. Has no effect if the <tt>DumpMask</tt> is non-zero, in which case audio decoding errors will always cause the indexing to fail.</p> +<p><b><tt>TIndexCallback IC</tt></b><br /> +A function pointer to a callback function that can be used to update progress. See <i>Callbacks</i> below for details.</p> +<p><b><tt>void *ICPrivate</tt></b><br /> +A pointer of your choice that will be passed as an argument to the progress reporting callback function. See <i>Callbacks</i> below for details.</p> +<p><b><tt>FFMS_ErrorInfo *ErrorInfo</tt></b><br /> +See above.</p> +<h4>Callbacks</h4> +<p>This function has two potential callbacks. One 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: +</p> +<pre>int FFMS_CC FunctionName(int64_t Current, int64_t Total, void *ICPrivate)</pre> +<p> The callback function's arguments are as follows:</p> +<ul> +<li><tt><b>int64_t Current, int64_t Total</b></tt> - The indexing progress (amount done/total amount).</li> +<li><tt><b>void *Private</b></tt> - the same pointer as the one you passed as the <tt>Private</tt> argument to <tt>FFMS_MakeIndex</tt>. Can be used for anything you like, but one example (in a GUI program) is to use it for passing a progress ticker object that you can update with each call to the indexing function.</li> +</ul> +<p>Return 0 from the callback function to continue indexing, non-0 to cancel indexing (returning non-0 will make <tt>FFMS_MakeIndex</tt> fail with the reason "indexing cancelled by user"). +</p> +<p> +The other callback is used to generate the filename(s) of the audio file(s) written if <tt>DumpMask</tt> is non-zero. It has the following signature: +</p> +<pre>int FFMS_CC FunctionName(const char *SourceFile, int Track, const FFMS_AudioProperties *AP, + char *FileName, int FNSize, void *Private)</pre> +<p>The callback function is called twice for each audio file generated. The first time <tt>FileName</tt> is <tt>NULL</tt>, and you should return the number of characters your generated filename will use plus one, and do nothing else. The second time <tt>FileName</tt> is a pointer to a pre-allocated array of char; you should write your generated filename to that and return the number of characters actually written plus one. Generally the easiest way to do this in both cases is to use <tt>snprintf</tt>. See the implementation of <tt>GenAudioFilename</tt> in ffmsindex.cpp for an example on how to do it.<br /> +The callback function's arguments are as follows:</p> +<ul> +<li><tt><b>const char *SourceFile</b></tt> - The name of the source media file.</li> +<li><tt><b>int Track</b></tt> - The track number of the audio track being dumped.</li> +<li><tt><b>const FFMS_AudioProperties *AP</b></tt> - A pointer to the <tt>FFMS_AudioProperties</tt> struct containing information about the audio track being dumped. Note that the <tt>LastTime</tt> field is not defined since the last timestamp has not yet been encountered during indexing.</li> +<li><tt><b>char *FileName</b></tt> - A pointer to the string to which the callback function should write the generated filename (see above).</li> +<li><tt><b>int FNSize</b></tt> - The length of the <tt>FileName</tt> string.</li> +<li><tt><b>void *Private</b></tt> - The <tt>ANCPrivate</tt> pointer passed to <tt>FFMS_MakeIndex</tt>. Can be used to store data between calls, or to give audio tracks individual names that aren't just based on their properties.</li> +</ul> +<p>Most of the parameters may seem pointless since you don't need to use them, but they are passed so that you can easily generate a filename based on the audio track's properties if you want to. +</p> +<h4>Return values</h4> +<p>Returns a pointer to the created <tt>FFMS_Index</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_DefaultAudioFilename - default callback for audio filename generation</h3> +<p>This function generates a default audio filename for use when dumping audio tracks to disk as Wave64 files during indexing. Its only use in the public API is as a default callback for <tt>FFMS_MakeIndex</tt> and <tt>FFMS_DoIndexing</tt>; you should never call it directly. See <tt>FFMS_MakeIndex</tt> for a description of its arguments.</p> + +<h3>FFMS_CreateIndexer - creates an indexer object for the given file</h3> +<pre>FFMS_Indexer *FFMS_CreateIndexer(const char *SourceFile, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Creates a <tt>FFMS_Indexer</tt> object for the given <tt>SourceFile</tt> and returns a pointer to it. See Indexing and You for details on how to use the indexer. Is basically a shorthand for <tt>FFMS_CreateIndexerWithDemuxer(SourceFile, FFMS_SOURCE_DEFAULT, ErrorInfo)</tt>.</p> +<h4>Return values</h4> +<p>Returns a pointer to the <tt>FFMS_Indexer</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_CreateIndexerWithDemuxer - creates an indexer object for the given file, using the given source module</h3> +<pre>FFMS_Indexer *FFMS_CreateIndexer(const char *SourceFile, int Demuxer, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Creates a <tt>FFMS_Indexer</tt> object for the given <tt>SourceFile</tt> using the given <tt>Demuxer</tt> (as enumerated in <tt>FFMS_Sources</tt>) and returns a pointer to it. See Indexing and You for details on how to use the indexer.<br /> +The chosen demuxer gets used for both indexing and decoding later on. Only force one if you know what you're doing. Picking a demuxer that doesn't work on your file will not cause automatic fallback on lavf or automatic probing; it'll just cause indexer creation to fail.</p> +<h4>Return values</h4> +<p>Returns a pointer to the <tt>FFMS_Indexer</tt> on success. Returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure.</p> + +<h3>FFMS_DoIndexing - indexes the file represented by an indexer object</h3> +<pre>FFMS_Index *FFMS_DoIndexing(FFMS_Indexer *Indexer, int IndexMask, int DumpMask, + TAudioNameCallback ANC, void *ANCPrivate, int ErrorHandling, TIndexCallback IC, void *ICPrivate, + FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Does the exact same thing as <tt>FFMS_MakeIndex</tt>, but takes an indexer object instead of a source filename. Return values and arguments are identical to <tt>FFMS_MakeIndex</tt>; see that function for details. See the Indexing and You section for more details about indexing. Note that calling this function destroys the <tt>FFMS_Indexer</tt> object and frees the memory allocated by <tt>FFMS_CreateIndexer</tt> (even if indexing fails for any reason).</p> + +<h3>FFMS_CancelIndexing - destroys the given indexer object</h3> +<pre>void FFMS_CancelIndexing(FFMS_Indexer *Indexer)</pre> +<p>Destroys the given <tt>FFMS_Indexer</tt> object and frees the memory allocated by <tt>FFMS_CreateIndexer</tt>.</p> + +<h3>FFMS_ReadIndex - reads an index file from disk</h3> +<pre>FFMS_Index *FFMS_ReadIndex(const char *IndexFile, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Attempts to read indexing information from the given <tt>IndexFile</tt>, which can be an absolute or relative path. Returns the <tt>FFMS_Index</tt> on success; returns <tt>NULL</tt> and sets <tt>ErrorMsg</tt> on failure. +</p> + +<h3>FFMS_IndexBelongsToFile - check if a given index belongs to a given file</h3> +<pre>int FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Makes a heuristic (but very reliable) guess about whether the given <tt>FFMS_Index</tt> is an index of the given <tt>SourceFile</tt> or not. Useful to determine if the index object you just read with <tt>FFMS_ReadIndex</tt> is actually relevant to your interests, since the only two ways to pair up index files with source files are a) trust the user blindly, or b) comparing the filenames; neither is very reliable. +</p> +<h4>Arguments</h4> +<p><b><tt>FFMS_Index *Index</tt></b><br /> +The index object to check.</p> +<p><b><tt>const char *SourceFile</tt></b><br /> +The source file to verify the index against.</p> +<h4>Return values</h4> +<p>Returns 0 if the given index is determined to belong to the given file. Returns non-0 and sets <tt>ErrorMsg</tt> otherwise.</p> + +<h3>FFMS_WriteIndex - writes an index object to disk</h3> +<pre>int FFMS_WriteIndex(const char *IndexFile, FFMS_Index *TrackIndices, FFMS_ErrorInfo *ErrorInfo)</pre> +<p>Writes the indexing information from the given <tt>FFMS_Index</tt> to the given <tt>IndexFile</tt> (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 <tt>ErrorMsg</tt> on failure. +</p> + +<h3>FFMS_GetPixFmt - gets a colorspace identifier from a colorspace name</h3> +<pre>int FFMS_GetPixFmt(const char *Name)</pre> +<p>Translates a given colorspace/pixel format <tt>Name</tt> to an integer constant representing it, suitable for passing to <tt>FFMS_SetOutputFormatV2</tt> (after some manipulation, see that function for details). This function exists so that you don't have to include a FFmpeg header file in every single program you ever write. For a list of colorspaces and their names, see <tt>libavutil/pixfmt.h</tt>. To get the name of a colorspace, strip the leading <tt>PIX_FMT_</tt> and convert the remainder to lowercase. For example, the name of <tt>PIX_FMT_YUV420P</tt> is <tt>yuv420p</tt>. It is strongly recommended to use this function instead of including pixfmt.h directly, since this function guarantees that you will always get the constant definitions from the version of FFmpeg that FFMS2 was linked against. +</p> +<h4>Arguments</h4> +<p><b><tt>const char *Name</tt></b><br /> +The name of the desired colorspace/pixel format, as a nul-terminated ASCII string.</p> +<h4>Return values</h4> +<p>Returns the integer constant representing the given colorspace/pixel format on success. Returns the integer constant representing <tt>PIX_FMT_NONE</tt> (that is, -1) on failure (i.e. if no matching colorspace was found), but note that you can call <tt>FFMS_GetPixFmt("none")</tt> and get the same return value without it being a failed call, strictly speaking.</p> + +<h3>FFMS_GetPresentSources - checks what source modules the library was compiled with</h3> +<pre>int FFMS_GetPresentSources()</pre> +<p> +Checks which source modules the library was compiled with and returns an integer by binary OR'ing the relevant constants from <tt>FFMS_Sources</tt> together. +</p> + +<h3>FFMS_GetEnabledSources - checks what source modules are actually available for use</h3> +<pre>int FFMS_GetEnabledSources()</pre> +<p> +Does the same thing as <tt>FFMS_GetPresentSources</tt> but checks what source modules are actually available for use instead of which ones are compiled in. +</p> + +<h3>FFMS_GetVersion - returns FFMS_VERSION constant</h3> +<pre>int FFMS_GetVersion()</pre> +<p> +Returns the FFMS_VERSION constant as defined in ffms.h as an integer. +</p> + + +<h2>Data Structures</h2> +<p> +The following public data structures may be of interest. +</p> + +<h3>FFMS_Frame</h3> +<pre>typedef struct { + 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;</pre> +<p>A struct representing a video frame. The fields are:</p> +<ul> +<li><b><tt>uint8_t *Data[4]</tt></b> - An array of pointers to the picture planes (fields containing actual pixel data). Planar formats use more than one plane, for example YV12 uses one plane each for the Y, U and V data. Packed formats (such as the various RGB32 flavors) use only the first plane. If you want to determine if plane <tt>i</tt> contains data or not, check for <tt>FFMS_Frame->Linesize[i] > 0</tt>.</li> +<li><b><tt>int Linesize[4]</tt></b> - An array of integers representing the length of each scan line in each of the four picture planes, in bytes. In alternative terminology, this is the "pitch" of the plane. Usually, the total size in bytes of picture plane <tt>i</tt> is <tt>FFMS_Frame->Linesize[i] * FFMS_VideoProperties->Height</tt>, but do note that some pixel formats (most notably YV12) has vertical chroma subsampling, and then the U/V planes may be of a different height than the primary plane.</li> +<li><b><tt>int EncodedWidth; int EncodedHeight</tt></b> - The original resolution of the frame (in pixels), as encoded in the compressed file, before any scaling was applied. Note that must not necessarily be the same for all frames in a stream.</li> +<li><b><tt>int EncodedPixelFormat</tt></b> - The original pixel format of the frame, as encoded in the compressed file.</li> +<li><b><tt>int ScaledWidth; int ScaledHeight;</tt></b> - The output resolution of the frame (in pixels), i.e. the resolution of what is actually stored in the <tt>Data</tt> field. Same as <tt>FFMS_VideoProperties->Width/Height</tt>, but unlike that struct, this one gets updated automatically when you call <tt>FFMS_GetFrame</tt>, so you don't have to call <tt>FFMS_GetVideoProperties</tt> all the time to see if someone changed the output format while you weren't looking.</li> +<li><b><tt>int ConvertedPixelFormat</tt></b> - The output pixel format of the frame, i.e. the pixel format of what is actually stored in the <tt>Data</tt> field.</li> +<li><b><tt>int KeyFrame</tt></b> - Nonzero if the frame is a keyframe, 0 otherwise.</li> +<li><b><tt>int RepeatPict</tt></b> - An integer repesenting the RFF flag for this frame; i.e. the frame shall be displayed for <tt>1+RepeatPict</tt> time units, where the time units are expressed in the special RFF timebase available in <tt>FFMS_VideoProperties->RFFDenominator</tt> and <tt>FFMS_VideoProperties->RFFNumerator</tt>. Note that if you actually end up using this, you need to ignore the usual timestamps (calculated via the <tt>FFMS_TrackTimeBase</tt> and the frame PTS) since they are fundamentally incompatible with RFF flags.</li> +<li><b><tt>int InterlacedFrame</tt></b> - Nonzero if the frame was coded as interlaced, zero otherwise.</li> +<li><b><tt>int TopFieldFirst</tt></b> - Nonzero if the frame has the top field first, zero if it has the bottom field first. Only relevant if <tt>InterlacedFrame</tt> is nonzero.</li> +<li><b><tt>char PictType</tt></b> - A single character denoting coding type (I/B/P etc) of the compressed frame. See the Constants and Preprocessor Definitions section for more information about what the different letters mean.</li> +<li><b><tt>int ColorSpace</tt></b> - Identifies the YUV color coefficients used in the frame. Same as in the MPEG-2 specs; see the <tt>FFMS_ColorSpaces</tt> enum.</li> +<li><b><tt>int ColorRange</tt></b> - Identifies the luma range of the frame. See the <tt>FFMS_ColorRanges</tt> enum.</li> +</ul> + +<h3>FFMS_TrackTimeBase</h3> +<pre>typedef struct { + int64_t Num; + int64_t Den; +} FFMS_TrackTimeBase;</pre> +<p> +A struct representing the basic time unit of a track, as a rational number where <tt>Num</tt> is the numerator and <tt>Den</tt> is the denominator. Note that while this rational number may occasionally turn out to be equal to 1/framerate for some CFR video tracks, it really has no relation whatsoever with the video framerate and you should definitely not assume anything framerate-related based on it. +</p> + +<h3>FFMS_FrameInfo</h3> +<pre>typedef struct { + int64_t PTS; + int RepeatPict; + int KeyFrame; +} FFMS_FrameInfo;</pre> +<p>A struct representing basic metadata about a given video frame. The fields are:</p> +<ul> +<li><b><tt>int64_t PTS</tt></b> - The decoding timestamp of the frame. To convert this to a timestamp in wallclock milliseconds, use the relation <tt>int64_t timestamp = (int64_t)((FFMS_FrameInfo->PTS * FFMS_TrackTimeBase->Num) / (double)FFMS_TrackTimeBase->Den)</tt>.</li> +<li><b><tt>int RepeatPict</tt></b> - RFF flag for the frame; same as in <tt>FFMS_Frame</tt>, see that structure for an explanation.</li> +<li><b><tt>int KeyFrame</tt></b> - Non-zero if the frame is a keyframe, zero otherwise.</li> +</ul> + +<h3>FFMS_VideoProperties</h3> +<pre>typedef struct { + int FPSDenominator; + int FPSNumerator; + int RFFDenominator; + int RFFNumerator; + int NumFrames; + int SARNum; + int SARDen; + int CropTop; + int CropBottom; + int CropLeft; + int CropRight; + int TopFieldFirst; + int ColorSpace; <span class="deprecated">[DEPRECATED]</span> + int ColorRange; <span class="deprecated">[DEPRECATED]</span> + double FirstTime; + double LastTime; +} FFMS_VideoProperties;</pre> +<p>A struct containing metadata about a video track. The fields are:</p> +<ul> +<li><b><tt>int FPSDenominator; int FPSNumerator;</tt></b> - The nominal framerate of the track, as a rational number. For Matroska files, this number is based on the average frame duration of all frames, while for everything else it's based on the duration of the first frame. While it might seem tempting to use these values to extrapolate wallclock timestamps for each frame, you really shouldn't do that since it makes your code unable to handle variable framerate properly. The ugly reality is that these values are pretty much only useful for informational purposes; they are only somewhat reliable for antiquated containers like AVI. Normally they should never be used for practical purposes; generate individual frame timestamps from <tt>FFMS_FrameInfo->PTS</tt> instead.</li> +<li><b><tt>int RFFDenominator; int RFFNumerator;</tt></b> - The special RFF timebase, as a rational number. See <tt>RepeatPict</tt> in the <tt>FFMS_Frame</tt> documentation for more information.</li> +<li><b><tt>int NumFrames;</tt></b> - The number of frames in the video track.</li> +<li><b><tt>int SARNum; int SARDen;</tt></b> - The sample aspect ratio of the video frames, as a rational number where <tt>SARNum</tt> is the numerator and <tt>SARDen</tt> is the denominator. Note that this is a metadata setting that you are free to ignore, but if you want the proper display aspect ratio with anamorphic material, you should honor it. On the other hand, there are situations (like when encoding) where you should probably ignore it because the user expects it to be ignored.</li> +<li><b><tt>int CropTop; int CropBottom; int CropLeft; int CropRight;</tt></b> - The number of pixels in each direction you should crop the frame before displaying it. Note that like the SAR, this is a metadata setting and you are free to ignore it, but if you want things to display 100% correctly you should honor it.</li> +<li><b><tt>int TopFieldFirst</tt></b> - Nonzero if the stream has the top field first, zero if it has the bottom field first.</li> +<li><b><tt>int ColorSpace</tt></b> - Identifies the YUV color coefficients used in the stream. Same as in the MPEG-2 specs; see the <tt>FFMS_ColorSpaces</tt> enum. The ColorSpace property in FFMS_Frame should be instead of this, as this can vary between frames.</li> +<li><b><tt>int ColorRange</tt></b> - Identifies the luma range of the stream. See the <tt>FFMS_ColorRanges</tt> enum. The ColorRange property in FFMS_Frame should be instead of this, as this can vary between frames.</li> +<li><b><tt>double FirstTime; double LastTime;</tt></b> - The first and last timestamp of the stream respectively, in seconds. Useful if you want to know if the stream has a delay, or for quickly determining its length in seconds.</li> +</ul> + +<h3>FFMS_AudioProperties</h3> +<pre>typedef struct { + int SampleFormat; + int SampleRate; + int BitsPerSample; + int Channels; + int64_t ChannelLayout; + int64_t NumSamples; + double FirstTime; + double LastTime; +} FFMS_AudioProperties;</pre> +<p>A struct containing metadata about an audio track. The fields are:</p> +<ul> +<li><b><tt>int SampleFormat</tt></b> - An integer that represents the audio sample format. See <tt>FFMS_SampleFormat</tt> in the Constants and Preprocessor Definitions section.</li> +<li><b><tt>int SampleRate</tt></b> - The audio samplerate, in samples per second.</li> +<li><b><tt>int BitsPerSample</tt></b> - The number of bits per audio sample. Note that this signifies the number of bits actually used to <i>code</i> each sample, not the number of bits used to <i>store</i> each sample, and may hence be different from what the <tt>SampleFormat</tt> would imply. Figuring out which bytes are significant and which aren't is left as an exercise for the reader.</li> +<li><b><tt>int Channels</tt></b> - The number of audio channels.</li> +<li><b><tt>int64_t ChannelLayout</tt></b> - The channel layout of the audio stream. Constructed by binary OR'ing the relevant integers from <tt>FFMS_AudioChannel</tt> together, which means that if the audio has the channel <tt>FFMS_CH_EXAMPLE</tt>, the operation <tt>(ChannelOrder & FFMS_CH_EXAMPLE)</tt> will evaluate to true. The samples are interleaved in the order the channels are listed in the <tt>FFMS_AudioChannel</tt> enum; see that part of the Constants and Preprocessor Definitions sections for more details.</li> +<li><b><tt>int64_t NumSamples</tt></b> - The number of samples in the audio track.</li> +<li><b><tt>double FirstTime; double LastTime;</tt></b> - The first and last timestamp of the stream respectively, in milliseconds. Useful if you want to know if the stream has a delay, or for quickly determining its length in seconds.</li> +</ul> + + +<h2>Constants and Preprocessor Definitions</h2> +<p>The following constants and preprocessor definititions defined in ffms.h are suitable for public usage.</p> + +<h3>FFMS_Errors</h3> +<pre>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 + + // 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 +}; +</pre> +<p> +Used to identify errors. Should be self-explanatory. +</p> + +<h3>FFMS_Sources</h3> +<pre>enum FFMS_Sources { + FFMS_SOURCE_DEFAULT = 0x00, + FFMS_SOURCE_LAVF = 0x01, + FFMS_SOURCE_MATROSKA = 0x02, + FFMS_SOURCE_HAALIMPEG = 0x04, + FFMS_SOURCE_HAALIOGG = 0x08 +};</pre> +<p> +Identifies source modules. +</p> +<ul> +<li><b><tt>FFMS_SOURCE_LAVF</tt></b> - libavformat (Libav/FFmpeg)</li> +<li><b><tt>FFMS_SOURCE_MATROSKA</tt></b> - Haali's BSD-licensed native Matroska parsing library</li> +<li><b><tt>FFMS_SOURCE_HAALIMPEG</tt></b> - Haali's closed-source DirectShow splitter (MPEG TS/PS)</li> +<li><b><tt>FFMS_SOURCE_HAALIOGG</tt></b> - Haali's closed-source DirectShow splitter (Ogg/OGM)</li> +</ul> + +<h3>FFMS_CPUFeatures</h3> +<pre>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 +};</pre> +<p> +No longer used by anything in FFMS2. This enumeration will go away at some point in the future. +</p> + +<h3>FFMS_SeekMode</h3> +<pre>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 +};</pre> +<p>Used in <tt>FFMS_CreateVideoSource</tt> to control the way seeking is handled. Explanation of the values:</p> +<ul> +<li><b><tt>FFMS_SEEK_LINEAR_NO_RW</tt></b> - Linear access without rewind; i.e. will throw an error if each successive requested frame number isn't bigger than the last one. Only intended for opening images but might work on well with some obscure video format.</li> +<li><b><tt>FFMS_SEEK_LINEAR</tt></b> - Linear access (i.e. if you request frame <tt>n</tt> without having requested frames 0 to <tt>n-1</tt> in order first, all frames from 0 to <tt>n</tt> will have to be decoded before <tt>n</tt> can be delivered). The definition of slow, but should make some formats "usable".</li> +<li><b><tt>FFMS_SEEK_NORMAL</tt></b> - Safe normal. Bases seeking decisions on the keyframe positions reported by libavformat.</li> +<li><b><tt>FFMS_SEEK_UNSAFE</tt></b> - Unsafe normal. Same as <tt>FFMS_SEEK_NORMAL</tt> but no error will be thrown if the exact destination has to be guessed.</li> +<li><b><tt>FFMS_SEEK_AGGRESSIVE</tt></b> - Aggressive. Seeks in the forward direction even if no closer keyframe is known to exist. Only useful for testing and containers where libavformat doesn't report keyframes properly.</li> +</ul> + +<h3>FFMS_IndexErrorHandling</h3> +<pre>enum FFMS_IndexErrorHandling { + FFMS_IEH_ABORT = 0, + FFMS_IEH_CLEAR_TRACK = 1, + FFMS_IEH_STOP_TRACK = 2, + FFMS_IEH_IGNORE = 3 +};</pre> +<p> +Used by the indexing functions to control behavior when a decoding error is encountered. +</p> +<ul> +<li><b><tt>FFMS_IEH_ABORT</tt></b> - abort indexing and raise an error</li> +<li><b><tt>FFMS_IEH_CLEAR_TRACK</tt></b> - clear all indexing entries for the track (i.e. return a blank track)</li> +<li><b><tt>FFMS_IEH_STOP_TRACK</tt></b> - stop indexing but keep previous indexing entries (i.e. return a track that stops where the error occurred)</li> +<li><b><tt>FFMS_IEH_IGNORE</tt></b> - ignore the error and pretend it's raining</li> +</ul> + +<h3>FFMS_TrackType</h3> +<pre>enum FFMS_TrackType { + FFMS_TYPE_UNKNOWN = -1, + FFMS_TYPE_VIDEO, + FFMS_TYPE_AUDIO, + FFMS_TYPE_DATA, + FFMS_TYPE_SUBTITLE, + FFMS_TYPE_ATTACHMENT +};</pre> +<p> +Used for determining the type of a given track. Note that there are currently no functions to handle any type of track other than <tt>FFMS_TYPE_VIDEO</tt> and <tt>FFMS_TYPE_AUDIO</tt>. See <tt>FFMS_GetTrackType</tt>, <tt>FFMS_GetFirstTrackOfType</tt> and their variants. +</p> + +<h3>FFMS_SampleFormat</h3> +<pre>enum FFMS_SampleFormat { + FFMS_FMT_U8 = 0, + FFMS_FMT_S16, + FFMS_FMT_S32, + FFMS_FMT_FLT, + FFMS_FMT_DBL +};</pre> +<p>Identifies various audio sample formats.</p> +<ul> +<li><b><tt>FFMS_FMT_U8</tt></b> - One 8-bit unsigned integer (<tt>uint8_t</tt>) per sample.</li> +<li><b><tt>FFMS_FMT_S16</tt></b> - One 16-bit signed integer (<tt>int16_t</tt>) per sample.</li> +<li><b><tt>FFMS_FMT_S32</tt></b> - One 32-bit signed integer (<tt>int32_t</tt>) per sample.</li> +<li><b><tt>FFMS_FMT_FLT</tt></b> - One 32-bit (single precision) floating point value (<tt>float_t</tt>) per sample.</li> +<li><b><tt>FFMS_FMT_DBL</tt></b> - One 64-bit (double precision) floating point value (<tt>double_t</tt>) per sample.</li> +</ul> + +<h3>FFMS_AudioChannel</h3> +<pre>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 +};</pre> +<p> +Describes the audio channel layout of an audio stream. The names should be self-explanatory.<br /> +As you might have noticed, these constants are the same as the ones used for the <tt>dwChannelMask</tt> property of Microsoft's <tt>WAVEFORMATEXTENSIBLE</tt> struct; see <a href="http://msdn.microsoft.com/en-us/library/dd757714%28v=vs.85%29.aspx">its MSDN documentation page</a> for more information.<br /> +The exceptions to this convenient compatibility are <tt>FFMS_CH_STEREO_LEFT</tt> and <tt>FFMS_CH_STEREO_RIGHT</tt>, which are FFmpeg extensions. +</p> + +<h3>FFMS_Resizers</h3> +<pre>enum FFMS_Resizers { + FFMS_RESIZER_FAST_BILINEAR = 0x01, + FFMS_RESIZER_BILINEAR = 0x02, + FFMS_RESIZER_BICUBIC = 0x04, + FFMS_RESIZER_X = 0x08, + FFMS_RESIZER_POINT = 0x10, + FFMS_RESIZER_AREA = 0x20, + FFMS_RESIZER_BICUBLIN = 0x40, + FFMS_RESIZER_GAUSS = 0x80, + FFMS_RESIZER_SINC = 0x100, + FFMS_RESIZER_LANCZOS = 0x200, + FFMS_RESIZER_SPLINE = 0x400 +};</pre> +<p> +Describes various image resizing algorithms, as used in the arguments to <tt>FFMS_SetOutputFormatV2</tt>. The names should be self-explanatory. +</p> + +<h3>FFMS_AudioDelayModes</h3> +<pre>enum FFMS_AudioDelayModes { + FFMS_DELAY_NO_SHIFT = -3, + FFMS_DELAY_TIME_ZERO = -2, + FFMS_DELAY_FIRST_VIDEO_TRACK = -1 +};</pre> +<p> +Describes the different audio delay handling modes. See <tt>FFMS_CreateAudioSource</tt> for a detailed explanation. +</p> + +<h3>FFMS_ColorSpaces</h3> +<pre>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, +};</pre> +<p> +Identifies the color coefficients used for a YUV stream. The numerical constants are the same as in the MPEG-2 specification.<br /> +Some of these are specified or aliased in a number of places. Most importantly:<br /> +"BT709" (ITU-T Rec. 709) is equivalent to ITU-R BT1361, IEC 61966-2-4 xvYCC709 and SMPTE RP177 Annex B;<br /> +"BT470BG" (ITU-R BT. 470, also known as ITU-T Rec. 601) is equivalent to ITU-R BT601-6 625, ITU-R BT1358 625, ITU-R BT1700 625 PAL & SECAM and IEC 61966-2-4 xvYCC601;<br /> +"SMPTE170M" (SMPTE standard 170 M) is functionally the same as BT470BG, and is furthermore equivalent to ITU-R BT601-6 525, ITU-R BT1358 525, and ITU-R BT1700 NTSC. +</p> + +<h3>FFMS_ColorRanges</h3> +<pre>enum FFMS_ColorRanges { + FFMS_CR_UNSPECIFIED = 0, + FFMS_CR_MPEG = 1, + FFMS_CR_JPEG = 2, +};</pre> +<p> +Identifies the valid range of luma values in a YUV stream. <tt>FFMS_CR_MPEG</tt> is the standard "TV range" with head- and footroom. That is, valid luma values range from 16 to 235 with 8-bit color. <tt>FFMS_CR_JPEG</tt> is "full range"; all representable luma values are valid. +</p> + + +<h3>FFMS_CC</h3> +<pre>#ifdef _WIN32 +# define FFMS_CC __stdcall +#else +# define FFMS_CC +#endif +</pre> +<p> +The calling convention used by FFMS2 API functions and callbacks. Defined to <tt>__stdcall</tt> if <tt>_WIN32</tt> is defined. Otherwise defined, but not used. +</p> + + +<h3>Picture types</h3> +<p>As stored in <tt>FFMS_Frame->PictType</tt>:</p> +<pre>I: Intra +P: Predicted +B: Bi-dir predicted +S: S(GMC)-VOP MPEG4 +i: Switching Intra +p: Switching Predicted +b: FF_BI_TYPE (no good explanation available) +?: Unknown</pre> + + +<h2>Audio Filename Format Strings</h2> +<p>The following variables can be used:</p> +<ul> +<li><tt>%sourcefile%</tt> - same as the source file name, i.e. the file the audio is decoded from</li> +<li><tt>%trackn%</tt> - the track number</li> +<li><tt>%trackzn%</tt> - the track number zero padded to 2 digits</li> +<li><tt>%samplerate%</tt> - the audio sample rate</li> +<li><tt>%channels%</tt> - number of audio channels</li> +<li><tt>%bps%</tt> - bits per sample</li> +<li><tt>%delay%</tt> - delay, or more exactly the first timestamp encountered in the audio stream</li> +</ul> +<p> +Example string: <tt>%sourcefile%_track%trackzn%.w64</tt> +</p> + +</div> + +</body> +</html> diff --git a/ffms2/doc/ffms2-avisynth.html b/ffms2/doc/ffms2-avisynth.html new file mode 100644 index 0000000..16c1940 --- /dev/null +++ b/ffms2/doc/ffms2-avisynth.html @@ -0,0 +1,388 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="content-type" content="text/html; charset=utf-8" /> +<title> +FFmpegSource2 User Manual +</title> +<link href="style.css" media="screen" rel="Stylesheet" type="text/css" /> +</head> +<body> +<div class="maincontent"> +<h1>FFmpegSource2 User Manual</h1> +<p> +Opens files using FFmpeg and (almost) nothing else. May be frame accurate on good days. The source is MIT licensed and can be obtained from <a href="http://code.google.com/p/ffmpegsource/source/checkout">http://code.google.com/p/ffmpegsource/source/checkout</a>. The precompiled binary is GPL3 licensed. If you are religious you may consider this the second coming. +</p> + +<h2>Donate</h2> +<p> +Donate if you like this software. Collecting weird clips from the internet and making them play takes more time than you'd think. +</p> +<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> +<p> +<input type="hidden" name="cmd" value="_s-xclick" /> +<input type="hidden" name="hosted_button_id" value="6944567" /> +<input type="image" src="https://www.paypal.com/en_GB/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /> +<img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /> +</p> +</form> + + +<h2>Limitations</h2> +<ul> +<li>Requires <a href='http://haali.cs.msu.ru/mkv/'>Haali's Media Splitter</a> if you want to seek in OGM or MPEG PS/TS. Trying to do non-linear access in those containers without it will end in tears.</li> +<li>Haali's splitter requires transport streams to be cut at packet boundaries. Use <a href='http://forum.doom9.org/showthread.php?t=125447'>TsRemux</a> to fix the stream if you get an error message complaining about this.</li> +<li>Because of LAVF's demuxer, most raw streams (such as elementary h264 and other mpeg video streams) will fail to work properly.</li> +<li>FFAudioSource() will have to remake any index implicitly created by FFVideoSource() and therefore code like +<pre> +AudioDub(FFVideoSource(X), FFAudioSource(X)) +</pre> +will require two indexing passes. Apart from the time consumed this is harmless. To work around it open the audio first: +<pre> +A = FFAudioSource(X) +V = FFVideoSource(X) +AudioDub(V, A) +</pre> +or use FFIndex(), like so: +<pre> +FFIndex(X) +AudioDub(FFVideoSource(X), FFAudioSource(X)) +</pre> +</li> +</ul> + + +<h2>Known issues</h2> +<ul> +<li>Interlaced H.264 is decoded in an odd way; each field gets its own full-height frame and the fieldrate is reported as the framerate, and furthermore one of the fields (odd or even) may "jump around". To get the correct behavior, you can try setting <tt>fpsnum</tt> and <tt>fpsden</tt> so that the framerate is halved (may or may not work). This issue is caused by libavcodec.</li> +<li>Decoding some M2TS files using Haali's splitter will cause massive blocking and other corruption issues. You can work around the issue either by remuxing the file to MKV (using GDSMux (make sure you untick "minimize output file size" in the Global settings tab) or eac3to), or (if you will be doing linear decoding only) by setting <tt>demuxer="lavf"</tt> in <tt>FFIndex</tt> and using <tt>seekmode=0</tt> with <tt>FFVideoSource</tt>. The cause of this issue is unknown but being investigated.</li> +</ul> + + +<h2>Compatibility</h2> +<h3>Video</h3> +<ul> +<li>AVI, MKV, MP4, FLV: Frame accurate</li> +<li>WMV: Frame accurate(?) but avformat seems to pick keyframes relatively far away</li> +<li>OGM: Frame accurate(?)</li> +<li>VOB, MPG: Seeking seems to be off by one or two frames now and then</li> +<li>M2TS, TS: Seeking seems to be off a few frames here and there</li> +<li>Image files: Most formats can be opened if seekmode=-1 is set, no animation support</li> +</ul> + +<h3>Audio</h3> +<p>Seeking should be sample-accurate with most codecs in AVI, MKV, MP4 and FLV with two notable exceptions, namely <b>MP3</b> and <b>AC3</b> where FFmpeg's decoders seem to be completely broken (with MP3 in particular you can feed the decoder the same encoded data three times in a row and get a different decoded result every time). Still, results should usually be "good enough" for most purposes.</p> +<p>Decoding linearly will almost always work correctly.</p> + +<h2>Indexing and You</h2> +<p>Before FFMS2 can open a file, it must be indexed first so that keyframe/sample positions are known and seeking is easily accomplished. This is done automatically when using <tt>FFVideoSource()</tt> or <tt>FFAudioSource()</tt>, but if you want to you can invoke the indexing yourself by calling <tt>FFIndex()</tt>, or by running <tt>ffmsindex.exe</tt>. By default the index is written to a file so it can be reused the next time you open the same file, but this behavior can be turned off if desired.</p> +<p>If you wonder why FFMS2 takes so long opening files, the indexing is the answer. If you want a progress report on the indexing, you can use the supplied <tt>ffmsindex.exe</tt> commandline program.</p> + + +<div class="avisynth-functionref"> +<h2>Function reference</h2> +<h3>FFIndex</h3> +<pre> +FFIndex(string source, string cachefile = source + ".ffindex", int indexmask = -1, + int dumpmask = 0, string audiofile = "%sourcefile%.%trackzn%.w64", int errorhandling = 3, + bool overwrite = false, bool utf8 = false, string demuxer = "default") +</pre> +<p> +Indexes a number of tracks in a given source file and writes the index file to disk, where it can be picked up and used by <tt>FFVideoSource</tt> or <tt>FFAudioSource</tt>. Normally you do not need to call this function manually; it's invoked automatically if necessary by <tt>FFVideoSource</tt>/<tt>FFAudioSource</tt>. It does, however, give you more control over how indexing is done and it can also dump audio tracks to WAVE64 files while indexing is in progress. +</p> +<p> +Note that this function returns an integer, not a clip (since it doesn't open video, nor audio). The return value isn't particularly interesting, but for the record it's 0 if the index file already exists (and is valid) and overwrite was not enabled, 1 if the index file was created and no previous index existed, and 2 if the index file was created by overwriting an existing, valid index file. +</p> + +<h4>Arguments</h4> +<dl> +<dt>string source</dt> +<dd>The source file to index.</dd> + +<dt>string cachefile = source + ".ffindex"</dt> +<dd>The filename of the index file (where the indexing data is saved). Defaults to <tt>sourcefilename.ffindex</tt>.</dd> + +<dt>int indexmask = -1</dt> +<dd> +A binary mask representing what audio tracks should be indexed (all video tracks are always indexed; you have no choice in the matter). The mask is constructed by bitshifting 1 left by the track number; if multiple tracks are desired, bitwise OR each value so created together to get the full mask. In other words, the mask is a bit field where each bit is a track number (the least significant bit is track number 0). Since Avisynth doesn't have any bitwise operators at all, constructing a mask for more than one track inside an Avisynth script is a rather annoying task; for a single track the mask is, naturally, 2 to the power of the track number minus 1 (i.e. if you want to index track 3, the mask is <tt>2^(3-1) = 4</tt>).<br /> +Since the mask works like it does, and FFMS2 is designed to run on a machine that uses two's complement integers, -1 (the default) means index all tracks and 0 means index none.<br /> +Note that FFMS2's idea about what track has what number may be completely different from what any other application might think, and that track numbering starts from 1. +</dd> + +<dt>int dumpmask = 0</dt> +<dd> +The same as indexmask, but the tracks flagged by this mask are dumped to disk as decompressed Wave64 files. This mask overrides indexmask if set to nonzero (more specifically, they are bitwise OR'ed together), since dumping a track indexes it at the same time. +</dd> + +<dt>string audiofile = "%sourcefile%.%trackzn%.w64"</dt> +<dd>A string representing a filename template that determines where the audio tracks set to be dumped by the <tt>dumpmask</tt> will be written. You can use a number of variables here; make sure you include a track number variable if you're dumping multiple tracks, or you'll get really weird results when FFMS2 tries to write multiple tracks to the same file. Available variables: +<ul> +<li><b>%sourcefile%</b> - same as the source argument, i.e. the file the audio is decoded from</li> +<li><b>%trackn%</b> - the track number</li> +<li><b>%trackzn%</b> - the track number, zero padded to two digits</li> +<li><b>%samplerate%</b> - sample rate in Hertz</li> +<li><b>%channels%</b> - number of channels</li> +<li><b>%bps%</b> - bits per sample</li> +<li><b>%delay%</b> - delay, or more exactly the first timestamp encountered in the audio stream</li> +</ul> +</dd> + +<dt>int errorhandling = 3</dt> +<dd> +Controls what happens if an audio decoding error is encountered during indexing. Possible values are: +<ul> +<li><b>0:</b> Raise an error and abort indexing. No index file is written.</li> +<li><b>1:</b> Clear the affected track (effectively making it silent) and continue.</li> +<li><b>2:</b> Stop indexing the track but keep all the index entries so far, effectively ending the track where the error occured.</li> +<li><b>3:</b> Pretend it's raining and continue anyway. This is the default; if you encounter odd noises in the audio, try mode 0 instead and see if it's FFMS2's fault.</li> +</ul> +</dd> + +<dt>bool overwrite = false</dt> +<dd>If set to true, <tt>FFIndex()</tt> will reindex the source file and overwrite the index file even if the index file already exists and is valid. Mostly useful for trackmask changes and testing.</dd> + +<dt>bool utf8 = false</dt> +<dd> +If set to true, FFMS will assume that the .avs script is encoded as UTF-8 and therefore interpret all filenames as UTF-8 encoded strings. This makes it possible to open files with funny filenames that otherwise would not be openable. You only need to set this parameter on the first FFMS2 function you call in a script; subsequent uses will have no further effect.<br /> +<b>NOTE:</b> You must make sure you save the file without a BOM (byte-order marker) or Avisynth will refuse to open it. Notepad will write a BOM, so use something else.<br /> +You should also note that setting this parameter incorrectly will cause all file openings to fail unless your filenames are exclusively 7-bit ASCII compatible. +</dd> + +<dt>string demuxer = "default"</dt> +<dd> +Forces FFMS to use a given demuxer, namely one of: +<ul> + <li><b>default</b>: probe for the best source module, i.e. choose automatically. This is the default (duh).</li> + <li><b>lavf</b>: use libavformat.</li> + <li><b>matroska</b>: use Haali's Matroska parser. Obviously only works for Matroska and WebM files.</li> + <li><b>haalimpeg</b>: use Haali's DirectShow MPEG TS/PS parser. Only works if Haali Media Splitter is installed and only on MPEG TS/PS files (.ts/.m2ts/.mpg/.mpeg).</li> + <li><b>haaliogg:</b> use Haali's DirectShow Ogg parser. As above, only works if Haali Media Splitter is installed, and only on Ogg files (.ogg/.ogm).</li> +</ul> +You should only use this parameter if you know exactly what you're doing and exactly why you want to force another demuxer. +</dd> +</dl> + + +<h3>FFVideoSource</h3> +<pre> +FFVideoSource(string source, int track = -1, bool cache = true, + string cachefile = source + ".ffindex", int fpsnum = -1, int fpsden = 1, + int threads = -1, string timecodes = "", int seekmode = 1, int rffmode = 0, + int width = -1, int height = -1, string resizer = "BICUBIC", + string colorspace = "", bool utf8 = false, string varprefix = "") +</pre> +<p> +Opens video. Will invoke indexing of all video tracks (but no audio tracks) if no valid index file is found. +</p> + +<h4>Arguments</h4> +<dl> +<dt>string source</dt> +<dd>The source file to open.</dd> + +<dt>int track = -1</dt> +<dd>The video track number to open, as seen by the relevant demuxer. Track numbers start from zero, and are guaranteed to be countinous (i.e. there must be a track 1 if there is a track 0 and a track 2). -1 means open the first video track. Note that FFMS2's idea about what track has what number may (or may not) be completely different from what some other application might think. Trying to open an audio track with <tt>FFVideoSource</tt> will naturally fail.</dd> + +<dt>bool cache = true</dt> +<dd>If set to true (the default), <tt>FFVideoSource</tt> will first check if the <tt>cachefile</tt> contains a valid index, and if it does, that index will be used. If no index is found, all video tracks will be indexed, and the indexing data will be written to <tt>cachefile</tt> afterwards. If set to false, <tt>FFVideoSource</tt> not look for an existing index file; instead all video tracks will be indexed when the script is opened, and the indexing data will be discarded after the script is closed; you will have to index again next time you open the script.</dd> + +<dt>string cachefile = source + ".ffindex"</dt> +<dd>The filename of the index file (where the indexing data is saved). Defaults to <tt>sourcefilename.ffindex</tt>. Note that if you didn't change this parameter from its default value and <tt>FFVideoSource</tt> encounters an index file that doesn't seem to match the file it's trying to open, it will automatically reindex and then overwrite the old index file. On the other hand, if you <em>do</em> change it, <tt>FFVideoSource</tt> will assume you have your reasons and throw an error instead if the index doesn't match the file.</dd> + +<dt>int fpsnum = -1, int fpsden = 1</dt> +<dd>Controls the framerate of the output; used for VFR to CFR conversions. If <tt>fpsnum</tt> is less than or equal to zero (the default), the output will contain the same frames that the input did, and the frame rate reported to Avisynth will be set based on the input clip's average frame duration. If <tt>fpsnum</tt> is greater than zero, <tt>FFVideoSource</tt> will force a constant frame rate, expressed as a rational number where <tt>fpsnum</tt> is the numerator and <tt>fpsden</tt> is the denominator. This may naturally cause <tt>FFVideoSource</tt> to drop or duplicate frames to achieve the desired frame rate, and the output is not guaranteed to have the same number of frames that the input did.</dd> + +<dt>int threads = -1</dt> +<dd>The number of decoding threads to request from libavcodec. Setting it to less than or equal to zero means it defaults to the number of logical CPU's reported by Windows. Note that this setting might be completely ignored by libavcodec under a number of conditions; most commonly because a lot of decoders actually do not support multithreading.</dd> + +<dt>string timecodes = ""</dt> +<dd>Filename to write Matroska v2 timecodes for the opened video track to. If the file exists, it will be truncated and overwritten. Set to the empty string to disable timecodes writing (this is the default).</dd> + +<dt>int seekmode = 1</dt> +<dd>Controls how seeking is done. Mostly useful for getting uncooperative files to work. Only has an effect on files opened with the libavformat demuxer; on other files the equivalent of mode 1 is always used. Valid modes are: +<ul> +<li><b>-1:</b> Linear access without rewind; i.e. will throw an error if each successive requested frame number isn't bigger than the last one. Only intended for opening images but might work on well with some obscure video format.</li> +<li><b>0:</b> Linear access (i.e. if you request frame <tt>n</tt> without having requested all frames from 0 to <tt>n-1</tt> in order first, all frames from 0 to <tt>n</tt> will have to be decoded before <tt>n</tt> can be delivered). The definition of slow, but should make some formats "usable".</li> +<li><b>1:</b> Safe normal. Bases seeking decisions on the keyframe positions reported by libavformat.</li> +<li><b>2:</b> Unsafe normal. Same as mode 1, but no error will be thrown if the exact seek destination has to be guessed.</li> +<li><b>3:</b> Aggressive. Seeks in the forward direction even if no closer keyframe is known to exist. Only useful for testing and containers where libavformat doesn't report keyframes properly.</li> +</ul> +</dd> + +<dt>int rffmode = 0</dt> +<dd>Controls how RFF flags in the video stream are treated; in other words it's equivalent to the "field operation" mode switch in DVD2AVI/DGIndex. Valid modes are: +<ul> +<li><b>0:</b> Ignore all flags (the default mode).</li> +<li><b>1:</b> Honor all pulldown flags.</li> +<li><b>2:</b> Equivalent to DVD2AVI's "force film" mode.</li> +</ul> +Note that using modes 1 or 2 will make <tt>FFVideoSource</tt> throw an error if the video stream has no RFF flags at all. When using either of those modes, it will also make the output be assumed as CFR, disallow vertical scaling and disallow setting the output colorspace. <tt>FFPICT_TYPE</tt> will also not be set as the output is a combination of several frames. Other subtle behavior changes may also exist.<br /> +Also note that "force film" is mostly useless and only here for completeness' sake, since if your source really is safe to force film on, using mode 0 will have the exact same effect while being considerably more efficient.</dd> + +<dt>int width = -1, int height = -1</dt> +<dd>Sets the resolution of the output video, in pixels. Setting either dimension to less than or equal to zero means the resolution of the first decoded video frame is used for that dimension. These parameters are mostly useful because FFMS2 supports video streams that change resolution mid-stream; since Avisynth does not, these parameters are used to set single resolution for the output.</dd> + +<dt>string resizer = "BICUBIC"</dt> +<dd>The resizing algorithm to use if rescaling the image is necessary. If the video uses subsampled chroma but your chosen output colorspace does not, the chosen resizer will be used to upscale the chroma planes, even if you did not request an image rescaling. The available choices are <tt>FAST_BILINEAR</tt>, <tt>BILINEAR</tt>, <tt>BICUBIC</tt> (default), <tt>X</tt>, <tt>POINT</tt>, <tt>AREA</tt>, <tt>BICUBLIN</tt>, <tt>GAUSS</tt>, <tt>SINC</tt>, <tt>LANCZOS</tt> and <tt>SPLINE</tt>. Note that <tt>SPLINE</tt> is completely different from Avisynth's builtin Spline resizers.</dd> + +<dt>string colorspace = ""</dt> +<dd>Convert the output from whatever it was to the given colorspace, which can be one of <tt>YV12</tt>, <tt>YUY2</tt>, <tt>RGB24</tt> or <tt>RGB32</tt>. Setting this to an empty string (the default) means keeping the same colorspace as the input.</dd> + +<dt>bool utf8 = false</dt> +<dd>Does the same thing as in <tt>FFIndex()</tt>; see that function for details.</dd> + +<dt>string varprefix = ""</dt> +<dd>A string that is added as a prefix to all exported Avisynth variables. This makes it possible to differentiate between variables from different clips. For convenience the last used FFMS function in a script sets the global variable <tt>FFVAR_PREFIX</tt> to its own variable prefix so that <tt>FFInfo()</tt> can default to it.</dd> + +</dl> + + +<h3>FFAudioSource</h3> +<pre> +FFAudioSource(string source, int track = -1, bool cache = true, + string cachefile = source + ".ffindex", int adjustdelay = -1, bool utf8 = false, + string varprefix = "") +</pre> +<p> +Opens audio. Invokes indexing of all tracks if no valid index file is found, or if the requested track isn't present in the index. +</p> +<h4>Arguments</h4> +<p>Are exactly the same as to <tt>FFVideoSource</tt>, with one exception:</p> +<dl> +<dt>int adjustdelay = -1</dt> +<dd>Controls how audio delay is handled, i.e. what happens if the first audio sample in the file doesn't have a timestamp of zero. The following arguments are valid: +<ul> +<li><b>-3:</b> No adjustment is made; the first decodable audio sample becomes the first sample in the output.</li> +<li><b>-2:</b> Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at time zero.</li> +<li><b>-1:</b> Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at the same time as frame 0 of the first video track. This is the default, and probably what most people want.</li> +<li><b>Any integer >= 0:</b> Same as -1, but adjust relative to the video track with the given track number instead. If the provided track number isn't a video track, an error is raised.</li> +</ul> +-2 obviously does the same thing as -1 if the first video frame of the first video track starts at time zero. In some containers this will always be the case, in others (most notably 188-byte MPEG TS) it will almost never happen. +</dd> +</dl> + + +<h3>FFmpegSource2</h3> +<pre> +FFmpegSource2(string source, int vtrack = -1, int atrack = -2, bool cache = true, + string cachefile = source + ".ffindex", int fpsnum = -1, int fpsden = 1, + int threads = -1, string timecodes = "", int seekmode = 1, + bool overwrite = false, int width = -1, int height = -1, + string resizer = "BICUBIC", string colorspace = "", int rffmode = 0, + int adjustdelay = -1, bool utf8 = false, string varprefix = "") +</pre> +<p>A convenience function that combines the functionality of <tt>FFVideoSource</tt> and <tt>FFAudioSource</tt>. The arguments do the same thing as in <tt>FFVideoSource</tt> and <tt>FFAudioSource</tt>; see those functions for details. <tt>vtrack</tt> and <tt>atrack</tt> are the video and audio track to open, respectively; setting <tt>atrack</tt> <= -2 means audio is disabled.</p> +<p><strong>Note:</strong> this function is provided by <tt>FFMS2.avsi</tt> and is not available unless that script has been imported or autoloaded.</p> + + +<h3>FFImageSource</h3> +<pre> +FFImageSource(string source, int width = -1, int height = -1, + string resizer = "BICUBIC", string colorspace = "", bool utf8 = false) +</pre> +<p>A convenience alias for <tt>FFVideoSource</tt>, with the options set optimally for using it as an image reader. Disables caching and seeking for maximum compatiblity.</p> +<p><strong>Note:</strong> this function is provided by <tt>FFMS2.avsi</tt> and is not available unless that script has been imported or autoloaded.</p> + + +<h3>SWScale</h3> +<pre>SWScale(clip, int width = -1, int height = -1, string resizer = "BICUBIC", string colorspace = "")</pre> +<p>An image resizing and colorspace conversion filter. Does nothing special; it's almost always a better idea to just use Avisynth's builtins instead. Might potentially be useful for testing or odd experiments just because it does things in a different way from Avisynth. See the relevant arguments to <tt>FFVideoSource</tt> for details.</p> + + +<h3>FFFormatTime</h3> +<pre>FFFormatTime(int ms)</pre> +<p> +A helper function used to format a time given in milliseconds into a h:mm:ss.ttt string. Used internally by <tt>FFInfo</tt>. +</p> +<p><strong>Note:</strong> this function is provided by <tt>FFMS2.avsi</tt> and is not available unless that script has been imported or autoloaded.</p> + + +<h3>FFInfo</h3> +<pre>FFInfo(clip c, bool framenum = true, bool frametype = true, bool cfrtime = true, + bool vfrtime = true, string varprefix = "")</pre> +<p> +A helper function similar to Avisynth's internal <tt>Info()</tt> function; shows general information about the current frame. Note that not all values are exported in all source modes, so some information may not always be shown. The arguments can be used to disable the drawing of certain information if so desired. Use the varprefix argument to determine which clip you want information about. +</p> +<p><strong>Note:</strong> this function is provided by <tt>FFMS2.avsi</tt> and is not available unless that script has been imported or autoloaded.</p> + + +<h3>FFSetLogLevel</h3> +<pre>FFSetLogLevel(int Level = -8)</pre> +<p>Sets the FFmpeg logging level, i.e. how much diagnostic spam it prints to STDERR. Since most applications that open Avisynth scripts do not provide a way to display things printed to STDERR, and since it's rather hard to make any sense of the printed messages unless you're quite familiar with FFmpeg internals, the usefulness of this function is rather limited for end users. It's mostly intended for debugging. Defaults to quiet (no messages printed); a list of meaningful values can be found in <tt>libavutil/log.h</tt>.</p> + + +<h3>FFGetLogLevel</h3> +<pre>FFGetLogLevel()</pre> +<p>Returns the current log level, as an integer.</p> + +<h3>FFGetVersion</h3> +<pre>FFGetVersion()</pre> +<p>Returns the FFMS2 version, as a string.</p> + + +<h2>Exported Avisynth variables</h2> +<p>All variable names are prefixed by the <tt>varprefix</tt> argument to the respective <tt>FFVideoSource</tt> or <tt>FFAudioSource</tt> call that generated them.</p> + +<dl> +<dt>FFSAR_NUM, FFSAR_DEN, FFSAR</dt> +<dd> +The playback aspect ratio specified by the container. <tt>FFSAR_NUM</tt> and <tt>FFSAR_DEN</tt> make up the rational number of the ratio; <tt>FFSAR</tt> is only provided for convenience and may not be set in case it cannot be calculated (i.e. if <tt>FFSAR_DEN</tt> is zero). +</dd> + +<dt>FFCROP_LEFT, FFCROP_RIGHT, FFCROP_TOP, FFCROP_BOTTOM</dt> +<dd>The on-playback cropping specified by the container.</dd> + +<dt>FFCOLOR_SPACE</dt> +<dd>The colorimetry the input claims to be using. Only meaningful for YUV inputs. The source for this variable is a metadata flag that can arbitrarily be set or manipulated at will by incompetent users or buggy programs without changing the actual video content, so blindly trusting its correctness is not recommended.<br /> +The value is exported as a cryptic numerical constant that matches the values in the MPEG-2 specification. You can find the gory details in the FFMS2 API documentation, but the important ones are: +<ul> +<li><b>0:</b> RGB (usually indicates the stream isn't actually YUV, but RGB flagged as YUV)</li> +<li><b>1:</b> ITU-R Rec.709</li> +<li><b>2:</b> Unknown or unspecified</li> +<li><b>5 and 6:</b> ITU-R Rec.601</li> +</ul> +</dd> + +<dt>FFCOLOR_RANGE</dt> +<dd> +The color range the input video claims to be using. Much like FFCOLOR_SPACE, the source for this variable is a metadata flag that can freely be set to arbitrary values, so trusting it blindly might not be a good idea.<br /> +Note that using SWScale() or the width/height/colorspace parameters to FFVideoSource may under some circumstances change the output color range. +<ul> +<li><b>0:</b> Unknown/unspecified</li> +<li><b>1:</b> Limited range (usually 16-235)</li> +<li><b>2:</b> Full range (0-255)</li> +</ul> +</dd> + +<dt>FFPICT_TYPE</dt> +<dd> +The picture type of the most recently requested frame as the ASCII number of the character listed below. Use <tt>Chr()</tt> to convert it to an actual letter in avisynth. Use after_frame=true in Avisynth's conditional scripting for proper results. Only set when rffmode=0. The FFmpeg source definition of the characters: +<pre> +I: Intra +P: Predicted +B: Bi-dir predicted +S: S(GMC)-VOP MPEG4 +i: Switching Intra +p: Switching Predicted +b: FF_BI_TYPE (no good explanation available) +?: Unknown +</pre> +</dd> + +<dt>FFVFR_TIME</dt> +<dd>The actual time of the source frame in milliseconds. Only set when no type of CFR conversion is being done (<tt>rffmode</tt> and <tt>fpsnum</tt> left at their defaults).</dd> + + +<dt>FFCHANNEL_LAYOUT</dt> +<dd>The audio channel layout of the audio stream. This is exported as a very cryptic integer that is constructed in the same way as the <tt>dwChannelMask</tt> property of the Windows <tt>WAVEFORMATEXTENSIBLE</tt> struct. If you don't know what a <tt>WAVEFORMATEXTENSIBLE</tt> is or what the <tt>dwChannelMask</tt> does, don't worry about it.</dd> + +<dt>FFVAR_PREFIX</dt> +<dd>The variable prefix of the last called FFMS source function. Note that this is a global variable</dd> + +</dl> +</div> + +</div> + +</body> +</html> diff --git a/ffms2/doc/ffms2-changelog.html b/ffms2/doc/ffms2-changelog.html new file mode 100644 index 0000000..b060b86 --- /dev/null +++ b/ffms2/doc/ffms2-changelog.html @@ -0,0 +1,288 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="content-type" content="text/html; charset=utf-8" /> +<title> +FFmpegSource2 Changelog +</title> +<link href="style.css" media="screen" rel="Stylesheet" type="text/css" /> +</head> +<body> +<div class="maincontent"> +<h1>FFmpegSource2 Changelog</h1> +<ul> +<li>2.18<ul> +<li>Fix regression (r483) with rffmode that caused it to error out even if using the default output colorspace. (TheRyuu)</li> +<li>High(er) quality YUV->RGB conversion. (TheRyuu)</li> +<li>Fix indexing on files with cover art. (TheRyuu)</li> +<li>Add support for libav/ffmpeg built with msvc, this is the default on windows when building with msvc. (TheRyuu)</li> +<li>Remove postproc support. (TheRyuu)</li> +<li>Deprecate the CPUFeatures argument to FFMS_Init since postproc was the only thing still using it. (Plorkyeran)</li> +<li>Added VapourSynth support. (Myrsloik)</li> +<li>ffmsindex can now output keyframe numbers to a file while indexing. (Plorkyeran)</li> +<li>configure now defaults to building a shared library, except when building MinGW/Cygwin, since you usually want static for those. (Plorkyeran)</li> +<li>The source color space and color range used when converting with swscale can now be overridden. (Plorkyeran)</li> +<li>Fix issues with unicode filenames when building with mingw. (Plorkyeran)</li> +<li>Fix progress reporting when indexing files with non-zero initial timestamp with haali's splitter. (Plorkyeran)</li> +<li>Add support for formats with packet durations but no packet timestamps. (Plorkyeran)</li> +<li>Fix corruption when seeking in VC-1 in MKV. (Plorkyeran)</li> +<li>Fix bug that resulted in files opened with Haali's splitter sometimes always decoding from the beginning on every seek. (Plorkyeran)</li> +<li>Add support for VP8. (Plorkyeran)</li> +<li>Fix crash when indexing video formats with no parser. (Plorkyeran)</li> +<li>Fix compilation errors with recent versions of libav/ffmpeg. (Plorkyeran)</li> +<li>Fix NVOP handling with frame-based threading (aka zero-size frames with mp4 bug). (Plorkyeran)</li> +<li>Add support for vc1image. (Plorkyeran)</li> +<li>Use the container SAR when the codec SAR is unset when opening via lavf. (Plorkyeran)</li> +<li>Actually set the ColorRange and ColorSpace of frames when nothing has been overridden. (Plorkyeran)</li> +<li>Add support for files without timestamps to lavf audio. (Plorkyeran)</li> +<li>Fix handling of audio delay with invalid inital timestamps. (Plorkyeran)</li> +<li>Sort of partially fix interlaced H.264. (Plorkyeran)</li> +<li>Fix errors when the client asks for audio past the end of the file. (Plorkyeran)</li> +<li>Fix rounding error with MKV timestamps that resulted in things getting a FPS like 60001/1001. (TheRyuu)</li> +<li>Bump required version to libav 0.8/FFmpeg 0.9. (Plorkyeran)</li> +<li>Switch to avcodec_decode_audio4. (Plorkyeran)</li> +<li>Add support for planar audio from lavc. (Plorkyeran)</li> +<li>Add SetOutputFormatA for audio resampling/mixing using libavresample. (Plorkyeran)</li> +<li>Zero-length index files are now rejected rather than bad things happening.</li> +</ul> +</li> + +<li>2.17<ul> +<li>Reworked color matrix and color range handling a bit, which fixed a bug that could cause FFMS2 to always output TV range even if the input was full range. (TheFluff)</li> +<li>The autotools build system can now create debug builds properly. (Daemon404)</li> +<li>Deprecated parts of the API will now cause compiler warnings when you use them. (TheFluff)</li> +<li>Added a <tt>FFMS_GetVersion</tt> function to the API (lets library users get the version number at runtime) and exposed it in Avisynth as <tt>FFGetVersion</tt>. (TheRyuu, TheFluff)</li> +<li>Added a variable prefix option to the Avisynth functions. Its primary purpose is to get subsequent calls to source functions from overwriting variables from earlier calls. (TheFluff)</li> +<li>Make it possible to open single-frame videos without explicitly setting seekmode to -1 for you weird people who want to open images with ffms (Plorkyeran)</li> +<li>Fixed bug where indices would sometimes be incorrectly considered valid (TheRyuu)</li> +<li>Add support for recent versions of Libav/FFmpeg built as shared libraries (Plorkyeran, TheRyuu, Kovensky)</li> +<li>When possible, non-API symbols are no longer exported (Daemon404, TheFluff)</li> +<li>Deprecate postprocessing support. Libav and FFmpeg are planning on removing it at some point in the near future and it's really not very useful.</li> +<li>Fix the pkg-config version on OS X (Plorkyeran).</li> +<li>Fixed a bug that could cause the <tt>FFmpegSource2()</tt> Avisynth function to not use UTF8 filenames even when told to do so. (pandv2)</li> +<li>Fixed a few minor memory leaks. (Plorkyeran)</li> +<li>Adjusting audio delay relative to the first video track should now work properly again (was broken in 2.16). (Plorkyeran)</li> +<li>General bitrot fixes to deal with changes in Libav/FFmpeg (everyone)</li> +<li>Corrected handling of codec private data when using a non-libavformat parser. Fixes decoding of FFV1 and UTVideo in MKV, among other things. (TheFluff)</li> +<li>Bump minimum required version of FFmpeg to 0.6.</li> +</ul> +</li> + +<li>2.16<ul> +<li>Reimplemented output colorspace selection, this should fix all issues with the Avisynth plugin when opening yuv420p10 or yuv444 material plus several other less common cases. (Myrsloik)</li> +<li>Added <tt>FFMS_SetOutputFormatV2</tt> to the API. This function allows you to specify PixelFormats >= 64 for use as output. (Myrsloik)</li> +<li>Fixed a serious bug that could cause crashes and completely useless index files with h264 in Matroska. (Myrsloik)</li> +<li>Automatically detect number of decoding threads. The Avisynth video source funtion already did this, now moved so the API can use it as well. (TheRyuu)</li> +<li>Re-add the ability to target x64 with MSVC, since it's a bit more sane now. (TheRyuu)</li> +<li>Fixed a bug that could cause crashes when reading audio if FFMS2 was compiled with GCC. (Myrsloik)</li> +<li>ffmsindex will no longer crash if it cannot open the file given to it for indexing. (TheFluff)</li> +<li>FFMS2 will no longer crash if the video decoder feeds it an empty frame (can sometimes happen when using lots of decoder threads); you'll get a nice error message instead. (TheFluff)</li> +<li>The C-plugin can now act as both an Avisynth 2.6 plugin (including support for new colorspaces) as well as an Avisynth 2.5 one, in the same binary. (kemuri_-9)</li> +<li>Fixed an issue that could cause opening Vorbis audio to fail because FFMS2 couldn't find an initial valid PTS. (TheFluff)</li> +<li>FFMS2 will no longer crash if forced or tricked into using an index file generated by a FFMS2 version compiled for a different architecture. (TheRyuu)</li> +<li>Fixed a crash when the last frame was requested using the Avisynth plugin's forced CFR mode. (Plorkyeran)</li> +<li>Fixed various issues with decoding audio from the Ogg container without Haali's splitter. (Myrsloik, TheFluff)</li> +<li>Fixed the "invalid postprocessing settings", it is caused by a parsing bug in libpostproc and a workaround has been added (Myrsloik)</li> +<li>Tinkered a bit with the non-MSVS build system. (Daemon404, Kovensky)</li> +</ul></li> + +<li>2.15<ul> +<li>FFVideoSource and FFAudioSource will now automatically reindex and overwrite the index file if it doesn't match the file being opened and the <tt>cachefile</tt> argument is left as the default. (Plorkyeran)</li> +<li>FFMS2 can now be used to decode Lagarith, but note that libavcodec's decoder is very experimental at the moment. (Plorkyeran)</li> +<li>SWScale can now use SSE2 optimizations for certain operations if your CPU supports it. (kemuri_-9)</li> +<li>Fixed a bug that could cause SWScale initialization to fail. (kemuri_-9)</li> +<li>Fixed a bug that could cause index files to never be considered valid, forcing a reindexing every time a script was loaded. (TheRyuu)</li> +<li>Trying to use postprocessing on a fullrange YUV clip will no longer cause errors. (TheFluff)</li> +<li>Fixed a few random decoding bugs related to unaligned memory or buffers that were not initialized properly. (TheFluff)</li> +<li>It is now possible to force FFMS2 to use a specific demuxer instead of letting it pick one automatically. (TheFluff)</li> +<li>When converting YUV to RGB, FFMS2 will now try to actually use the correct color coefficients rather than assuming everything is bt470bg. (Plorkyeran)</li> +<li>Moved support for container-level audio delay from the Avisynth plugin to the core and exposed it in the API (Plorkyeran)</li> +<li>Audio decoding has been substantially reworked. Linearly decoding audio now almost always works correctly and seeking is now actually sample-accurate for many formats. (Plorkyeran)</li> +<li>It is now possible to build 64bit versions of the plugin for use with Avisynth (and whatever else) from MSVC by means of black magic (this probably only works when the planets are aligned, also 64bit builds might require msvcr90.dll). (TheRyuu)</li> +<li>The Avisynth plugin now supports UTF8 filenames; ffmsindex.exe also supports Unicode filenames. FFMS_USE_UTF8_PATHS is now a runtime option instead of a compile-time one. (TheFluff)</li> +<li>The FFInfo() function (supplied by ffms2.avsi) will now round timestamps to nearest millisecond instead of truncating them. It's also been cleaned up in general and no longer relies on global variables. (Gavino)</li> +<li>Containers opened with libavformat will now report a framerate based on the average frame duration instead of the duration of the first frame, just like Matroska files and files opened with Haali's splitter does. Should fix CFR framerates being reported incorrectly in dumb containers like FLV. (TheFluff)</li> +<li>PC/TV luma range (16-235 versus 0-255) detection should now be a bit more reliable. (TheFluff)</li> +<li>Fixed a crash when opening files with Unicode filename support enabled. (Plorkyeran)</li> +</ul></li> + +<li>2.14<ul> +<li>Reworked filename handling a bit. Index files should no longer get a garbled name when using the Avisynth plugin and an input filename in the local codepage (issue 9), and FFMS_USE_UTF8_PATHS does no longer require patching ffmpeg. (TheFluff, nielsm)</li> +<li>Fixed a bunch of compiler warnings and added versioning for the shared library when building under Unix. (Kovensky)</li> +<li>Fixed an invalid memory access bug that could cause random crashes or other errors when opening files. (TheFluff)</li> +<li>The timebase for video tracks is now corrected if it's invalid. (kemuri_-9)</li> +<li>Fixed a number of multithreaded decoding issues. (kemuri_-9)</li> +<li>Use aligned memory for audio decoding buffers; fixes some crashes during audio decoding. (greg)</li> +<li>Fixed a bug that caused ffmsindex -c to fail. (chdheu)</li> +<li>Added support for MKV files using header stripping compression. (TheFluff)</li> +<li>It is now possible to compile FFMS2 using a ffmpeg without libpostproc compiled in (this will obviously cause postprocessing-related functions to fail). Hence it is now possible to build a GPL-free FFMS2, since the rest of ffmpeg can be compiled as LGPL. (TheFluff)</li> +<li>Audio streams that change channel layout, sample rate or bitdepth mid-stream will no longer cause crashes; an error will be raised during indexing instead. (TheFluff)</li> +<li>Fix a potential crash when ffmpeg thought it couldn't decode a certain format, but was wrong. Fixes issues with some FLV's. (Plorkyeran)</li> +<li>Fix heap corruption that could cause crashes and odd issues when opening H.264 in MPEG-TS with Haali's splitter. (Plorkyeran)</li> +<li>Fix a memleak when decoding H.264 in MPEG-TS using Haali's splitter. (kemuri-_9)</li> +<li>Updated FFmpeg to rev 25329.</li> +</ul></li> + +<li>2.13<ul> +<li>Fixed a bug where the Avisynth plugin would drop the last frame when converting to CFR (lanwcp)</li> +<li>The Avisynth plugin will now attempt to detect and use NTSC fractional framerates for CFR files if applicable, instead of reporting something based on the average framerate (astrange, TheFluff)</li> +<li>The errorhandling parameter to FFIndex() will now actually do what the documentation claims it does (TheFluff)</li> +<li>Fixed a progress reporting crash when opening images (TheFluff)</li> +<li>Replaced the CMake build system with an autotools one that hopefully works better (Kovensky)</li> +<li>Fixed various compilation issues with MinGW (TheFluff)</li> +<li>Fixed h264 in mkv which was remuxed from bd sources, there are no longer decoding artifacts after seeking</li> +<li>Use pts instead of dts for seeking with lavf, fixes various timecode problems on mp4 files with certain obscure delay headers</li> +<li>Now compresses the index files with zlib to save space</li> +<li>Removed the boost dependency</li> +<li>Fixed the framerate calculation for AVC video in the RFF modes</li> +<li>Improved/fixed the NVOP detection in MPEG4 and how timestamps are calculated (lanwcp, Myrsloik)</li> +<li>Fixed an issue where the first 15 audio frames would never be redecoded if needed again</li> +<li>Fixed/added support for uncompressed video and audio formats in matroska, fixes Blank.Clip.720p.x264-darkhold.mkv (Emess)</li> +<li>The indexer and test is now statically linked so no extra runtimes are needed</li> +<li>FFmpeg is now compiled with runtime cpu detection, allows opterons and old cpus to work properly</li> +<li>Updated FFmpeg to rev 21782</li> +</ul></li> + +<li>2.12<ul> +<li>Added support for (L)PCM in TS/PS</li> +<li>Fixed some possible memory corruption on initialization in the indexers</li> +<li>Improved the API slightly by making resolution and colorspace frame properties only like they actually are</li> +<li>Fixed adjustdelay=-1 when no video track is present, previously it would crash</li> +<li>Updated FFmpeg to rev 19824, FFmpeg-mt unchanged at 24/08/2009 - with faad2, opencore-amr nb/wb, and pthreads</li> +</ul></li> + +<li>2.11<ul> +<li>Now 100% less beta</li> +<li>FFMSIndex can now write timecode files</li> +<li>Optimized index reading and writing, file opening should be faster especially for big files</li> +<li>Fixed a crash bug on zlib compressed streams in matroska</li> +<li>Added an argument to FFAudioSource that makes it automatically adjust the delay relative to the first video track (default), the specified track (any track type possible) or relative to the zero timestamp, no adjustment is done for files with no video track in the default mode</li> +<li>Now exports the colorimetry info in a format easily usable with ColorMatrix, see FFCOLOR_SPACE and FFCOLOR_RANGE in the manual, the reported information may be unreliable</li> +<li>Added an FFImageSource() function to ffms2.avsi which invokes FFVideoSource with the optimal settings for use on images</li> +<li>Now exports the actual frame presentation time in FFVFR_TIME, added the general information function FFInfo() and FFFormatTime() functions to ffms2.avsi in addition to fixing the missing backslash</li> +<li>The seek/read method has been changed in the matroska video source to only need the information in the index and nothing more, this matches the audio source and should make seeking faster in some cases</li> +<li>No longer drops the last audio frame</li> +<li>It is now possible to force indexing of broken tracks when using FFIndex and from the API, this can in many cases help when the last frame of an avi file is corrupted which would otherwise prevent indexing of all working data</li> +<li>Fixed a bug that would prevent the SWScale and FFPP filters from working because of randomly added flags</li> +<li>Added support for RFF flags, the three possible modes should be equivalent to the ones found in DGDecode</li> +<li>Added a workaround for mpeg4 files with NVOPs</li> +<li>Fixed a bug where the first frame would be corrupted if the colorspace/dimensions were set for the output</li> +<li>Now VC1 in TS decoding works in many cases</li> +<li>Added the missing install target to CMake and changed the default output library name (Kovensky)</li> +<li>Now reverts to using LAVF if Haali's splitter isn't installed (note that LAVF is VERY bad at seeking in these formats)</li> +<li>Now requires the boost headers (but not libraries) to compile because boost::format is so convenient</li> +<li>More API changes to return proper error codes and more source cleanups</li> +<li>Updated FFmpeg to rev 19776, FFmpeg-mt to 24/08/2009 - with faad2, opencore-amr nb/wb, and w32threads (pthreads for FFmpeg-mt)</li> +</ul></li> + +<li>2.00 beta 10<ul> +<li>Possibly fixed h264 in transport stream decoding, now a suitable bitstream filter is added (could theoretically break other h264 in ts files so make sure to report if any such files stop working)</li> +<li>Now returns the frame type as a character to make presentation easier and to remove the random numbers from the API</li> +<li>Fixed the identification of certain codecs (like VC1) in some transport streams</li> +<li>Fixed a bug introduced in SeekMode=1 by the changes in beta 6, prevents an access violation from happening in very rare conditions</li> +<li>Some (but not all) stream properties are now retrieved from the container and passed to libavcodec, this makes a few more formats work like vc1 in mkv/ts</li> +<li>It is now possible to specify the desired output colorspace and resolution in FFVideoSource, this is mostly useful for file where the resolution changes to avoid excessive up/downscaling</li> +<li>Added support for files where the video frames have changing size and colorspace</li> +<li>The library part can now be compiled to accept UTF8 encoded strings, this allows full unicode support on windows when FFmpeg is compiled with a small patch applied (TheFluff)</li> +<li>Added proper detection of when the opened file and index is mismatched and throws an error when it happens instead of undefined behavior, should not add a noticable delay to file opening</li> +<li>Added a proper cmake based build system and vs2008 project files to make developement and use easier (TheFluff, JEEB, Kovensky)</li> +<li>Added API documentation by TheFluff and revised many argument descriptions to reflect how they currently work</li> +<li>The output audio filename can now be specified in avisynth (was ignored previously) with variables such as track number and delay possible to use</li> +<li>Indexing with Haali's splitters should now show progress in most cases</li> +<li>Fixed a few more memory leaks in indexing</li> +<li>Now checks for failed seeking when LAVF is used and retries with more aggressive seeking options before failing</li> +<li>Updated FFmpeg to rev 19479 (now compiled with the opencore amr decoder)</li> +</ul></li> + +<li>2.00 beta 9<ul> +<li>Dumping audio now actually implies indexing too in FFIndex, previously nothing would be done if the index mask wasn't set as well</li> +<li>FFAudioSource will now first load the index and returns the first indexed audio track with track=-1, if no audio tracks are indexed or the chosen track isn't indexed the equivalent of FFIndex(indexmask = -1, overwrite = cache) is executed first</li> +<li>Codec lookup for non-lavf opened files now to a large part use the same lookup tables as lavf, this should improve the number of properly recognized codecs</li> +<li>Now uses the average framerate for files opened with Haali's splitters, before it was always reported as 30 fps</li> +<li>Implemented audio decoding using Haali's splitters, FFAudioSource now works on ts, ps and ogm</li> +<li>Can now be compiled with ICL 10.1 (probably other versions too)</li> +<li>How indexing works has been split internally so the track numbers and types are reported, this makes it possible to create an interactive GUI or ask which audio tracks are to be indexed</li> +<li>Now has stricter index checking to detect when different FFmpeg versions were used to create an index of the same version</li> +<li>Fixed memory leaks when audio sources were destroyed and when errors happened during indexing</li> +<li>Fixed access violations occurring when a track of the wrong type was specified or didn't exist in FFVideoSource and FFAudioSource</li> +<li>Fixed access violations occurring when unindexed or empty audio tracks in matroska/lavf read files were opened</li> +<li>Less type conversion/signedness warnings</li> +<li>When audio track dumping is performed a custom callback can now be supplied to name the tracks</li> +<li>The audio track delay is now exposed in the API in the same way as video tracks</li> +<li>A big type and argument name cleanup in the API, many things have been renamed to be clearer and ffms.h should be completely C friendly now</li> +<li>Removed FFNoLog and replaced it with FFSetLogLevel and FFGetLogLevel, the default logging is now also set to quiet, the magical numbers to supply it can be found in avutil/log.h</li> +<li>Updated FFmpeg to rev 18972 (now with faad2 again by popular demand, updated to GCC 4.4.0 for compiling all libraries)</li> +</ul></li> + +<li>2.00 beta 8<ul> +<li>Improved the audio decoding quality a lot by adding a simple cache, no more seeking is done when playing a file linearly and pops and other artifacts should be much more uncommon</li> +<li>Fixed a bug that would most of the time drop frame 0 and sometimes frame 1</li> +<li>Updated Haali's matroska parser code to the latest version</li> +<li>Updated FFmpeg to rev 18774</li> +</ul></li> + + +<li>2.00 beta 7<ul> +<li>Using ffms2 as a library no longer requires an installed pixfmt.h from libavutil, it is however still required to compile ffms2 and the avisynth plugin part</li> +<li>Fix a crash bug at the end of files with b-frames in beta 6 caused by uninitialized null packets</li> +<li>Includes TheFluff's wrapper function for 1.21 style syntax</li> +<li>Added a simple regression test application to the source</li> +<li>Removed a few pointless functions from the API</li> +<li>Fixed the accessing of codecprivate data with Haali's splitters</li> +<li>Timecode output should be fixed to include decimals AND not be in scientific format</li> +<li>Fixed a memory leak when using Haali's splitters</li> +<li>Updated FFmpeg to rev 18717</li> +</ul></li> + +<li>2.00 beta 6<ul> +<li>Haali's splitters have been improved for video and now have audio dumping during indexing implemented</li> +<li>SeekMode=1 has improved logic which will make it go back and decode more frames if necessary to figure out where it is, in theory SeekMode=0 should now be mostly obsolete</li> +<li>Haali's splitters are now used to open mpeg ps and ogm in addition to mpeg ts, only ogm is frame accurate at this time</li> +<li>Negative timecodes and other bugs caused by an integer overflow fixed</li> +<li>Updated FFmpeg to rev 18442 (once again compilation fixes for the changes)</li> +</ul></li> + +<li>2.00 beta 5<ul> +<li>FFMSIndex should now print the progress properly when another application reads its output</li> +<li>Added missing variables and explanations to the manual</li> +<li>Can now directly be compiled as a library for use in *nix</li> +<li>Fixed the missing decimals in saved timecode files</li> +</ul></li> + +<li>2.00 beta 4<ul> +<li>Added the function FFNoLog which suppresses all messages from ffmpeg</li> +<li>Experimental new TS parsing using Haali's splitter (with bugs)</li> +<li>Everything is now compiled with VS2008 and GCC 4.3.2</li> +<li>Updated FFmpeg to rev 16383 (no libfaad2 this time)</li> +</ul></li> + +<li>2.00 beta 3<ul> +<li>Compiled with libfaad2 again (has anyone seen a single aac file lavc can open right now?)</li> +<li>More API changes (and even more are likely to come)</li> +<li>Several access violations and memory leaks on opening and indexing files fixed</li> +<li>Added a VFR to CFR mode</li> +<li>Readded FFAudioSource support for other containers (glitches still present now and then but no separate raw cache is required and possibly less buggy)</li> +<li>Renamed the dll to FFMS2.dll, FFMS2 is now the official short name of the project</li> +<li>Updated FFmpeg to rev 15522</li> +</ul></li> + +<li>2.00 beta 2<ul> +<li>More API changes (and more are likely to come)</li> +<li>Includes a simple CLI indexing application</li> +<li>FFIndex now takes a few more arguments</li> +<li>Readded FFAudioSource (only matroska supported for now)</li> +<li>Updated FFmpeg to rev 15396</li> +</ul></li> + +<li>2.00 beta 1<ul> +<li>Can now be used as a stand alone library for making indices and retrieving frames</li> +<li>Rewrote most things</li> +<li>Updated FFmpeg to rev 15301</li> +</ul></li> + +</ul> + +</div> + +</body> +</html> diff --git a/ffms2/doc/style.css b/ffms2/doc/style.css new file mode 100644 index 0000000..7b925d6 --- /dev/null +++ b/ffms2/doc/style.css @@ -0,0 +1,60 @@ +body { + background-color: #fffffb; + font-family: sans-serif; + font-size: 9pt; + text-align: center; +} +table { + border-collapse: collapse; + margin: 3pt; + font-family: sans-serif; + font-size: 9pt; +} +td { + padding: 1pt; + padding-left: 3pt; + padding-right: 3pt; +} +td.minpadding { + padding: 1pt; +} +th { + padding: 1pt; + padding-left: 3pt; + padding-right: 3pt; +} +a:link { + color: #40b070; +} +a:visited { + color: #103020; +} +h1, h2, h3 { + margin: 1.2em 0em -0.2em; +} +h4 { + margin: 0em 0em -0.5em; + text-decoration: underline; +} +.deprecated { + color: red; +} +img { + border-width: 0px; +} +img.w3cicon { + width: 88px; + height: 31px; +} +body div.maincontent { + margin-left: auto; + margin-right: auto; + text-align: left; + width: 90%; +} + +.avisynth-functionref dt { + font-family: monospace; + padding: 5px 3px 3px 3px; +} + |
