Beispiel #1
0
        public int RequestAllocator(IMemAllocator pPreferred, AllocatorProperties pProps, out IMemAllocator ppActual)
        {
            int hr;

            Debug.WriteLine(string.Format("RequestAllocator {0} Align: {1} Buffer: {2} #: {3}",
                                          pPreferred != null, pProps.cbAlign, pProps.cbBuffer, pProps.cBuffers));
            Debug.Assert(pPreferred != null, "No allocator provided");

            // Need to set it to something.  Let's hope for the best.
            ppActual = pPreferred;

            lock (this) // Protect the m_ variables
            {
                // Release any previous allocator
                if ((m_MemAlloc != null) && (m_MemAlloc != pPreferred))
                {
                    Marshal.ReleaseComObject(m_MemAlloc);
                    m_MemAlloc = null;
                }

                if (pPreferred != null)
                {
                    m_MemAlloc = pPreferred;
                    hr         = S_Ok;
                }
                else
                {
                    // Todo - In theory, we should provide our own allocator if one isn't offered.
                    // In practice, no one accepts an allocator if I offer one.
                    hr = E_Fail;
                }
            }

            return(hr);
        }
Beispiel #2
0
        public int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
        {
#if HAMED_LOG_METHOD_INFO
            MethodBase method = new StackTrace().GetFrame(0).GetMethod();
            Console.WriteLine(this.GetType().FullName + " - " + method.Name + " - " + method.ToString());
#endif

            AllocatorProperties _actual = new AllocatorProperties();

            BitmapInfoHeader _bmi = (BitmapInfoHeader)Pins[0].CurrentMediaType;
            prop.cbBuffer = _bmi.GetBitmapSize();

            if (prop.cbBuffer < _bmi.ImageSize)
            {
                prop.cbBuffer = _bmi.ImageSize;
            }
            if (prop.cbBuffer < m_bmi.bmiHeader.ImageSize)
            {
                prop.cbBuffer = m_bmi.bmiHeader.ImageSize;
            }

            prop.cBuffers = 1;
            prop.cbAlign  = 1;
            prop.cbPrefix = 0;
            int hr = pAlloc.SetProperties(prop, _actual);
            return(hr);
        }
Beispiel #3
0
        public int SuggestAllocatorProperties(AllocatorProperties pprop)
        {
            AllocatorProperties _properties = new AllocatorProperties();
            HRESULT             hr          = (HRESULT)GetAllocatorProperties(_properties);

            if (FAILED(hr))
            {
                return(hr);
            }
            if (pprop.cbBuffer != -1)
            {
                if (pprop.cbBuffer < _properties.cbBuffer)
                {
                    return(E_FAIL);
                }
            }
            if (pprop.cbAlign != -1 && pprop.cbAlign != _properties.cbAlign)
            {
                return(E_FAIL);
            }
            if (pprop.cbPrefix != -1 && pprop.cbPrefix != _properties.cbPrefix)
            {
                return(E_FAIL);
            }
            if (pprop.cBuffers != -1 && pprop.cBuffers < 1)
            {
                return(E_FAIL);
            }
            return(NOERROR);
        }
Beispiel #4
0
        public int GetAllocatorProperties(AllocatorProperties pprop)
        {
            AMMediaType mt = Pins[0].CurrentMediaType;

            if (mt.majorType == MediaType.Video)
            {
                int lSize             = mt.sampleSize;
                BitmapInfoHeader _bmi = mt;
                if (_bmi != null)
                {
                    if (lSize < _bmi.GetBitmapSize())
                    {
                        lSize = _bmi.GetBitmapSize();
                    }
                    if (lSize < _bmi.ImageSize)
                    {
                        lSize = _bmi.ImageSize;
                    }
                }
                pprop.cbBuffer = lSize;
                pprop.cBuffers = 1;
                pprop.cbAlign  = 1;
                pprop.cbPrefix = 0;
            }
            return(NOERROR);
        }
