/// <summary>
        /// Enqueue a new video frame encoded in I420 format.
        /// If the internal queue reached its maximum capacity, do nothing and drop the frame.
        /// </summary>
        /// <param name="frame">The video frame to enqueue</param>
        /// <returns>Return <c>true</c> if the frame was enqueued successfully, or <c>false</c> if it was dropped</returns>
        /// <remarks>This should only be used if the queue has storage for a compatible video frame encoding.</remarks>
        public bool Enqueue(I420AVideoFrame frame)
        {
            double curTime = _stopwatch.Elapsed.TotalMilliseconds;

            // Always update queued time, which refers to calling Enqueue(), even
            // if the queue is full and the frame is dropped.
            float queuedDt = (float)(curTime - _lastQueuedTimeMs);

            _lastQueuedTimeMs = curTime;

            // Try to get some storage for that new frame
            ulong byteSize = (ulong)(frame.strideY + frame.strideA) * frame.height + (ulong)(frame.strideU + frame.strideV) * frame.height / 2;
            T     storage  = GetStorageFor(byteSize);

            if (storage == null)
            {
                // Too many frames in queue, drop the current one
                float droppedDt = (float)(curTime - _lastDroppedTimeMs);
                _lastDroppedTimeMs = curTime;
                _droppedFrameTimeAverage.Push(1000f / droppedDt);
                return(false);
            }

            // Copy the new frame to its storage
            frame.CopyTo(storage.Buffer);
            storage.Width  = frame.width;
            storage.Height = frame.height;

            // Enqueue for later delivery
            _frameQueue.Enqueue(storage);
            _queuedFrameTimeAverage.Push(1000f / queuedDt);
            _droppedFrameTimeAverage.Push(0f);
            return(true);
        }
예제 #2
0
 internal void OnI420AFrameReady(I420AVideoFrame frame)
 {
     MainEventSource.Log.I420ALocalVideoFrameReady(frame.width, frame.height);
     lock (_videoFrameReadyLock)
     {
         _videoFrameReady?.Invoke(frame);
     }
 }
 internal void OnI420AFrameReady(I420AVideoFrame frame)
 {
     MainEventSource.Log.I420ARemoteVideoFrameReady(frame.width, frame.height);
     I420AVideoFrameReady?.Invoke(frame);
 }
 void VideoTrackSourceInterop.IVideoSource.OnI420AFrameReady(I420AVideoFrame frame)
 {
     MainEventSource.Log.I420ARemoteVideoFrameReady(frame.width, frame.height);
     _videoFrameReady?.Invoke(frame);
 }