Exemplo n.º 1
0
 public static void Reset(this MediaDictionary?md, AVDictionary *dict)
 {
     if (md != null)
     {
         md._nativePointer = (IntPtr)dict;
     }
 }
Exemplo n.º 2
0
        public static MediaDictionary2 Copy(MediaDictionary2 source)
        {
            AVDictionary *destination = null;

            av_dict_copy(&destination, source, 0).ThrowIfError();
            return(new MediaDictionary2(destination));
        }
Exemplo n.º 3
0
        /// <summary>
        /// <see cref="avcodec_open2(AVCodecContext*, AVCodec*, AVDictionary**)"/>
        /// </summary>
        public void Open(Codec?codec = null, MediaDictionary?options = null)
        {
            AVDictionary *ptrDict = options;

            avcodec_open2(this, codec, &ptrDict).ThrowIfError();
            options.Reset(ptrDict);
        }
Exemplo n.º 4
0
        public void Close()
        {
            AVDictionary *p = this;

            av_dict_free(&p);
            _handle = null;
        }
        /// <summary>
        /// <see cref="avformat_write_header(AVFormatContext*, AVDictionary**)"/>
        /// </summary>
        public StreamInitIn WriteHeader(MediaDictionary?options = null)
        {
            AVDictionary *dictPtr = options;
            int           ret     = avformat_write_header(this, &dictPtr).ThrowIfError();

            options.Reset(dictPtr);
            return((StreamInitIn)ret);
        }
        /// <summary>
        /// <see cref="avformat_init_output(AVFormatContext*, AVDictionary**)"/>
        /// </summary>
        public StreamInitIn InitOutput(MediaDictionary?options = null)
        {
            AVDictionary *dictPtr = options;
            int           ret     = avformat_init_output(this, &dictPtr).ThrowIfError();

            options.Reset(dictPtr);
            return((StreamInitIn)ret);
        }
Exemplo n.º 7
0
        public static void OutputDictionary(AVDictionary *dict, string title)
        {
            var info = GetDictionary(dict);

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(title);
            Console.ResetColor();
            info.ToList().ForEach(x => Console.WriteLine($"{x.Key} = {x.Value}"));
        }
        /// <summary>
        /// <see cref="avformat_open_input(AVFormatContext**, string, AVInputFormat*, AVDictionary**)"/>
        /// </summary>
        public static FormatContext OpenInput(string?url, InputFormat?format = null, MediaDictionary?options = null)
        {
            AVFormatContext *resultPtr;
            AVDictionary *   dictPtr = options;

            avformat_open_input(&resultPtr, url, format, &dictPtr).ThrowIfError();
            options.Reset(dictPtr);
            return(new InputFormatContext(resultPtr, isOwner: true));
        }
Exemplo n.º 9
0
        private int InitInput()
        {
            _inputContext = avformat_alloc_context();

            AVDictionary *options = null;

            _errorId = av_dict_set(&options, "rtsp_transport", "udp", 0);
            if (CheckError(_errorId))
            {
                return(_errorId);
            }

            /*
             * 作者:Jack
             * 日期:2018-06-08
             * 描述:增加打开视频源超时.
             */
            _errorId = av_dict_set(&options, "stimeout", "5000000", 0);
            if (CheckError(_errorId))
            {
                return(_errorId);
            }
            //var startOpen = DateTime.Now;
            //AVIOInterruptCB_callback interruptCB_Callback = (p0) =>
            //{
            //    /// AVFormatContext* formatContext = (AVFormatContext*)p0;
            //    var endDate = DateTime.Now;
            //    if ((endDate - startOpen).Seconds >= 5)
            //    {
            //        Console.WriteLine((endDate - startOpen).Seconds);
            //        return 1;
            //    }
            //    return 0;
            //};
            //_inputContext->interrupt_callback.callback = interruptCB_Callback;
            // _inputContext->interrupt_callback.opaque = _inputContext;

            var inputContext = _inputContext;

            _errorId = avformat_open_input(&inputContext, _command.PullAddress, null, &options);
            if (CheckError(_errorId, "读取源地址超时.  "))
            {
                //如果读取失败, inpuContext分配内存空间也失败, 执行Dispose方法会报错.
                _inputContext = avformat_alloc_context();
                return(_errorId);
            }
            ;

            _errorId = avformat_find_stream_info(_inputContext, null);
            if (CheckError(_errorId))
            {
                return(_errorId);
            }

            return(0);
        }