Beispiel #5
0
        public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties pProperties)
        {
#if HAMED_LOG_METHOD_INFO
            MethodBase method = new StackTrace().GetFrame(0).GetMethod();
            Console.WriteLine(this.GetType().FullName + " - " + method.Name + " - " + method.ToString());
#endif

            if (!IsConnected)
            {
                return(VFW_E_NOT_CONNECTED);
            }
            AllocatorProperties _actual = new AllocatorProperties();
            HRESULT             hr      = (HRESULT)GetAllocatorProperties(_actual);
            if (SUCCEEDED(hr) && _actual.cBuffers <= pProperties.cBuffers && _actual.cbBuffer <= pProperties.cbBuffer && _actual.cbAlign == pProperties.cbAlign)
            {
                AllocatorProperties Actual = new AllocatorProperties();
                hr = (HRESULT)pAlloc.SetProperties(pProperties, Actual);
                if (SUCCEEDED(hr))
                {
                    pProperties.cbAlign  = Actual.cbAlign;
                    pProperties.cbBuffer = Actual.cbBuffer;
                    pProperties.cbPrefix = Actual.cbPrefix;
                    pProperties.cBuffers = Actual.cBuffers;
                }
            }
            return((m_Filter as VirtualCamFilter).DecideBufferSize(ref pAlloc, ref pProperties));
        }
Beispiel #6
0
        public int GetAllocatorProperties(AllocatorProperties pprop)
        {
#if HAMED_LOG_METHOD_INFO
            MethodBase method = new StackTrace().GetFrame(0).GetMethod();
            Console.WriteLine(this.GetType().FullName + " - " + method.Name + " - " + method.ToString());
#endif

            if (pprop == null)
            {
                return(E_POINTER);
            }
            if (m_pProperties != null)
            {
                pprop.cbAlign  = m_pProperties.cbAlign;
                pprop.cbBuffer = m_pProperties.cbBuffer;
                pprop.cbPrefix = m_pProperties.cbPrefix;
                pprop.cBuffers = m_pProperties.cBuffers;
                return(NOERROR);
            }
            if (IsConnected)
            {
                HRESULT hr = (HRESULT)Allocator.GetProperties(pprop);
                if (SUCCEEDED(hr) && pprop.cBuffers > 0 && pprop.cbBuffer > 0)
                {
                    return(hr);
                }
            }
            return((m_Filter as VirtualCamFilter).GetAllocatorProperties(pprop));
        }
Beispiel #7
0
        public int GetAllocatorProperties(AllocatorProperties pprop)
        {
#if HAMED_LOG_METHOD_INFO
            MethodBase method = new StackTrace().GetFrame(0).GetMethod();
            Console.WriteLine(this.GetType().FullName + " - " + method.Name + " - " + method.ToString());
#endif

            AMMediaType mt = Pins[0].CurrentMediaType;
            if (mt.majorType == MediaType.Video)
            {
                int lSize             = mt.sampleSize;
                BitmapInfoHeader _bmi = mt;
                if (_bmi != null)
                {
                    if (lSize < _bmi.GetBitmapSize())
                    {
                        lSize = _bmi.GetBitmapSize();
                    }
                    if (lSize < _bmi.ImageSize)
                    {
                        lSize = _bmi.ImageSize;
                    }
                }
                pprop.cbBuffer = lSize;
                pprop.cBuffers = 1;
                pprop.cbAlign  = 1;
                pprop.cbPrefix = 0;
            }
            return(NOERROR);
        }
Beispiel #8
0
        public int SuggestAllocatorProperties(AllocatorProperties pprop)
        {
#if HAMED_LOG_METHOD_INFO
            MethodBase method = new StackTrace().GetFrame(0).GetMethod();
            Console.WriteLine(this.GetType().FullName + " - " + method.Name + " - " + method.ToString());
#endif

            AllocatorProperties _properties = new AllocatorProperties();
            HRESULT             hr          = (HRESULT)GetAllocatorProperties(_properties);
            if (FAILED(hr))
            {
                return(hr);
            }
            if (pprop.cbBuffer != -1)
            {
                if (pprop.cbBuffer < _properties.cbBuffer)
                {
                    return(E_FAIL);
                }
            }
            if (pprop.cbAlign != -1 && pprop.cbAlign != _properties.cbAlign)
            {
                return(E_FAIL);
            }
            if (pprop.cbPrefix != -1 && pprop.cbPrefix != _properties.cbPrefix)
            {
                return(E_FAIL);
            }
            if (pprop.cBuffers != -1 && pprop.cBuffers < 1)
            {
                return(E_FAIL);
            }
            return(NOERROR);
        }
