Exemplo n.º 1
0
        public override bool Seek(double absoluteTimestamp)
        {
#if PARALLEL
            OutStreams.AsParallel().ForAll(x =>
            {
                if (!x.InStream.SignalSeek(ref absoluteTimestamp))
                {
                    Logger.WARN("Unable to signal seek on an outbound stream");
                }
            });
#else
            foreach (
                var baseOutStream in
                OutStreams.Where(
                    baseOutStream => !baseOutStream.SignalSeek(ref absoluteTimestamp)))
            {
                Logger.WARN("Unable to signal seek on an outbound stream");
            }
#endif
            if (!SignalSeek(ref absoluteTimestamp))
            {
                Logger.FATAL("Unable to signal seek");
                return(false);
            }
            return(true);
        }
Exemplo n.º 2
0
        public override bool Stop()
        {
            if (!SignalStop())
            {
                Logger.FATAL("Unable to signal stop");
                return(false);
            }
#if PARALLEL
            OutStreams.AsParallel().ForAll(x =>
            {
                if (!x.InStream.SignalStop())
                {
                    Logger.WARN("Unable to signal stop on an outbound stream");
                }
            });
#else
            foreach (
                var baseOutStream in
                OutStreams.Where(
                    baseOutStream => !baseOutStream.SignalStop()))
            {
                Logger.WARN("Unable to signal stop on an outbound stream");
            }
#endif
            return(true);
        }
Exemplo n.º 3
0
        public bool Link(IOutStream pOutStream, bool reverseLink = true)
        {
            if (!pOutStream.IsCompatibleWithType(Type) || !IsCompatibleWithType(pOutStream.Type))
            {
                Logger.FATAL("stream type {0} not compatible with stream type {1}", Type.TagToString(), pOutStream.Type.TagToString());
                return(false);
            }
            if (OutStreams.Contains(pOutStream))
            {
                Logger.WARN("BaseInStream::Link: This stream is already linked");
                return(true);
            }
            OutStreams.Add(pOutStream);
            if (reverseLink)
            {
                if (!pOutStream.Link(this, false))
                {
                    Logger.FATAL("BaseInStream::Link: Unable to reverse link");
                    //NYIA;
                    return(false);
                }
            }
            SignalOutStreamAttached(pOutStream);

            return(true);
        }
Exemplo n.º 4
0
        public override bool Play(double absoluteTimestamp, double length)
        {
            if (!SignalPlay(ref absoluteTimestamp, ref length))
            {
                Logger.FATAL("Unable to signal play");
                return(false);
            }

#if PARALLEL
            OutStreams.AsParallel().ForAll(x =>
            {
                if (!x.InStream.SignalPlay(ref absoluteTimestamp, ref length))
                {
                    Logger.WARN("Unable to signal play on an outbound stream");
                }
            });
#else
            foreach (
                var baseOutStream in
                OutStreams.Where(
                    baseOutStream => !baseOutStream.SignalPlay(ref absoluteTimestamp, ref length)))
            {
                Logger.WARN("Unable to signal play on an outbound stream");
            }
#endif
            return(true);
        }
Exemplo n.º 5
0
        public void Start(Peer peer, uint publisherId, FlowWriter controller)
        {
            if (PublisherId != 0)
            {
                if (controller != null)
                {
                    controller.WriteStatusResponse("Publish.BadName", Name + "is already published");
                }
            }
            PublisherId = publisherId;

            //string error;
            //if (!peer.OnPublish(this, out error))
            //{
            //    if (String.IsNullOrEmpty(error)) error = "Not allowed to publish " + Name;
            //}
            _publisher     = peer;
            _controller    = controller;
            _firstKeyFrame = false;
            foreach (var baseOutStream in OutStreams.OfType <IOutNetStream>())
            {
                baseOutStream.SendPublishNotify();
            }
            if (controller != null)
            {
                controller.WriteStatusResponse("Publish.Start", Name + "is now published");
            }
        }
Exemplo n.º 6
0
 public bool UnLink(IOutStream pOutStream)
 {
     OutStreams.Remove(pOutStream);
     OnFeedData          -= pOutStream.FeedData;
     OnSendStreamMessage -= pOutStream.SendStreamMessage;
     SignalOutStreamDetached(pOutStream);
     return(true);
 }
Exemplo n.º 7
0
        public override void Dispose()
        {
            base.Dispose();

            foreach (var outStream in OutStreams)
            {
                OnFeedData          -= outStream.FeedData;
                OnSendStreamMessage -= outStream.SendStreamMessage;
                outStream.UnLink();
            }
            OutStreams.Clear();
        }