Exemplo n.º 10
0
        /// <summary>
        /// <see cref="avio_open2(AVIOContext**, string, int, AVIOInterruptCB*, AVDictionary**)"/>
        /// </summary>
        public static unsafe MediaIO Open(string url, MediaIOFlags flags = MediaIOFlags.Read, MediaDictionary?options = null)
        {
            AVIOContext * ctx     = null;
            AVDictionary *dictPtr = options;

            avio_open2(&ctx, url, (int)flags, null, &dictPtr).ThrowIfError();
            options.Reset(dictPtr);

            return(new MediaIO(ctx, isOwner: true));
        }
Exemplo n.º 11
0
        /// <summary>
        /// <see cref="av_packet_unpack_dictionary(byte*, int, AVDictionary**)"/>
        /// </summary>
        public static MediaDictionary UnpackDictionary(Span <byte> data)
        {
            AVDictionary *dict = null;

            fixed(byte *ptr = data)
            {
                av_packet_unpack_dictionary(ptr, data.Length, &dict).ThrowIfError();
            }

            return(MediaDictionary.FromNative(dict, isOwner: true));
        }
Exemplo n.º 12
0
        public static IReadOnlyList <KeyValuePair <string, string> > GetKeyValues(AVDictionary *dict)
        {
            List <KeyValuePair <string, string> > keyValuePairs = new List <KeyValuePair <string, string> >();
            AVDictionaryEntry *t = null;

            while ((t = ffmpeg.av_dict_get(dict, "", t, (int)(DictFlags.AV_DICT_IGNORE_SUFFIX))) != null)
            {
                keyValuePairs.Add((*t).ToKeyValuePair());
            }
            return(keyValuePairs);
        }
Exemplo n.º 13
0
        public static KeyValuePair <string, string>[] GetKeyValues(AVDictionary *dict)
        {
            List <KeyValuePair <string, string> > keyValuePairs = new List <KeyValuePair <string, string> >();
            AVDictionaryEntry *t = null;

            while ((t = ffmpeg.av_dict_get(dict, "", t, (int)(DictFlags.IgnoreSuffix))) != null)
            {
                keyValuePairs.Add((*t).ToKeyValuePair());
            }
            return(keyValuePairs.ToArray());
        }
Exemplo n.º 14
0
        /// <summary>
        /// Sets the value for the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="dontOverwrite">if set to <c>true</c> [dont overwrite].</param>
        public void Set(string key, string value, bool dontOverwrite)
        {
            var flags = 0;

            if (dontOverwrite)
            {
                flags |= ffmpeg.AV_DICT_DONT_OVERWRITE;

                fixed(AVDictionary **reference = &Pointer)
                {
                    ffmpeg.av_dict_set(reference, key, value, flags);
                    Pointer = *reference;
                }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Converts the AVDictionary to a regular dictionary.
        /// </summary>
        /// <param name="dictionary">The dictionary to convert from.</param>
        /// <returns>the converterd dictionary</returns>
        public static Dictionary <string, string> ToDictionary(AVDictionary *dictionary)
        {
            var result = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            var metadataEntry = ffmpeg.av_dict_get(dictionary, string.Empty, null, ffmpeg.AV_DICT_IGNORE_SUFFIX);

            while (metadataEntry != null)
            {
                result[Utils.PtrToString(metadataEntry->key)] = Utils.PtrToString(metadataEntry->value);
                metadataEntry = ffmpeg.av_dict_get(dictionary, string.Empty, metadataEntry, ffmpeg.AV_DICT_IGNORE_SUFFIX);
            }

            return(result);
        }
Exemplo n.º 16
0
        public unsafe void Dispose(bool dispose)
        {
            if (Pointer == null)
                return;

            // Console.WriteLine("Disposing AVDictionary");

            fixed(AVDictionary **p = &Pointer)
            {
                ffmpeg.av_dict_free(p);

                Pointer = null;
            }
        }
Exemplo n.º 17
0
        private static IReadOnlyDictionary <string, string> GetDictionary(AVDictionary *dict)
        {
            AVDictionaryEntry *tag = null;
            var result             = new Dictionary <string, string>();

            while ((tag = ffmpeg.av_dict_get(dict, "", tag, ffmpeg.AV_DICT_IGNORE_SUFFIX)) != null)
            {
                var key   = Marshal.PtrToStringAnsi((IntPtr)tag->key);
                var value = Marshal.PtrToStringAnsi((IntPtr)tag->value);
                result.Add(key, value);
            }

            return(result);
        }
Exemplo n.º 18
0
        public bool Remove(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            AVDictionary *ptr         = this;
            bool          containsKey = ContainsKey(key);

            av_dict_set(&ptr, key, null, 0).ThrowIfError();
            _handle = ptr;
            return(containsKey);
        }
Exemplo n.º 19
0
        /// <summary>
        /// A wrapper for the av_dict_get method
        /// </summary>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="key">The key.</param>
        /// <param name="matchCase">if set to <c>true</c> [match case].</param>
        /// <returns></returns>
        public static FFDictionaryEntry GetEntry(AVDictionary *dictionary, string key, bool matchCase = true)
        {
            if (dictionary == null)
            {
                return(null);
            }

            var entryPointer = ffmpeg.av_dict_get(dictionary, key, null, matchCase ? ffmpeg.AV_DICT_MATCH_CASE : 0);

            if (entryPointer == null)
            {
                return(null);
            }
            return(new FFDictionaryEntry(entryPointer));
        }
Exemplo n.º 20
0
        public void Set(string key, string value, DictFlags flags = DictFlags.DontOverwrite)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));                // in AVDictionary, value is also not-null.
            }
            AVDictionary *ptr = this;

            av_dict_set(&ptr, key, value, (int)flags).ThrowIfError();
            _handle = ptr;
        }