Beispiel #9
0
        public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
        {
            Console.WriteLine("DecideBufferSize");

            if (!Output.IsConnected)
            {
                return(VFW_E_NOT_CONNECTED);
            }
            if (Output.CurrentMediaType.majorType != MediaType.Video)
            {
                return(VFW_E_INVALIDMEDIATYPE);
            }
            AllocatorProperties _actual = new AllocatorProperties();
            BitmapInfoHeader    _bmi    = (BitmapInfoHeader)Output.CurrentMediaType;

            if (_bmi == null)
            {
                return(VFW_E_INVALIDMEDIATYPE);
            }
            prop.cbBuffer = _bmi.GetBitmapSize();
            if (prop.cbBuffer < _bmi.ImageSize)
            {
                prop.cbBuffer = _bmi.ImageSize;
            }
            prop.cBuffers = 1;
            int hr = pAlloc.SetProperties(prop, _actual);

            return(hr);
        }
Beispiel #10
0
 private void ShowAllocatorRequirements(object sender, EventArgs e)
 {
     if (connectingPin != null)
     {
         IMemInputPin imip = connectingPin.IPin as IMemInputPin;
         if (imip != null)
         {
             try
             {
                 AllocatorProperties pr = new AllocatorProperties();
                 int hr = imip.GetAllocatorRequirements(out pr);
                 DsError.ThrowExceptionForHR(hr);
                 if (pr != null)
                     Program.mainform.propform.SetObject(new FieldsToPropertiesProxyTypeDescriptor(pr));
             }
             catch (COMException ex)
             {
                 Graph.ShowCOMException(ex, "Can't get requirements");
             }
             catch (Exception ex)
             {
                 MessageBox.Show(ex.Message, "Exception caught in IMemInputPin::GetAllocatorRequirements");
             }
         }
     }
     connectingPin = null;
 }
Beispiel #11
0
 /// <summary>
 /// Meldet die Anforderungen dieses Endpunktes an die Speicherverwaltung.
 /// </summary>
 /// <param name="info">Die gewünschten Anforderungen.</param>
 public void GetAllocatorRequirements(ref AllocatorProperties info)
 {
     // Default all
     info.cbAlign  = 0;
     info.cbBuffer = 0;
     info.cbPrefix = 0;
     info.cBuffers = 0;
 }
Beispiel #12
0
 /// <summary>
 /// Requests an allocator during the pin connection.
 /// </summary>
 /// <param name="pPreferred">Pointer to the <see cref="IMemAllocator"/> interface on the input pin's preferred allocator, or NULL.</param>
 /// <param name="pProps">An <see cref="AllocatorProperties"/> structure, allocated by the caller. The caller should fill in any allocator properties that the input pin requires, and set the remaining members to zero.</param>
 /// <param name="ppActual">Pointer that receives an <see cref="IMemAllocator"/>.</param>
 /// <returns></returns>
 public int RequestAllocator(IntPtr pPreferred, AllocatorProperties pProps, out IntPtr ppActual)
 {
     lock (m_Lock)
     {
         // We are not working with Allocators, set the outgoing pointer to 0
         ppActual = IntPtr.Zero;
         return(E_NOTIMPL);
     }
 }
 int IAsyncReader.RequestAllocator(IMemAllocator pPreferred, AllocatorProperties pProps, out IMemAllocator ppActual)
 {
     if (pPreferred != null)
     {
         ppActual = pPreferred;
         if (pProps != null)
         {
             pPreferred.GetProperties(pProps);
         }
         return(S_OK);
     }
     ppActual = null;
     return(E_FAIL);
 }
        /// <summary>
        /// Verändert die Konfiguration der Speicherverwaltung.
        /// </summary>
        /// <param name="request">Die gewünschte Konfiguration.</param>
        /// <returns>Die tatsächlich ab sofort verwendete Konfiguration.</returns>
        /// <exception cref="COMException">Reicht Fehlermeldung des COM Objektes durch.</exception>
        public AllocatorProperties SetProperties(AllocatorProperties request)
        {
            // Helper
            AllocatorProperties actual = new AllocatorProperties();

            // Process
            Int32 hResult = m_SetProperties(ComInterface, ref request, ref actual);

            if (hResult < 0)
            {
                throw new COMException("MemoryAllocator.SetProperties", hResult);
            }

            // Report result
            return(actual);
        }
        /// <summary>
        /// Decides the size of the buffer.
        /// </summary>
        /// <param name="pAlloc">The p alloc.</param>
        /// <param name="prop">The property.</param>
        /// <returns></returns>
        public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
        {
            AllocatorProperties _actual = new AllocatorProperties();

            BitmapInfoHeader _bmi = CurrentMediaType;

            prop.cbBuffer = _bmi.GetBitmapSize();
            if (prop.cbBuffer < _bmi.ImageSize)
            {
                prop.cbBuffer = _bmi.ImageSize;
            }
            prop.cBuffers = 1;

            int hr = pAlloc.SetProperties(prop, _actual);

            return(hr);
        }