Exemplo n.º 8
0
        protected override bool FeedMetaData(MediaFile pFile, MediaFrame mediaFrame)
        {
            //1. Seek into the data file at the correct position
            if (!pFile.SeekTo(mediaFrame.Start))
            {
                FATAL("Unable to seek to position {0}", mediaFrame.Start);
                return(false);
            }
            var endPosition = pFile.Position + (long)mediaFrame.Length;

            //2. Read the data
            //_metadataBuffer.IgnoreAll();
            //if (!_metadataBuffer.ReadFromFs(pFile, (int) mediaFrame.Length)) {
            //    Logger.FATAL("Unable to read {0} bytes from offset {1}", mediaFrame.Length, mediaFrame.Start);
            //    return false;
            //}

            //3. Parse the metadata
            _metadataName = "";
            _metadataParameters.SetValue();

            var _tempVariant = _amf0Reader.ReadVariant();

            //if (!_amfSerializer.Read(_metadataBuffer, _tempVariant)) {
            //    Logger.WARN("Unable to read metadata");
            //    return true;
            //}
            if (_tempVariant != VariantType.String)
            {
                WARN("Unable to read metadata");
                return(true);
            }
            _metadataName = _tempVariant;

            while (pFile.Position < endPosition)
            {
                _metadataParameters.Add(_amf0Reader.ReadVariant());
            }

            var message = GenericMessageFactory.GetNotify(
                ((BaseOutNetRTMPStream )OutStreams.Last()).CommandsChannelId,
                ((BaseOutNetRTMPStream )OutStreams.Last()).RTMPStreamId,
                mediaFrame.AbsoluteTime,
                true,
                _metadataName,
                _metadataParameters);

            //5. Send it
            return(((BaseRTMPProtocol )Protocol).SendMessage(message, true));
        }
Exemplo n.º 9
0
 public override bool Stop()
 {
     if (PublisherId == 0)
     {
         return(true);
     }
     foreach (var baseOutStream in OutStreams.OfType <IOutNetStream>())
     {
         baseOutStream.SendUnpublishNotify();
     }
     _controller.WriteStatusResponse("Unpublish.Success", Name + " is now unpublished");
     Flush();
     PublisherId = 0;
     _publisher  = null;
     return(true);
 }
Exemplo n.º 10
0
 public override void ReadyForSend()
 {
     lock (this)
     {
         if (!Feed())
         {
             Logger.FATAL("Feed failed");
             if (OutStreams.Any())
             {
                 OutStreams.Last().EnqueueForDelete();
             }
         }
         else
         {
             Flush();
         }
     }
 }
Exemplo n.º 11
0
 protected override bool FeedOtherType()
 {
     if (_currentFrame.Type == MediaFrameType.Message && OutStreams.Last() is BaseOutNetRTMPStream)
     {
         if (!_pFile.SeekTo(_currentFrame.Start))
         {
             FATAL("Unable to seek to position {0}", _currentFrame.Start);
             return(false);
         }
         var buffer = new BufferWithOffset(_amf0Reader.BaseStream, false, (int)_currentFrame.Length);
         SendStreamMessage(buffer);
         _pFile.Position = _currentFrame.Start + _currentFrame.Length;
         //message.Recycle();
         _currentFrameIndex++;
         return(true);
     }
     //todo 这里会导致播放中断,对于其他协议要修改
     Paused = true;
     return(base.FeedOtherType());
 }
Exemplo n.º 12
0
        public override bool FeedData(Stream pData, uint dataLength, uint processedLength, uint totalLength, uint absoluteTimestamp, bool isAudio)
        {
            switch (_rtcpPresence)
            {
            case RtcpPresence.Unknown:
                if (_rtcpDetectionInterval == TimeSpan.Zero)
                {
                    WARN("RTCP disabled on stream {0}({1}) with name {2}. A/V drifting may occur over long periods of time", Type.TagToString(), UniqueId, Name);
                    _rtcpPresence = RtcpPresence.Absent;
                    return(true);
                }
                if (_rtcpDetectionStart == DateTime.MinValue)
                {
                    _rtcpDetectionStart = DateTime.Now;
                    return(true);
                }
                if (DateTime.Now - _rtcpDetectionStart > _rtcpDetectionInterval)
                {
                    WARN("Stream {0}({1}) with name {2} doesn't have RTCP. A/V drifting may occur over long periods of time", Type.TagToString(), UniqueId, Name);
                    _rtcpPresence = RtcpPresence.Absent;
                    return(true);
                }

                var audioRTCPPresent = !_hasAudio || _audioNTP != 0;
                var videoRTCPPresent = !_hasVideo || _videoNTP != 0;
                if (audioRTCPPresent && videoRTCPPresent)
                {
                    _rtcpPresence = RtcpPresence.Available;
                }
                return(true);

            case RtcpPresence.Available:
                var rtp = isAudio ? _audioRTP : _videoRTP;
                var ntp = isAudio ? _audioNTP : _videoNTP;
                absoluteTimestamp = (uint)(ntp + absoluteTimestamp - rtp);

                break;

            case RtcpPresence.Absent:
                var firstTimestamp = isAudio ? _audioFirstTimestamp : _videoFirstTimestamp;
                if (firstTimestamp < 0)
                {
                    firstTimestamp = absoluteTimestamp;
                }
                absoluteTimestamp -= (uint)firstTimestamp;
                break;

            default:
                return(false);
            }
            var lastTs = isAudio ? _audioLastTs : _videoLastTs;

            if (-1.0 < lastTs * 100.0 - absoluteTimestamp * 100.0 && lastTs * 100.0 - absoluteTimestamp * 100.0 < 1.0)
            {
                absoluteTimestamp = lastTs;
            }
            if (lastTs > absoluteTimestamp)
            {
                WARN("Back time on {0} ATS:{1} LTS:{2} D:{3}", Name, absoluteTimestamp, lastTs, lastTs - absoluteTimestamp);
                return(true);
            }
            if (isAudio)
            {
                _audioLastTs = absoluteTimestamp;
            }
            else
            {
                _videoLastTs = absoluteTimestamp;
            }
            if (!_avCodecsSent)
            {
                foreach (var temp in OutStreams.Where(x => !x.IsEnqueueForDelete()))
                {
                    SignalOutStreamAttached(temp);
                }

                if (!_avCodecsSent)
                {
                    return(true);
                }
            }
            if (_hasAudio && _hasVideo && ((_audioLastTs == 0) || (_videoLastTs == 0)))
            {
                return(true);
            }

            return(base.FeedData(pData, dataLength, processedLength, totalLength, absoluteTimestamp, isAudio));
        }
