/// <summary> /// http://www.codeproject.com/KB/cs/idisposable.aspx /// </summary> protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // Dispose managed resources. } // There are no unmanaged resources to release, but // if we add them, they need to be released here. if (instance != IntPtr.Zero) { InteropWrapper.stream_close(instance); instance = IntPtr.Zero; readPacketDelegate = null; seekDelegate = null; } } disposed = true; // If it is available, make the call to the // base class's Dispose(Boolean) method //base.Dispose(disposing); }
/// <summary> /// Instatiates an FFmpeg reader that works in file mode, where FFmpeg gets the file name and /// handles file access itself. /// </summary> /// <param name="filename">the name of the file to read</param> /// <param name="mode">the types of data to read</param> public FFmpegReader(string filename, Type mode) { this.filename = filename; instance = InteropWrapper.stream_open_file(mode, filename); this.mode = mode; ReadOutputConfig(); }
private void CheckAndHandleOpeningError() { if (InteropWrapper.stream_has_error(instance)) { string errorMessage = Marshal.PtrToStringAnsi(InteropWrapper.stream_get_error(instance)); throw new IOException("Error opening the FFmpeg stream: " + errorMessage); } }
public int ReadFrame(out long timestamp, byte[] output_buffer, int output_buffer_size, out Type frameType) { int type; int ret = InteropWrapper.stream_read_frame(instance, out timestamp, output_buffer, output_buffer_size, out type); frameType = (Type)type; return(ret); }
private void ReadOutputConfig() { if ((mode & Type.Audio) != 0) { IntPtr ocp = InteropWrapper.stream_get_output_config(instance, Type.Audio); audioOutputConfig = (AudioOutputConfig)Marshal.PtrToStructure(ocp, typeof(AudioOutputConfig)); } if ((mode & Type.Video) != 0) { IntPtr ocp = InteropWrapper.stream_get_output_config(instance, Type.Video); videoOutputConfig = (VideoOutputConfig)Marshal.PtrToStructure(ocp, typeof(VideoOutputConfig)); } }
/// <summary> /// Instantiates an FFmpeg reader in stream mode, where FFmpeg only gets stream reading callbacks /// and the actual file access is handled by the caller. An optional file name hint can be passed /// to FFmpeg to help it detect the file format, which is useful for file formats without /// distinct headers (e.g. SHN). /// </summary> /// <param name="stream">the stream to decode</param> /// <param name="mode">the types of data to read</param> /// <param name="fileName">optional filename as a hint for FFmpeg to determine the data format</param> public FFmpegReader(Stream stream, Type mode, string fileName) { this.filename = fileName ?? "bufferedIO_stream"; this.mode = mode; var transferBuffer = new byte[0]; readPacketDelegate = delegate(IntPtr opaque, IntPtr buffer, int bufferSize) { /* NOTE there's no way to cast the IntPtr to a byte array which is required * for stream reading, so we need to add an intermediary transfer buffer. */ // Increase transfer buffer's size if too small if (transferBuffer.Length < bufferSize) { transferBuffer = new byte[bufferSize]; } // Read data into transfer buffer int bytesRead = stream.Read(transferBuffer, 0, bufferSize); // Transfer data to unmanaged memory Marshal.Copy(transferBuffer, 0, buffer, bytesRead); // Return number of bytes read return(bytesRead); }; seekDelegate = delegate(IntPtr opaque, long offset, int whence) { if (whence == 0x10000 /* AVSEEK_SIZE */) { return(stream.Length); } return(stream.Seek(offset, (SeekOrigin)whence)); }; instance = InteropWrapper.stream_open_bufferedio(mode, IntPtr.Zero, readPacketDelegate, seekDelegate, fileName); CheckAndHandleOpeningError(); ReadOutputConfig(); }
public void RemoveSeekIndex(Type type) { InteropWrapper.stream_seekindex_remove(instance, type); }
public void CreateSeekIndex(Type type) { InteropWrapper.stream_seekindex_create(instance, type); }
public void Seek(long timestamp, Type type) { InteropWrapper.stream_seek(instance, timestamp, type); }
public void RemoveSeekIndex(Type type) { CheckAndHandleActiveInstance(); InteropWrapper.stream_seekindex_remove(instance, type); }
public void Seek(long timestamp, Type type) { CheckAndHandleActiveInstance(); InteropWrapper.stream_seek(instance, timestamp, type); }