Beispiel #16
0
        private void TestAllocator()
        {
            int hr;
            AllocatorProperties pProps = new AllocatorProperties();

            pProps.cbAlign  = 1;
            pProps.cbBuffer = 1000;
            pProps.cbPrefix = 4;
            pProps.cBuffers = 6;

            // Doesn't seem to work right in c++ either
            hr = m_mts.SetStreamAllocatorRequirements(pProps);
            //MsError.ThrowExceptionForHR(hr);

            // Doesn't seem to work right in c++ either
            hr = m_mts.GetStreamAllocatorRequirements(out pProps);
            //MsError.ThrowExceptionForHR(hr);
        }
Beispiel #17
0
 private void ShowAllocatorProperties(object sender, EventArgs e)
 {
     if (connectingPin != null)
     {
         IMemInputPin imip = connectingPin.IPin as IMemInputPin;
         if (imip != null)
         {
             IMemAllocator ma = null;
             imip.GetAllocator(out ma);
             if (ma != null)
             {
                 AllocatorProperties pr = new AllocatorProperties();
                 ma.GetProperties(pr);
                 Program.mainform.propform.SetObject(new FieldsToPropertiesProxyTypeDescriptor(pr));
             }
         }
     }
     connectingPin = null;
 }
        private void TestAllocator()
        {
            int hr;
            AllocatorProperties pProps       = new AllocatorProperties();
            AllocatorProperties pActualProps = new AllocatorProperties();

            pProps.cbAlign  = 1;
            pProps.cbBuffer = 512 * 2;
            pProps.cbPrefix = 0;
            pProps.cBuffers = 5;

            hr = m_iar.RequestAllocator(null, pProps, out m_pActual);
            DsError.ThrowExceptionForHR(hr);

            hr = m_pActual.SetProperties(pProps, pActualProps);
            DsError.ThrowExceptionForHR(hr);

            hr = m_pActual.Commit();
            DsError.ThrowExceptionForHR(hr);
        }
Beispiel #19
0
        public int SuggestAllocatorProperties(AllocatorProperties pprop)
        {
#if HAMED_LOG_METHOD_INFO
            MethodBase method = new StackTrace().GetFrame(0).GetMethod();
            Console.WriteLine(this.GetType().FullName + " - " + method.Name + " - " + method.ToString());
#endif

            if (IsConnected)
            {
                return(VFW_E_ALREADY_CONNECTED);
            }
            HRESULT hr = (HRESULT)(m_Filter as VirtualCamFilter).SuggestAllocatorProperties(pprop);
            if (FAILED(hr))
            {
                m_pProperties = null;
                return(hr);
            }
            if (m_pProperties == null)
            {
                m_pProperties = new AllocatorProperties();
                (m_Filter as VirtualCamFilter).GetAllocatorProperties(m_pProperties);
            }
            if (pprop.cbBuffer != -1)
            {
                m_pProperties.cbBuffer = pprop.cbBuffer;
            }
            if (pprop.cbAlign != -1)
            {
                m_pProperties.cbAlign = pprop.cbAlign;
            }
            if (pprop.cbPrefix != -1)
            {
                m_pProperties.cbPrefix = pprop.cbPrefix;
            }
            if (pprop.cBuffers != -1)
            {
                m_pProperties.cBuffers = pprop.cBuffers;
            }
            return(NOERROR);
        }
