// AForge Video for Windows Library // AForge.NET framework // http://www.aforgenet.com/framework/ // // Copyright © Andrew Kirillov, 2007-2009 // andrew.kirillov@aforgenet.com // // using System; using System.Runtime.InteropServices; using GreenshotPlugin.UnmanagedHelpers; using System.Collections.Generic; using System.IO; namespace Greenshot.Helpers { /// /// AVI files writing using Video for Windows interface. /// /// /// The class allows to write AVI files using Video for Windows API. /// /// Sample usage: /// /// // instantiate AVI writer, use WMV3 codec /// AVIWriter writer = new AVIWriter( "wmv3" ); /// // create new AVI file and open it /// writer.Open( "test.avi", 320, 240 ); /// // create frame image /// Bitmap image = new Bitmap( 320, 240 ); /// /// for ( int i = 0; i < 240; i++ ) /// { /// // update image /// image.SetPixel( i, i, Color.Red ); /// // add the image as a new frame of video file /// writer.AddFrame( image ); /// } /// writer.Close( ); /// /// /// public class AVIWriter : IDisposable { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(AVIWriter)); // AVI file private IntPtr file; // video stream private IntPtr stream; // compressed stream private IntPtr streamCompressed; // width of video frames private int width; // height of vide frames private int height; // length of one line private int stride; // quality private int quality = -1; // frame rate private int rate = 25; // current position private int position; // codec used for video compression private string codec = null; //"DIB "; /// /// Width of video frames. /// /// /// The property specifies the width of video frames, which are acceptable /// by method for saving, which is set in /// method. /// public int Width { get { return width; } } /// /// Height of video frames. /// /// /// The property specifies the height of video frames, which are acceptable /// by method for saving, which is set in /// method. /// public int Height { get { return height; } } /// /// Current position in video stream. /// /// /// The property tell current position in video stream, which actually equals /// to the amount of frames added using method. /// public int Position { get { return position; } } /// /// Desired playing frame rate. /// /// /// The property sets the video frame rate, which should be use during playing /// of the video to be saved. /// /// The property should be set befor opening new file to take effect. /// /// Default frame rate is set to 25. /// public int FrameRate { get { return rate; } set { rate = value; } } /// /// Codec used for video compression. /// /// /// The property sets the FOURCC code of video compression codec, which needs to /// be used for video encoding. /// /// The property should be set befor opening new file to take effect. /// /// Default video codec is set "DIB ", which means no compression. /// public string Codec { get { return codec; } set { codec = value; } } /// /// Compression video quality. /// /// /// The property sets video quality used by codec in order to balance compression rate /// and image quality. The quality is measured usually in the [0, 100] range. /// /// The property should be set befor opening new file to take effect. /// /// Default value is set to -1 - default compression quality of the codec. /// public int Quality { get { return quality; } set { quality = value; } } /// /// Initializes a new instance of the class. /// /// /// Initializes Video for Windows library. /// public AVIWriter() { Avi32.AVIFileInit(); } /// /// Initializes a new instance of the class. /// /// /// Codec to use for compression. eg [CVID],[IV50] /// /// Initializes Video for Windows library. /// public AVIWriter(string codec) : this() { this.codec = codec; } /// /// Destroys the instance of the class. /// /// ~AVIWriter() { Dispose(false); } /// /// Dispose the object. /// /// /// Frees unmanaged resources used by the object. The object becomes unusable /// after that. /// public void Dispose() { Dispose(true); // remove me from the Finalization queue GC.SuppressFinalize(this); } /// /// Dispose the object. /// /// /// Indicates if disposing was initiated manually. /// protected virtual void Dispose(bool disposing) { if (disposing) { // dispose managed resources } // close current AVI file if any opened and uninitialize AVI library Close(); Avi32.AVIFileExit(); } /// /// Create new AVI file and open it for writing. /// /// /// AVI file name to create. /// Video width. /// Video height. /// /// The method opens (creates) a video files, configure video codec and prepares /// the stream for saving video frames with a help of method. /// /// Failure of opening video files (the exception message /// specifies the issues). /// public bool Open(string fileName, int width, int height) { lock (this) { // calculate stride stride = width * 4; if ((stride % 4) != 0) { stride += (4 - stride % 4); } this.width = width; this.height = height; // describe new stream Avi32.AVISTREAMINFO info = new Avi32.AVISTREAMINFO(); LOG.InfoFormat("Available codecs: {0}", String.Join(", ", Avi32.AvailableCodecs.ToArray())); info.type = Avi32.mmioFOURCC("vids"); if (codec != null) { info.handler = Avi32.mmioFOURCC(codec); } else { info.handler = Avi32.mmioFOURCC("DIB "); } info.scale = 1; info.rate = rate; info.suggestedBufferSize = stride * height; try { // create new file if (Avi32.AVIFileOpen(out file, fileName, Avi32.OpenFileMode.Create | Avi32.OpenFileMode.Write, IntPtr.Zero) != 0) { throw new ApplicationException("Failed opening file"); } // create stream if (Avi32.AVIFileCreateStream(file, out stream, ref info) != 0) { throw new ApplicationException("Failed creating stream"); } // describe compression options Avi32.AVICOMPRESSOPTIONS options = new Avi32.AVICOMPRESSOPTIONS(); // uncomment if video settings dialog is required to show int retCode = 0; if (codec == null) { retCode = Avi32.AVISaveOptions(stream, ref options); if (retCode == 0) { LOG.Debug("Cancel clicked!"); return false; } codec = Avi32.decode_mmioFOURCC(options.handler); quality = options.quality; } else { options.handler = Avi32.mmioFOURCC(codec); options.quality = quality; } LOG.DebugFormat("Codec {0} selected with quality {1}.", codec, quality); AviError retval; // create compressed stream try { retval = Avi32.AVIMakeCompressedStream(out streamCompressed, stream, ref options, IntPtr.Zero); } catch (Exception exCompress) { LOG.Warn("Couldn't use compressed stream.", exCompress); retval = AviError.AVIERR_OK; } if (retval != AviError.AVIERR_OK) { throw new ApplicationException(string.Format("Failed creating compressed stream: {0}", retval)); } // describe frame format BitmapInfoHeader bitmapInfoHeader = new BitmapInfoHeader(width, height, 32); // set frame format if (streamCompressed != IntPtr.Zero) { retval = Avi32.AVIStreamSetFormat(streamCompressed, 0, ref bitmapInfoHeader, Marshal.SizeOf(bitmapInfoHeader.GetType())); } else { retval = Avi32.AVIStreamSetFormat(stream, 0, ref bitmapInfoHeader, Marshal.SizeOf(bitmapInfoHeader.GetType())); } if (retval != 0) { throw new ApplicationException(string.Format("Failed creating stream: {0}", retval)); } position = 0; return true; } catch (Exception ex) { Close(); Avi32.AVIFileExit(); if (File.Exists(fileName)) { File.Delete(fileName); } throw ex; } } } /// /// Close video file. /// /// public void Close() { LOG.Debug("Close called"); lock (this) { // release compressed stream if (streamCompressed != IntPtr.Zero) { LOG.Debug("AVIStreamRelease streamCompressed"); Avi32.AVIStreamRelease(streamCompressed); streamCompressed = IntPtr.Zero; } // release stream if (stream != IntPtr.Zero) { LOG.Debug("AVIStreamRelease stream"); Avi32.AVIStreamRelease(stream); stream = IntPtr.Zero; } // release file if (file != IntPtr.Zero) { LOG.Debug("AVIFileRelease file"); Avi32.AVIFileRelease(file); file = IntPtr.Zero; } } } public void AddEmptyFrames(int frames) { lock (this) { position += frames; } } /// /// Add new frame to the AVI file. /// /// New frame data. public void AddLowLevelFrame(IntPtr frameData) { lock (this) { // write to stream if (Avi32.AVIStreamWrite(streamCompressed, position, 1, frameData, stride * height, 0, IntPtr.Zero, IntPtr.Zero) != 0) { throw new ApplicationException("Failed adding frame"); } position++; } } } /// /// Windows API functions and structures. /// /// /// The class provides Video for Windows and some other Avi32 functions and structurs. /// internal static class Avi32 { private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(Avi32)); [DllImport("MSVFW32", CharSet = CharSet.Ansi)] static extern bool ICInfo(int fccType, int fccHandler, ref ICINFO lpicinfo); [DllImport("MSVFW32"), PreserveSig] static extern IntPtr ICOpen(int fccType, int fccHandler, ICMODE wMode); [DllImport("MSVFW32")] static extern int ICClose(IntPtr hic); [DllImport("MSVFW32", CharSet = CharSet.Ansi)] static extern int ICGetInfo(IntPtr hic, ref ICINFO lpicinfo, int cb); // --- Video for Windows Functions /// /// Initialize the AVIFile library. /// /// [DllImport("avifil32")] public static extern void AVIFileInit(); /// /// Exit the AVIFile library. /// [DllImport("avifil32")] public static extern void AVIFileExit(); /// /// Open an AVI file. /// /// /// Opened AVI file interface. /// AVI file name. /// Opening mode (see ). /// Handler to use (null to use default). /// /// Returns zero on success or error code otherwise. /// [DllImport("avifil32", CharSet = CharSet.Unicode)] public static extern AviError AVIFileOpen(out IntPtr aviHandler, String fileName, OpenFileMode mode, IntPtr handler); /// /// Release an open AVI stream. /// /// /// Open AVI file interface. /// /// Returns the reference count of the file. /// [DllImport("avifil32")] public static extern int AVIFileRelease(IntPtr aviHandler); /// /// Get stream interface that is associated with a specified AVI file /// /// /// Handler to an open AVI file. /// Stream interface. /// Stream type to open. /// Count of the stream type. Identifies which occurrence of the specified stream type to access. /// /// /// [DllImport("avifil32")] public static extern int AVIFileGetStream(IntPtr aviHandler, out IntPtr streamHandler, int streamType, int streamNumner); /// /// Create a new stream in an existing file and creates an interface to the new stream. /// /// /// Handler to an open AVI file. /// Stream interface. /// Pointer to a structure containing information about the new stream. /// /// Returns zero if successful or an error otherwise. /// [DllImport("avifil32")] public static extern int AVIFileCreateStream(IntPtr aviHandler, out IntPtr streamHandler, ref AVISTREAMINFO streamInfo); /// /// Release an open AVI stream. /// /// /// Handle to an open stream. /// /// Returns the current reference count of the stream. /// [DllImport("avifil32")] public static extern int AVIStreamRelease(IntPtr streamHandler); /// /// Set the format of a stream at the specified position. /// /// /// Handle to an open stream. /// Position in the stream to receive the format. /// Pointer to a structure containing the new format. /// Size, in bytes, of the block of memory referenced by format. /// /// Returns zero if successful or an error otherwise. /// [DllImport("avifil32")] public static extern AviError AVIStreamSetFormat(IntPtr streamHandler, int position, ref BitmapInfoHeader format, int formatSize); /// /// Get the starting sample number for the stream. /// /// /// Handle to an open stream. /// /// Returns the number if successful or – 1 otherwise. /// [DllImport("avifil32")] public static extern int AVIStreamStart(IntPtr streamHandler); /// /// Get the length of the stream. /// /// Handle to an open stream. /// Returns the stream's length, in samples, if successful or -1 otherwise. [DllImport("avifil32")] public static extern int AVIStreamLength(IntPtr streamHandler); /// /// Obtain stream header information. /// /// /// Handle to an open stream. /// Pointer to a structure to contain the stream information. /// Size, in bytes, of the structure used for streamInfo. /// /// Returns zero if successful or an error otherwise. /// [DllImport("avifil32", CharSet = CharSet.Unicode)] public static extern int AVIStreamInfo(IntPtr streamHandler, ref AVISTREAMINFO streamInfo, int infoSize); /// /// Prepare to decompress video frames from the specified video stream /// /// Pointer to the video stream used as the video source. /// Pointer to a structure that defines the desired video format. Specify NULL to use a default format. /// Returns an object that can be used with the function. [DllImport("avifil32")] public static extern IntPtr AVIStreamGetFrameOpen(IntPtr streamHandler, ref BitmapInfoHeader wantedFormat); /// /// Prepare to decompress video frames from the specified video stream. /// /// Pointer to the video stream used as the video source. /// Pointer to a structure that defines the desired video format. Specify NULL to use a default format. /// Returns a GetFrame object that can be used with the function. [DllImport("avifil32")] public static extern IntPtr AVIStreamGetFrameOpen(IntPtr streamHandler, int wantedFormat); /// /// Releases resources used to decompress video frames. /// /// Handle returned from the function. /// Returns zero if successful or an error otherwise. [DllImport("avifil32")] public static extern int AVIStreamGetFrameClose(IntPtr getFrameObject); /// /// Return the address of a decompressed video frame. /// /// Pointer to a GetFrame object. /// Position, in samples, within the stream of the desired frame. /// Returns a pointer to the frame data if successful or NULL otherwise. [DllImport("avifil32")] public static extern IntPtr AVIStreamGetFrame(IntPtr getFrameObject, int position); /// /// Write data to a stream. /// /// Handle to an open stream. /// First sample to write. /// Number of samples to write. /// Pointer to a buffer containing the data to write. /// Size of the buffer referenced by buffer. /// Flag associated with this data. /// Pointer to a buffer that receives the number of samples written. This can be set to NULL. /// Pointer to a buffer that receives the number of bytes written. This can be set to NULL. /// /// Returns zero if successful or an error otherwise. /// [DllImport("avifil32")] public static extern AviError AVIStreamWrite(IntPtr streamHandler, int start, int samples, IntPtr buffer, int bufferSize, int flags, IntPtr samplesWritten, IntPtr bytesWritten); /// /// Retrieve the save options for a file and returns them in a buffer. /// /// Handle to the parent window for the Compression Options dialog box. /// Flags for displaying the Compression Options dialog box. /// Number of streams that have their options set by the dialog box. /// Pointer to an array of stream interface pointers. /// Pointer to an array of pointers to AVICOMPRESSOPTIONS structures. /// Returns TRUE if the user pressed OK, FALSE for CANCEL, or an error otherwise. [DllImport("avifil32")] public static extern int AVISaveOptions(IntPtr window, int flags, int streams, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] streamInterfaces, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] options); /// /// Free the resources allocated by the AVISaveOptions function. /// /// Count of the AVICOMPRESSOPTIONS structures referenced in options. /// Pointer to an array of pointers to AVICOMPRESSOPTIONS structures. /// Returns 0. [DllImport("avifil32")] public static extern AviError AVISaveOptionsFree(int streams, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] options); /// /// Create a compressed stream from an uncompressed stream and a /// compression filter, and returns the address of a pointer to /// the compressed stream. /// /// Pointer to a buffer that receives the compressed stream pointer. /// Pointer to the stream to be compressed. /// Pointer to a structure that identifies the type of compression to use and the options to apply. /// Pointer to a class identifier used to create the stream. /// Returns 0 if successful or an error otherwise. [DllImport("avifil32")] public static extern AviError AVIMakeCompressedStream(out IntPtr compressedStream, IntPtr sourceStream, ref AVICOMPRESSOPTIONS options, IntPtr clsidHandler); /// /// Code type /// public enum ICMODE { ICMODE_COMPRESS = 1, ICMODE_DECOMPRESS = 2, ICMODE_FASTDECOMPRESS = 3, ICMODE_QUERY = 4, ICMODE_FASTCOMPRESS = 5, ICMODE_DRAW = 8 } // --- structures /// /// Structor for the codec info /// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dd743162%28v=vs.85%29.aspx /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct ICINFO { public int dwSize; public int fccType; public int fccHandler; public int dwFlags; public int dwVersion; public int dwVersionICM; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string szName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szDescription; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szDriver; public ICINFO(int type) { dwSize = Marshal.SizeOf(typeof(ICINFO)); fccType = type; fccHandler = 0; dwFlags = 0; dwVersion = 0; dwVersionICM = 0; szName = null; szDescription = null; szDriver = null; } } /// /// Structure, which contains information for a single stream . /// /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] public struct AVISTREAMINFO { /// /// Four-character code indicating the stream type. /// /// [MarshalAs(UnmanagedType.I4)] public int type; /// /// Four-character code of the compressor handler that will compress this video stream when it is saved. /// /// [MarshalAs(UnmanagedType.I4)] public int handler; /// /// Applicable flags for the stream. /// /// [MarshalAs(UnmanagedType.I4)] public int flags; /// /// Capability flags; currently unused. /// /// [MarshalAs(UnmanagedType.I4)] public int ñapabilities; /// /// Priority of the stream. /// /// [MarshalAs(UnmanagedType.I2)] public short priority; /// /// Language of the stream. /// /// [MarshalAs(UnmanagedType.I2)] public short language; /// /// Time scale applicable for the stream. /// /// /// Dividing rate by scale gives the playback rate in number of samples per second. /// [MarshalAs(UnmanagedType.I4)] public int scale; /// /// Rate in an integer format. /// /// [MarshalAs(UnmanagedType.I4)] public int rate; /// /// Sample number of the first frame of the AVI file. /// /// [MarshalAs(UnmanagedType.I4)] public int start; /// /// Length of this stream. /// /// /// The units are defined by rate and scale. /// [MarshalAs(UnmanagedType.I4)] public int length; /// /// Audio skew. This member specifies how much to skew the audio data ahead of the video frames in interleaved files. /// /// [MarshalAs(UnmanagedType.I4)] public int initialFrames; /// /// Recommended buffer size, in bytes, for the stream. /// /// [MarshalAs(UnmanagedType.I4)] public int suggestedBufferSize; /// /// Quality indicator of the video data in the stream. /// /// /// Quality is represented as a number between 0 and 10,000. /// [MarshalAs(UnmanagedType.I4)] public int quality; /// /// Size, in bytes, of a single data sample. /// /// [MarshalAs(UnmanagedType.I4)] public int sampleSize; /// /// Dimensions of the video destination rectangle. /// /// [MarshalAs(UnmanagedType.Struct, SizeConst = 16)] public RECT rectFrame; /// /// Number of times the stream has been edited. /// /// [MarshalAs(UnmanagedType.I4)] public int editCount; /// /// Number of times the stream format has changed. /// /// [MarshalAs(UnmanagedType.I4)] public int formatChangeCount; /// /// Description of the stream. /// /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string name; } /// /// Structure, which contains information about a stream and how it is compressed and saved. /// /// [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct AVICOMPRESSOPTIONS { /// /// Four-character code indicating the stream type. /// /// [MarshalAs(UnmanagedType.I4)] public int type; /// /// Four-character code for the compressor handler that will compress this video stream when it is saved. /// /// [MarshalAs(UnmanagedType.I4)] public int handler; /// /// Maximum period between video key frames. /// /// [MarshalAs(UnmanagedType.I4)] public int keyFrameEvery; /// /// Quality value passed to a video compressor. /// /// [MarshalAs(UnmanagedType.I4)] public int quality; /// /// Video compressor data rate. /// /// [MarshalAs(UnmanagedType.I4)] public int bytesPerSecond; /// /// Flags used for compression. /// /// [MarshalAs(UnmanagedType.I4)] public int flags; /// /// Pointer to a structure defining the data format. /// /// [MarshalAs(UnmanagedType.I4)] public int format; /// /// Size, in bytes, of the data referenced by format. /// /// [MarshalAs(UnmanagedType.I4)] public int formatSize; /// /// Video-compressor-specific data; used internally. /// /// [MarshalAs(UnmanagedType.I4)] public int parameters; /// /// Size, in bytes, of the data referenced by parameters. /// [MarshalAs(UnmanagedType.I4)] public int parametersSize; /// /// Interleave factor for interspersing stream data with data from the first stream. /// /// [MarshalAs(UnmanagedType.I4)] public int interleaveEvery; } // --- enumerations /// /// File access modes. /// /// [Flags] public enum OpenFileMode { Read = 0x00000000, Write = 0x00000001, ReadWrite = 0x00000002, ShareCompat = 0x00000000, ShareExclusive = 0x00000010, ShareDenyWrite = 0x00000020, ShareDenyRead = 0x00000030, ShareDenyNone = 0x00000040, Parse = 0x00000100, Delete = 0x00000200, Verify = 0x00000400, Cancel = 0x00000800, Create = 0x00001000, Prompt = 0x00002000, Exist = 0x00004000, Reopen = 0x00008000 } /// /// .NET replacement of mmioFOURCC macros. Converts four characters to code. /// /// /// Four characters string. /// /// Returns the code created from provided characters. /// public static int mmioFOURCC(string str) { return (((int)(byte)(str[0])) | ((int)(byte)(str[1]) << 8) | ((int)(byte)(str[2]) << 16) | ((int)(byte)(str[3]) << 24)); } /// /// Inverse to . Converts code to fout characters string. /// /// /// Code to convert. /// /// Returns four characters string. /// public static string decode_mmioFOURCC(int code) { char[] chs = new char[4]; for (int i = 0; i < 4; i++) { chs[i] = (char)(byte)((code >> (i << 3)) & 0xFF); if (!char.IsLetterOrDigit(chs[i])) { chs[i] = ' '; } } return new string(chs); } /// /// Get a list of available codecs. /// /// List public static List AvailableCodecs { get { List returnValues = new List(); int codecNr = 0; ICINFO codecInfo = new ICINFO(mmioFOURCC("VIDC")); bool success = true; do { success = ICInfo(codecInfo.fccType, codecNr++, ref codecInfo); if (success) { IntPtr hic = ICOpen(codecInfo.fccType, codecInfo.fccHandler, ICMODE.ICMODE_QUERY); if (hic != IntPtr.Zero) { ICGetInfo(hic, ref codecInfo, Marshal.SizeOf(codecInfo)); string codecName = decode_mmioFOURCC(codecInfo.fccHandler); returnValues.Add(codecName); LOG.DebugFormat("Found codec {0} {4}, with name {1} and description {2}, driver {3}", codecName, codecInfo.szName, codecInfo.szDescription, codecInfo.szDriver, codecInfo.dwVersion); ICClose(hic); } } } while (success); return returnValues; } } /// /// Version of for one stream only. /// /// /// Stream to configure. /// Stream options. /// /// Returns TRUE if the user pressed OK, FALSE for CANCEL, or an error otherwise. /// public static int AVISaveOptions(IntPtr stream, ref AVICOMPRESSOPTIONS options) { IntPtr[] streams = new IntPtr[1]; IntPtr[] infPtrs = new IntPtr[1]; IntPtr mem; int ret; // alloc unmanaged memory mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AVICOMPRESSOPTIONS))); // copy from managed structure to unmanaged memory Marshal.StructureToPtr(options, mem, false); streams[0] = stream; infPtrs[0] = mem; // show dialog with a list of available compresors and configuration ret = AVISaveOptions(IntPtr.Zero, 0, 1, streams, infPtrs); // copy from unmanaged memory to managed structure options = (AVICOMPRESSOPTIONS)Marshal.PtrToStructure(mem, typeof(AVICOMPRESSOPTIONS)); // free AVI compression options AVISaveOptionsFree(1, infPtrs); // clear it, because the information already freed by AVISaveOptionsFree options.format = 0; options.parameters = 0; // free unmanaged memory Marshal.FreeHGlobal(mem); return ret; } } /// /// AVI Error Codes /// [Flags] public enum AviError : uint { /// /// Compression is not supported for this type of data. /// This error might be returned if you try to compress /// data that is not audio or video. /// AVIERR_UNSUPPORTED = 0x80044065, /// /// The file couldn't be read, indicating a corrupt file or an unrecognized format /// AVIERR_BADFORMAT = 0x80044066, /// /// There is not enough memory to complete the operation. /// AVIERR_MEMORY = 0x80044067, /// /// /// // TODO : Put documentation AVIERR_INTERNAL = 0x80044068, /// /// /// // TODO : Put documentation AVIERR_BADFLAGS = 0x80044069, /// /// /// // TODO : Put documentation AVIERR_BADPARAM = 0x8004406A, /// /// /// // TODO : Put documentation AVIERR_BADSIZE = 0x8004406B, /// /// /// // TODO : Put documentation AVIERR_BADHANDLE = 0x8004406C, /// /// A disk error occurred while reading the file /// AVIERR_FILEREAD = 0x8004406D, /// /// /// // TODO : Put documentation AVIERR_FILEWRITE = 0x8004406E, /// /// A disk error occurred while opening the file /// AVIERR_FILEOPEN = 0x8004406F, /// /// /// // TODO : Put documentation AVIERR_COMPRESSOR = 0x80044070, /// /// A suitable compressor cannot be found. /// AVIERR_NOCOMPRESSOR = 0x80044071, /// /// /// // TODO : Put documentation AVIERR_READONLY = 0x80044072, /// /// /// // TODO : Put documentation AVIERR_NODATA = 0x80044073, /// /// /// // TODO : Put documentation AVIERR_BUFFERTOOSMALL = 0x80044074, /// /// /// // TODO : Put documentation AVIERR_CANTCOMPRESS = 0x80044075, /// /// /// // TODO : Put documentation AVIERR_USERABORT = 0x800440C6, /// /// /// // TODO : Put documentation AVIERR_ERROR = 0x800440C7, /// /// Operation successful /// AVIERR_OK = 0x0 } }