namespace OpenVIII.AV { using FFmpeg.AutoGen; using System; public class FfccVaribleGroup : IDisposable { #region Fields public unsafe AVCodec* _codec; public unsafe AVCodecContext* _codecContext; public unsafe AVFormatContext* _format; public unsafe AVFrame* _frame; public unsafe AVPacket* _packet; private bool disposedValue = false; #endregion Fields #region Constructors public unsafe FfccVaribleGroup() { Format = ffmpeg.avformat_alloc_context(); Packet = ffmpeg.av_packet_alloc(); Frame = ffmpeg.av_frame_alloc(); CodecContext = null; StreamIndex = -1; } #endregion Constructors #region Destructors ~FfccVaribleGroup() { Dispose(false); } #endregion Destructors #region Properties /// /// Codec /// public unsafe AVCodec* Codec { get => _codec; set => _codec = value; } /// /// CodecContext /// public unsafe AVCodecContext* CodecContext { get => _codecContext; set => _codecContext = value; } /// /// Format holds alot of file info. File is opened and data about it is stored here. /// public unsafe AVFormatContext* Format { get => _format; set => _format = value; } /// /// Frame holds a chunk of data related to the current stream. /// public unsafe AVFrame* Frame { get => _frame; set => _frame = value; } /// /// Packet of data can contain 1 or more frames. /// public unsafe AVPacket* Packet { get => _packet; set => _packet = value; } /// /// Current Stream based on index /// public unsafe AVStream* Stream => StreamIndex >= 0 && Format != null ? Format->streams[StreamIndex] : null; /// /// Set Stream Index typically 0 is video 1 is audio, unless no video then 0 is audio. -1 for no stream of type. /// public int StreamIndex { get; set; } /// /// Type of current Stream. /// public unsafe AVMediaType Type => Stream != null ? Stream->codec->codec_type : AVMediaType.AVMEDIA_TYPE_UNKNOWN; #endregion Properties #region Methods // This code added to correctly implement the disposable pattern. public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); // TODO: uncomment the following line if the finalizer is overridden above. GC.SuppressFinalize(this); } protected virtual unsafe void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects). } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. if (_format != null) { fixed (AVFormatContext** tmp = &_format) { for (int i = 0; i < Format->nb_streams; i++) { ffmpeg.avcodec_close(Format->streams[i]->codec); } ffmpeg.avformat_close_input(tmp); } } if (_codecContext != null) { ffmpeg.avcodec_close(CodecContext); fixed (AVCodecContext** tmp = &_codecContext) { ffmpeg.avcodec_free_context(tmp); //ctd } } //ffmpeg.av_free(Codec); //CTD on linux ffmpeg.av_packet_unref(Packet); ffmpeg.av_free(Packet); ffmpeg.av_frame_unref(Frame); ffmpeg.av_free(Frame); ffmpeg.av_free(Stream); disposedValue = true; } } #endregion Methods } }