Exemplo n.º 21
0
        internal unsafe static IDictionary <string, string> DictionaryConvert(AVDictionary *avDictionary)
        {
            IDictionary <string, string> metaDataDictionary = new Dictionary <string, string>();
            AVDictionaryEntry *          dictEntry          = null;

            do
            {
                dictEntry = ffmpeg.av_dict_get(avDictionary, string.Empty, dictEntry, ffmpeg.AV_DICT_IGNORE_SUFFIX);
                if (dictEntry != null)
                {
                    metaDataDictionary.Add(
                        Marshal.PtrToStringAnsi(new IntPtr(dictEntry->key)),
                        Marshal.PtrToStringAnsi(new IntPtr(dictEntry->value)));
                }
            } while (dictEntry != null);

            return(metaDataDictionary);
        }
Exemplo n.º 22
0
        internal static unsafe Dictionary <string, string> ToDictionary(AVDictionary *avDictionary)
        {
            var dictionary = new Dictionary <string, string>();

            if (avDictionary == null)
            {
                return(dictionary);
            }

            AVDictionaryEntry *tag = null;

            while ((tag = ffmpeg.av_dict_get(avDictionary, string.Empty, tag, ffmpeg.AV_DICT_IGNORE_SUFFIX)) != null)
            {
                var key   = Marshal.PtrToStringAnsi((IntPtr)tag->key);
                var value = Marshal.PtrToStringAnsi((IntPtr)tag->value);
                dictionary.Add(key, value);
            }
            return(dictionary);
        }
Exemplo n.º 23
0
        public string this[string key]
        {
            get
            {
                AVDictionaryEntry *entry = av_dict_get(this, key, null, (int)DictFlags.MatchCase);
                if (entry == null)
                {
                    throw new KeyNotFoundException(key);
                }

                return(((IntPtr)entry->value).PtrToStringUTF8());
            }
            set
            {
                AVDictionary *ptr = this;
                av_dict_set(&ptr, key, value, (int)DictFlags.None).ThrowIfError();
                _handle = ptr;
            }
        }
Exemplo n.º 24
0
        public string this[string key]
        {
            get
            {
                AVDictionaryEntry *entry = av_dict_get(this, key, null, (int)MediaDictionaryReadFlags.CaseSensitive);
                if (entry == null)
                {
                    throw new KeyNotFoundException(key);
                }

                return(Marshal.PtrToStringUTF8((IntPtr)entry->value));
            }
            set
            {
                AVDictionary *ptr = this;
                av_dict_set(&ptr, key, value, (int)MediaDictionarySetFlags.None).ThrowIfError();
                _nativePointer = (IntPtr)ptr;
            }
        }
