public override void Dispose()
        {
            base.Dispose();
            if (_pTimer != null)
            {
                _pTimer.ResetStream();
                _pTimer.EnqueueForDelete();
                _pTimer = null;
            }
            _audioBuffer.Dispose();
            _videoBuffer.Dispose();
            _pSeekFile.Dispose();
            _pFile.Dispose();
//            ReleaseFile(_pSeekFile);
//          ReleaseFile(_pFile);
        }
        public virtual bool Initialize(int clientSideBufferLength)
        {
            //1. Check to see if we have an universal seeking file
            var seekFilePath = Name + "." + MEDIA_TYPE_SEEK;

            if (!File.Exists(seekFilePath))
            {
                var meta = Variant.GetMap(new VariantMapHelper {
                    { META_SERVER_FULL_PATH, Name }
                });
                if (!ResolveCompleteMetadata(ref meta))
                {
                    Logger.FATAL("Unable to generate metadata");
                    return(false);
                }
            }
            //2. Open the seek file
            _pSeekFile = MediaFile.Initialize(seekFilePath);
            if (_pSeekFile == null)
            {
                Logger.FATAL("Unable to open seeking file {0}", seekFilePath);
                return(false);
            }

            //3. read stream capabilities
            var streamCapabilitiesSize = _pSeekFile.Br.ReadUInt32();

            //var raw = new MemoryStream();
            //_pSeekFile.CopyPartTo(raw, (int)streamCapabilitiesSize);

            if (streamCapabilitiesSize < 14 || !StreamCapabilities.Deserialize(_pSeekFile.DataStream, Capabilities))
            {
                Logger.FATAL("Unable to deserialize stream Capabilities. Please delete {0} and {1} files so they can be regenerated",
                             Name + "." + MEDIA_TYPE_SEEK,
                             Name + "." + MEDIA_TYPE_META);
                return(false);
            }
            //4. compute offsets
            _seekBaseOffset   = _pSeekFile.Position;
            _framesBaseOffset = _seekBaseOffset + 4;
            //5. Compute the optimal window size by reading the biggest frame size
            //from the seek file.
            if (!_pSeekFile.SeekTo(_pSeekFile.Length - 8))
            {
                Logger.FATAL("Unable to seek to {0} position", _pSeekFile.Position - 8);
                return(false);
            }
            ulong maxFrameSize = _pSeekFile.Br.ReadUInt64();

            if (!_pSeekFile.SeekBegin())
            {
                Logger.FATAL("Unable to seek to beginning of the file");
                return(false);
            }
            //3. Open the media file
            var windowSize = (uint)maxFrameSize * 16;

            //windowSize = windowSize < 65536 ? 65536 : windowSize;
            //windowSize = (windowSize > (1024 * 1024)) ? (windowSize / 2) : windowSize;
            _pFile = MediaFile.Initialize(Name);
            //4. Read the frames count from the file
            if (!_pSeekFile.SeekTo(_seekBaseOffset))
            {
                Logger.FATAL("Unable to seek to _seekBaseOffset: {0}", _seekBaseOffset);
                return(false);
            }
            _totalFrames       = _pSeekFile.Br.ReadUInt32();
            _timeToIndexOffset = _framesBaseOffset + _totalFrames * MediaFrame.MediaFrameSize;

            //5. Set the client side buffer length
            _clientSideBufferLength = clientSideBufferLength;

            //6. Create the timer
            _pTimer = new InFileStreamTimer(this);
            _pTimer.EnqueueForTimeEvent((uint)(_clientSideBufferLength - _clientSideBufferLength / 3));

            //7. Done
            return(true);
        }