private void DeliverSample(ComObject requestToken, IRtspSample packet) { using (var sample = MediaFactory.CreateSample()) { using (var buffer = MediaFactory.CreateMemoryBuffer(packet.Buffer.Length)) { int max, cur; var ptr = buffer.Lock(out max, out cur); Marshal.Copy(packet.Buffer, 0, ptr, packet.Buffer.Length); buffer.CurrentLength = packet.Buffer.Length; buffer.Unlock(); sample.AddBuffer(buffer); } sample.SampleTime = packet.SampleTime; if (requestToken.NativePointer != IntPtr.Zero) { sample.Set(SampleAttributeKeys.Token, requestToken); } if (packet.IsKeyFrame) { sample.Set(SampleAttributeKeys.CleanPoint, true); } if (packet.Discontinuity) { sample.Set(SampleAttributeKeys.Discontinuity, true); } if (Type == StreamType.Video) { sample.Set(NaluAttributeKeys.LengthInformation, packet.LengthInfo.Select(BitConverter.GetBytes).SelectMany(b => b).ToArray()); } //Trace.WriteLine($"RtspMediaStream<{Type}>::DeliverSample() SampleTime={packet.SampleTime / 10000}(ms) Length={packet.Buffer.Length}"); _eventGenerator.QueueEventParamUnk(MediaEventTypes.MediaSample, Guid.Empty, Result.Ok, sample); } requestToken.Dispose(); _debugSaveStream?.Write(packet.Buffer, 0, packet.Buffer.Length); }
public void Start(/*IMFPresentationDescriptor*/ IntPtr pPresentationDescriptor, ref Guid pguidTimeFormat, ref Variant pvarStartPosition) { CheckShutdown(); Trace.WriteLine("RtspMediaSource::Start()"); if (!IsStopped && !IsPaused) { throw new SharpDXException(ResultCode.InvalidStateTransition); } if (pguidTimeFormat != null && pguidTimeFormat != Guid.Empty) { throw new SharpDXException(ResultCode.UnsupportedTimeFormat); } if (pPresentationDescriptor == IntPtr.Zero) { throw new ArgumentNullException(); } var pd = ComObjectUtils.AttachAs <PresentationDescriptor>(pPresentationDescriptor); try { // Get stream selection var selection = new bool[_streams.Length]; for (var i = 0; i < pd.StreamDescriptorCount; i++) { RawBool isSelected; var sdesc = pd.GetStreamDescriptorByIndex(i, out isSelected); var id = sdesc.StreamIdentifier; switch (id) { case (int)RtspMediaStream.StreamType.Video: case (int)RtspMediaStream.StreamType.Audio: selection[id] = isSelected; break; default: throw new ArgumentException(); } } // Activate selected stream for (var i = 0; i < selection.Length; i++) { if (selection[i]) { using (var comStream = new ComObject(_streams[i])) { if (_streams[i].IsActive) { // stream updated _eventGenerator.QueueEventParamUnk(MediaEventTypes.UpdatedStream, Guid.Empty, Result.Ok, comStream); } else { // new stream started _streams[i].Activate(); _eventGenerator.QueueEventParamUnk(MediaEventTypes.NewStream, Guid.Empty, Result.Ok, comStream); } } } else { _streams[i].Deactivate(); } } // Ignore pvarStartPosition _bufferingStartedSent = false; ChangeState(SourceState.Playing); _eventGenerator.QueueEventParamVar(MediaEventTypes.SourceStarted, Guid.Empty, Result.Ok, new Variant { Value = 0L }); } catch (Exception ex) { if (!IsShutdown) { _eventGenerator.QueueEventParamErr(ex.HResult); } throw; } finally { pd?.Dispose(); } }