Exemplo n.º 25
0
        public void Add(string key, string value)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));                // in AVDictionary, value is also not-null.
            }
            if (ContainsKey(key))
            {
                throw new ArgumentException($"An item with the same key has already been added. Key: {key}");
            }

            AVDictionary *ptr = this;

            av_dict_set(&ptr, key, value, (int)DictFlags.DontOverwrite).ThrowIfError();
            _handle = ptr;
        }
        private static unsafe String GetAvFoundationLogsAboutDevicesList()
        {
            String inputFormat = "avfoundation";

            AVInputFormat *  avInputFormat = ffmpeg.av_find_input_format(inputFormat);
            AVFormatContext *pFormatCtx    = ffmpeg.avformat_alloc_context();
            AVDictionary *   options       = null;

            ffmpeg.av_dict_set(&options, "list_devices", "true", 0);

            // We use temporarily a specific callback to log FFmpeg entries
            FFmpegInit.UseSpecificLogCallback();
            ffmpeg.avformat_open_input(&pFormatCtx, null, avInputFormat, &options); // Here nb is < 0 ... But we have anyway an output from av_log which can be parsed ...
            ffmpeg.avformat_close_input(&pFormatCtx);

            // We no more need to use temporarily a specific callback to log FFmpeg entries
            FFmpegInit.UseDefaultLogCallback();

            // returns logs
            return(FFmpegInit.GetStoredLogs());
        }
Exemplo n.º 27
0
        private static unsafe void open_audio(AVFormatContext *oc, AVStream *st)
        {
            AVCodecContext *c = st->codec;
            AVCodec *       codec;

            /* find the audio encoder */
            codec = ffmpeg.avcodec_find_encoder(c->codec_id);
            if (codec == null)
            {
                die("avcodec_find_encoder");
            }

            /* open it */
            AVDictionary *dict = null;

            ffmpeg.av_dict_set(&dict, "strict", "+experimental", 0);
            int res = ffmpeg.avcodec_open2(c, codec, &dict);

            if (res < 0)
            {
                die("avcodec_open");
            }
        }
Exemplo n.º 28
0
        private void DoStart()
        {
            var vss = Source;

            if (!_modeAudio)
            {
                vss = Tokenise(vss);
            }

            AVDictionary *options = null;

            if (_inputFormat == null)
            {
                ffmpeg.av_dict_set(&options, "analyzeduration", _analyzeDuration.ToString(), 0);



                string prefix = vss.ToLower().Substring(0, vss.IndexOf(":", StringComparison.Ordinal));
                switch (prefix)
                {
                case "http":
                case "mmsh":
                case "mms":
                    ffmpeg.av_dict_set(&options, "timeout", _timeout.ToString(), 0);
                    ffmpeg.av_dict_set(&options, "stimeout", (_timeout * 1000).ToString(), 0);

                    if (_cookies != "")
                    {
                        ffmpeg.av_dict_set(&options, "cookies", _cookies, 0);
                    }

                    if (_headers != "")
                    {
                        ffmpeg.av_dict_set(&options, "headers", _headers, 0);
                    }
                    if (_userAgent != "")
                    {
                        ffmpeg.av_dict_set(&options, "user-agent", _userAgent, 0);
                    }
                    break;

                case "tcp":
                case "udp":
                case "rtp":
                case "sdp":
                case "mmst":
                case "ftp":
                    ffmpeg.av_dict_set(&options, "timeout", _timeout.ToString(), 0);
                    break;

                case "rtsp":
                case "rtmp":
                    ffmpeg.av_dict_set(&options, "stimeout", (_timeout * 1000).ToString(), 0);
                    if (_userAgent != "")
                    {
                        ffmpeg.av_dict_set(&options, "user-agent", _userAgent, 0);
                    }
                    break;
                }

                ffmpeg.av_dict_set(&options, "rtsp_transport", RTSPmode, 0);
            }

            ffmpeg.av_dict_set(&options, "rtbufsize", "10000000", 0);

            var lo = _options.Split(Environment.NewLine.ToCharArray());

            foreach (var nv in lo)
            {
                if (!string.IsNullOrEmpty(nv))
                {
                    var i = nv.IndexOf('=');
                    if (i > -1)
                    {
                        var n = nv.Substring(0, i).Trim();
                        var v = nv.Substring(i + 1).Trim();
                        if (!string.IsNullOrEmpty(n) && !string.IsNullOrEmpty(v))
                        {
                            int j;
                            if (int.TryParse(v, out j))
                            {
                                ffmpeg.av_dict_set_int(&options, n, j, 0);
                            }
                            else
                            {
                                ffmpeg.av_dict_set(&options, n, v, 0);
                            }
                        }
                    }
                }
            }


            _stopReadingFrames = false;
            try
            {
                Program.FfmpegMutex.WaitOne();
                var pFormatContext = ffmpeg.avformat_alloc_context();
                _lastPacket = DateTime.UtcNow;


                _interruptCallback        = InterruptCb;
                _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

                pFormatContext->interrupt_callback.callback = _interruptCallbackAddress;
                pFormatContext->interrupt_callback.opaque   = null;


                if (ffmpeg.avformat_open_input(&pFormatContext, vss, _inputFormat, &options) != 0)
                {
                    throw new ApplicationException(@"Could not open source");
                }
                _formatContext = pFormatContext;


                SetupFormat();
            }
            catch (Exception ex)
            {
                ErrorHandler?.Invoke(ex.Message);
                _res = ReasonToFinishPlaying.VideoSourceError;
                PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
                AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
            }
            finally
            {
                try
                {
                    Program.FfmpegMutex.ReleaseMutex();
                }
                catch
                {
                }
            }
            _starting = false;
        }