Exemplo n.º 13
0
 public override void GetStats(Variant info, uint namespaceId)
 {
     base.GetStats(info, namespaceId);
     info["outStreamsUniqueIds"] = Variant.Get(OutStreams.Select(x => Variant.Get((((ulong)namespaceId) << 32) | x.UniqueId)).ToList());
     info.Add("bandwidth", Capabilities?.BandwidthHint ?? 0);
 }
Exemplo n.º 14
0
        protected virtual bool Feed()
        {
            //2. First, send audio and video codecs
            if (!_audioVideoCodecsSent && !SendCodecs())
            {
                Logger.FATAL("Unable to send audio codec");
                return(false);
            }
            while (!Paused && OutStreams.Count != 0)
            {
                //2. Determine if the client has enough data on the buffer and continue
                //or stay put
                var elapsedTime = (int)(DateTime.Now - _startFeedingTime).TotalSeconds;
                if ((int)_totalSentTime - elapsedTime >= _clientSideBufferLength)
                {
                    return(true);
                }

                //3. Test to see if we have sent the last frame
                if (_currentFrameIndex >= _totalFrames || _playLimit >= 0 && _playLimit < _totalSentTime)
                {
                    this.Log().Info("Done streaming file");
                    OutStreams.Last().SignalStreamCompleted();
                    Paused = true;
                    return(true);
                }

                //4. Read the current frame from the seeking file
                if (!_pSeekFile.SeekTo(_framesBaseOffset + _currentFrameIndex * MediaFrame.MediaFrameSize))
                {
                    Logger.FATAL("Unablt to seek inside seek file");
                    return(false);
                }
                if (!MediaFrame.ReadFromMediaFile(_pSeekFile, out _currentFrame))
                {
                    Logger.FATAL("Unable to read frame from seeking file");
                    return(false);
                }
                Stream buffer = null;
                //Debug.WriteLine("{2},{0}:{1}", _currentFrame.AbsoluteTime, _currentFrame.Type, _currentFrameIndex);
                switch (_currentFrame.Type)
                {
                case MediaFrameType.Data:
                    _currentFrameIndex++;
                    if (!FeedMetaData(_pFile, _currentFrame))
                    {
                        Logger.FATAL("Unable to feed metadata");
                        return(false);
                    }
                    break;

                case MediaFrameType.Audio:
                    buffer = _audioBuffer;
                    goto case MediaFrameType.Video;

                case MediaFrameType.Video:
                    if (buffer == null)
                    {
                        buffer = _videoBuffer;
                    }
                    //7. Build the frame
                    if (!BuildFrame(_pFile, _currentFrame, buffer))
                    {
                        Logger.FATAL("Unable to build the frame");
                        return(false);
                    }

                    //8. Compute the timestamp
                    _totalSentTime = _currentFrame.AbsoluteTime / 1000 - _totalSentTimeBase;
                    //9. Do the feedeng
                    FeedData(buffer, (uint)buffer.Length, 0, (uint)buffer.Length, _currentFrame.AbsoluteTime, _currentFrame.Type == MediaFrameType.Audio);
                    //10. Discard the data
                    buffer.IgnoreAll();
                    //11. Increment the frame index
                    _currentFrameIndex++;
                    //12. Done. We either feed again if frame length was 0
                    //or just return true
                    //return _currentFrame.Length != 0 || Feed();
                    break;

                default:
                    if (!FeedOtherType())
                    {
                        return(false);
                    }
                    break;
                }
            }
            return(true);
        }