Beispiel #20
0
        public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties pProperties)
        {
            if (!IsConnected)
            {
                return(VFW_E_NOT_CONNECTED);
            }
            AllocatorProperties _actual = new AllocatorProperties();
            HRESULT             hr      = (HRESULT)GetAllocatorProperties(_actual);

            if (SUCCEEDED(hr) && _actual.cBuffers <= pProperties.cBuffers && _actual.cbBuffer <= pProperties.cbBuffer && _actual.cbAlign == pProperties.cbAlign)
            {
                AllocatorProperties Actual = new AllocatorProperties();
                hr = (HRESULT)pAlloc.SetProperties(pProperties, Actual);
                if (SUCCEEDED(hr))
                {
                    pProperties.cbAlign  = Actual.cbAlign;
                    pProperties.cbBuffer = Actual.cbBuffer;
                    pProperties.cbPrefix = Actual.cbPrefix;
                    pProperties.cBuffers = Actual.cBuffers;
                }
            }
            return((m_Filter as VirtualCamFilter).DecideBufferSize(ref pAlloc, ref pProperties));
        }
Beispiel #21
0
        private void Setup()
        {
            int hr;

            m_ma = new MemoryAllocator() as IMemAllocatorCallbackTemp;

            AllocatorProperties pProps  = new AllocatorProperties();
            AllocatorProperties pActual = new AllocatorProperties();

            pProps.cbAlign  = 1;
            pProps.cbBuffer = 1024;
            pProps.cbPrefix = 0;
            pProps.cBuffers = 24;

            hr = m_ma.SetProperties(pProps, pActual);
            DsError.ThrowExceptionForHR(hr);

            hr = m_ma.SetNotify(this);
            DsError.ThrowExceptionForHR(hr);

            hr = m_ma.Commit();
            DsError.ThrowExceptionForHR(hr);
        }
Beispiel #22
0
        private void TestProp()
        {
            int hr;
            AllocatorProperties pProps  = new AllocatorProperties();
            AllocatorProperties pProps2 = new AllocatorProperties();
            AllocatorProperties pActual = new AllocatorProperties();

            hr = m_ma.GetProperties(pProps);
            DsError.ThrowExceptionForHR(hr);

            pProps.cbAlign  = 1;
            pProps.cbBuffer = 1024;
            pProps.cbPrefix = 0;
            pProps.cBuffers = 24;

            hr = m_ma.SetProperties(pProps, pActual);
            DsError.ThrowExceptionForHR(hr);

            hr = m_ma.GetProperties(pProps2);
            DsError.ThrowExceptionForHR(hr);

            Debug.Assert(pProps.cbBuffer == pProps2.cbBuffer, "Check Size");
            Debug.Assert(pProps.cbBuffer == pActual.cbBuffer, "Check Size");
        }
Beispiel #23
0
        public int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
        {
            AllocatorProperties _actual = new AllocatorProperties();

            BitmapInfoHeader _bmi = (BitmapInfoHeader)Pins[0].CurrentMediaType;

            prop.cbBuffer = _bmi.GetBitmapSize();

            if (prop.cbBuffer < _bmi.ImageSize)
            {
                prop.cbBuffer = _bmi.ImageSize;
            }
            if (prop.cbBuffer < m_bmi.bmiHeader.ImageSize)
            {
                prop.cbBuffer = m_bmi.bmiHeader.ImageSize;
            }

            prop.cBuffers = 1;
            prop.cbAlign  = 1;
            prop.cbPrefix = 0;
            int hr = pAlloc.SetProperties(prop, _actual);

            return(hr);
        }
Beispiel #24
0
        public int SuggestAllocatorProperties(AllocatorProperties pprop)
        {
            if (IsConnected)
            {
                return(VFW_E_ALREADY_CONNECTED);
            }
            HRESULT hr = (HRESULT)(m_Filter as VirtualCamFilter).SuggestAllocatorProperties(pprop);

            if (FAILED(hr))
            {
                m_pProperties = null;
                return(hr);
            }
            if (m_pProperties == null)
            {
                m_pProperties = new AllocatorProperties();
                (m_Filter as VirtualCamFilter).GetAllocatorProperties(m_pProperties);
            }
            if (pprop.cbBuffer != -1)
            {
                m_pProperties.cbBuffer = pprop.cbBuffer;
            }
            if (pprop.cbAlign != -1)
            {
                m_pProperties.cbAlign = pprop.cbAlign;
            }
            if (pprop.cbPrefix != -1)
            {
                m_pProperties.cbPrefix = pprop.cbPrefix;
            }
            if (pprop.cBuffers != -1)
            {
                m_pProperties.cBuffers = pprop.cBuffers;
            }
            return(NOERROR);
        }