Exemplo n.º 29
0
        private void Open(string fileName, int width, int height, AVCodecID videoCodec, int framerate, AVCodecID audioCodec)
        {
            CreatedDate  = DateTime.UtcNow;
            Filename     = fileName;
            _abort       = false;
            _ignoreAudio = false;

            if (videoCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                IsTimelapse = framerate != 0;

                if (((width & 1) != 0) || ((height & 1) != 0))
                {
                    throw new ArgumentException("Video file resolution must be a multiple of two.");
                }
            }

            int i;

            _lastPacket = DateTime.UtcNow;
            var outputFormat = ffmpeg.av_guess_format(null, fileName, null);

            if (outputFormat == null)
            {
                switch (videoCodec)
                {
                default:
                case AVCodecID.AV_CODEC_ID_MPEG1VIDEO:
                    outputFormat = ffmpeg.av_guess_format("mpeg1video", null, null);
                    break;
                }
            }

            _formatContext = ffmpeg.avformat_alloc_context();

            if (_formatContext == null)
            {
                throw new Exception("Cannot allocate format context.");
            }

            _interruptCallback        = InterruptCb;
            _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

            _formatContext->interrupt_callback.callback = _interruptCallbackAddress;
            _formatContext->interrupt_callback.opaque   = null;



            _formatContext->oformat = outputFormat;

            AVDictionary *opts = null;

            if (audioCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                AddAudioStream(audioCodec);
                OpenAudio();
            }

            if (videoCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                _width  = width;
                _height = height;
                //_bitRate = videoBitRate;
                _framerate           = framerate;
                _isConstantFramerate = framerate > 0;

                AddVideoStream(videoCodec);
                OpenVideo();

                if (videoCodec == AVCodecID.AV_CODEC_ID_MPEG1VIDEO)
                {
                    ffmpeg.av_dict_set(&opts, "pkt_size", "1316", 0);
                    ffmpeg.av_dict_set(&opts, "buffer_size", "65535", 0);

                    //ffmpeg.av_dict_set(&opts, "crf", "30", 0);
                }
            }


            if (movflags != "")
            {
                ffmpeg.av_dict_set(&opts, "movflags", movflags, 0);
            }


            if ((outputFormat->flags & ffmpeg.AVFMT_NOFILE) != ffmpeg.AVFMT_NOFILE)
            {
                i = ffmpeg.avio_open2(&_formatContext->pb, fileName, ffmpeg.AVIO_FLAG_WRITE, null, &opts);
                if (i < 0)
                {
                    throw new Exception("Cannot create the video file. (" + i + ")");
                }
            }

            i = ffmpeg.avformat_write_header(_formatContext, null);
            if (i < 0)
            {
                throw new Exception("Cannot write header - check disk space (" + i + ")");
            }

            ffmpeg.av_dict_free(&opts);

            _frameNumber        = 0;
            _recordingStartTime = DateTime.UtcNow;
            _opened             = true;
        }
Exemplo n.º 30
0
        private void DoStart()
        {
            var vss = Source;

            if (!IsAudio)
            {
                vss = Tokenise(vss);
            }

            if (string.IsNullOrEmpty(vss))
            {
                ErrorHandler?.Invoke("Source not found");
                _res = ReasonToFinishPlaying.VideoSourceError;
                CleanUp();
                _starting = false;
                return;
            }

            AVDictionary *options = null;

            if (_inputFormat == null)
            {
                var prefix = vss.ToLower().Substring(0, vss.IndexOf(":", StringComparison.Ordinal));
                ffmpeg.av_dict_set_int(&options, "rw_timeout", _timeoutMicroSeconds, 0);
                ffmpeg.av_dict_set_int(&options, "tcp_nodelay", 1, 0);
                switch (prefix)
                {
                case "https":
                case "http":
                case "mmsh":
                case "mms":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    ffmpeg.av_dict_set_int(&options, "stimeout", _timeoutMicroSeconds, 0);

                    if (!string.IsNullOrEmpty(_cookies))
                    {
                        ffmpeg.av_dict_set(&options, "cookies", _cookies, 0);
                    }
                    if (!string.IsNullOrEmpty(_headers))
                    {
                        ffmpeg.av_dict_set(&options, "headers", _headers, 0);
                    }
                    if (!string.IsNullOrEmpty(_userAgent))
                    {
                        ffmpeg.av_dict_set(&options, "user_agent", _userAgent, 0);
                    }
                    break;

                case "rtsp":
                case "rtmp":
                    ffmpeg.av_dict_set_int(&options, "stimeout", _timeoutMicroSeconds, 0);
                    if (!string.IsNullOrEmpty(_userAgent))
                    {
                        ffmpeg.av_dict_set(&options, "user_agent", _userAgent, 0);
                    }
                    if (!string.IsNullOrEmpty(_modeRTSP))
                    {
                        ffmpeg.av_dict_set(&options, "rtsp_transport", _modeRTSP, 0);
                    }
                    ffmpeg.av_dict_set(&options, "rtsp_flags", "prefer_tcp", 0);
                    break;

                default:
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;

                case "tcp":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;

                case "udp":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;
                }
                ffmpeg.av_dict_set_int(&options, "buffer_size", BUFSIZE, 0);
            }
            //ffmpeg.av_dict_set_int(&options, "rtbufsize", BUFSIZE, 0);

            var lo = _options.Split(Environment.NewLine.ToCharArray());

            foreach (var nv in lo)
            {
                if (!string.IsNullOrEmpty(nv))
                {
                    var i = nv.IndexOf('=');
                    if (i > -1)
                    {
                        var n = nv.Substring(0, i).Trim();
                        var v = nv.Substring(i + 1).Trim();
                        if (!string.IsNullOrEmpty(n) && !string.IsNullOrEmpty(v))
                        {
                            int j;
                            if (int.TryParse(v, out j))
                            {
                                ffmpeg.av_dict_set_int(&options, n, j, 0);
                            }
                            else
                            {
                                ffmpeg.av_dict_set(&options, n, v, 0);
                            }
                        }
                    }
                }
            }


            _abort = false;
            try
            {
                Program.MutexHelper.Wait();
                var pFormatContext = ffmpeg.avformat_alloc_context();
                _lastPacket = DateTime.UtcNow;


                _interruptCallback        = InterruptCb;
                _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

                _aviocb = new AVIOInterruptCB_callback_func
                {
                    Pointer = _interruptCallbackAddress
                };
                pFormatContext->interrupt_callback.callback = _aviocb;
                pFormatContext->interrupt_callback.opaque   = null;
                pFormatContext->max_analyze_duration        = 0; //0 = auto

                var t = _timeoutMicroSeconds;
                _timeoutMicroSeconds = Math.Max(_timeoutMicroSeconds, 15000000);

                Throw("OPEN_INPUT", ffmpeg.avformat_open_input(&pFormatContext, vss, _inputFormat, &options));
                _formatContext = pFormatContext;

                SetupFormat();

                _timeoutMicroSeconds = t;
            }
            catch (Exception ex)
            {
                ErrorHandler?.Invoke(ex.Message);
                _res = ReasonToFinishPlaying.VideoSourceError;
                CleanUp();
            }
            finally
            {
                try
                {
                    Program.MutexHelper.Release();
                }
                catch
                {
                }
            }

            _starting = false;
        }