Beispiel #25
0
 public int GetAllocatorProperties(AllocatorProperties pprop)
 {
     if (pprop == null)
     {
         return(E_POINTER);
     }
     if (m_pProperties != null)
     {
         pprop.cbAlign  = m_pProperties.cbAlign;
         pprop.cbBuffer = m_pProperties.cbBuffer;
         pprop.cbPrefix = m_pProperties.cbPrefix;
         pprop.cBuffers = m_pProperties.cBuffers;
         return(NOERROR);
     }
     if (IsConnected)
     {
         HRESULT hr = (HRESULT)Allocator.GetProperties(pprop);
         if (SUCCEEDED(hr) && pprop.cBuffers > 0 && pprop.cbBuffer > 0)
         {
             return(hr);
         }
     }
     return((m_Filter as VirtualCamFilter).GetAllocatorProperties(pprop));
 }
Beispiel #26
0
 int IMemAllocator.GetProperties(AllocatorProperties pProps)
 {
     throw new NotImplementedException();
 }
Beispiel #27
0
 public int RequestAllocator(IMemAllocator pPreferred, AllocatorProperties pProps, out IMemAllocator ppActual)
 {
     ppActual = null;
     return(1);
 }
Beispiel #28
0
 int IMemAllocator.SetProperties(AllocatorProperties pRequest, AllocatorProperties pActual)
 {
     throw new NotImplementedException();
 }
Beispiel #29
0
        /// <summary>
        /// Nimmt Rohdaten zur Übermittelung in den Direct Show Graphen entgegen.
        /// </summary>
        /// <param name="buffer">Ein Rohdatenblock - ist dieser Parameter <i>null</i>,
        /// so wird das Ende des Rohdatenstroms angezeigt und die Direct Show
        /// Speicherverwaltungsinstanz freigegeben.</param>
        /// <param name="offset">Erstes zu verwendendes Byte im Rohdatenblock.</param>
        /// <param name="length">Anzahl der Bytes, die dem Rohdatenblock zu entnehmen sind.</param>
        /// <param name="sync">Gesetzt, wenn die Rohdaten einen Synchronisationspunkt im
        /// Datenstrom bezeichnen.</param>
        /// <param name="time">Gesetzt auf eine <i>Stream Time</i>, wenn die Rohdaten
        /// einen PTS getragen haben.</param>
        public void Inject(byte[] buffer, int offset, int length, bool sync, long?time)
        {
            // Force shutdown of allocator
            if (null == buffer)
            {
                // Release allocator
                if (null != m_Allocator)
                {
                    // Release memory
                    m_Allocator.Decommit();

                    // Release
                    m_Allocator.Dispose();

                    // Back to CLR
                    m_Allocator = null;

                    // Report
                    OnAllocatorChanged(null);
                }

                // Done
                return;
            }

            // Count
            m_BytesReceived += length;

            // Discard when not running
            if (!m_Running)
            {
                // Get rid of the rest
                Flush();

                // Done
                return;
            }

            // Create allocator once
            if (null == m_Allocator)
            {
                // Create allocator
                m_Allocator = new NoMarshalComObjects.MemoryAllocator();

                // Properties
                AllocatorProperties props = new AllocatorProperties();

                // Configure
                props.cbAlign  = 8;
                props.cBuffers = m_Count;
                props.cbBuffer = m_Buffer.Length;

                // Store
                m_Allocator.SetProperties(props);
                m_Allocator.Commit();

                // Forward
                OnAllocatorChanged(m_Allocator);
            }

            // Flush
            if (sync || time.HasValue)
            {
                // Get rid of buffer
                Flush();

                // We are now doing a sync
                m_SyncWaiting = sync;
                m_SyncTime    = time;
            }

            // All of it
            while (length > 0)
            {
                // Check for fill up
                int fill = Math.Min(m_Buffer.Length - m_Index, length);

                // Copy over
                Array.Copy(buffer, offset, m_Buffer, m_Index, fill);

                // Adjust buffer
                m_Index += fill;

                // Adjust input
                offset += fill;
                length -= fill;

                // See if we should send
                if (m_Index >= m_Buffer.Length)
                {
                    Flush();
                }
            }
        }