示例#1
0
 /// <summary>
 /// Encodes a frame.
 /// </summary>
 /// <seealso cref="IVideoEncoder.EncodeFrame"/>
 public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
 {
     BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);
     BitmapUtils.Bgr32ToBgr24(sourceBuffer, 0, destination, destOffset, width * height);
     isKeyFrame = true;
     return(MaxEncodedSize);
 }
示例#2
0
        /// <summary>Encodes a frame.</summary>
        public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
        {
            Argument.IsNotNull(source, nameof(source));
            Argument.IsNotNegative(srcOffset, nameof(srcOffset));
            Argument.ConditionIsMet(srcOffset + 4 * width * height <= source.Length,
                                    "Source end offset exceeds the source length.");
            Argument.IsNotNull(destination, nameof(destination));
            Argument.IsNotNegative(destOffset, nameof(destOffset));

#if NET5_0_OR_GREATER
            return(EncodeFrame(source.AsSpan(srcOffset), destination.AsSpan(destOffset), out isKeyFrame));
#else
            BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);

            var sourceHandle  = GCHandle.Alloc(sourceBuffer, GCHandleType.Pinned);
            var encodedHandle = GCHandle.Alloc(destination, GCHandleType.Pinned);
            try
            {
                var sourcePtr  = sourceHandle.AddrOfPinnedObject();
                var encodedPtr = encodedHandle.AddrOfPinnedObject();

                return(EncodeFrame(sourcePtr, encodedPtr, (uint)(destination.Length - destOffset), out isKeyFrame));
            }
            finally
            {
                sourceHandle.Free();
                encodedHandle.Free();
            }
#endif
        }
示例#3
0
 /// <summary>
 /// Encodes a frame.
 /// </summary>
 /// <seealso cref="IVideoEncoder.EncodeFrame"/>
 public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
 {
     BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);
     for (var i = 0; i < height; i++)
     {
         BitmapUtils.Bgr32ToBgr24(sourceBuffer, i * width * 4, destination, destOffset + i * stride, width);
     }
     isKeyFrame = true;
     return(MaxEncodedSize);
 }
示例#4
0
        /// <summary>Encodes a frame.</summary>
        public unsafe int EncodeFrame(ReadOnlySpan <byte> source, Span <byte> destination, out bool isKeyFrame)
        {
            Argument.ConditionIsMet(4 * width * height <= source.Length,
                                    "Source end offset exceeds the source length.");

            BitmapUtils.FlipVertical(source, sourceBuffer, height, width * 4);
            fixed(void *srcPtr = sourceBuffer, destPtr = destination)
            {
                var srcIntPtr  = new IntPtr(srcPtr);
                var destIntPtr = new IntPtr(destPtr);

                return(EncodeFrame(srcIntPtr, destIntPtr, (uint)destination.Length, out isKeyFrame));
            }
        }
示例#5
0
        /// <summary>Encodes a frame.</summary>
        /// <seealso cref="IVideoEncoder.EncodeFrame"/>
        public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
        {
            // TODO: Introduce Width and Height in IVideoRecorder and add Requires to EncodeFrame contract
            Contract.Assert(srcOffset + 4 * width * height <= source.Length);

            BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);

            var sourceHandle  = GCHandle.Alloc(sourceBuffer, GCHandleType.Pinned);
            var encodedHandle = GCHandle.Alloc(destination, GCHandleType.Pinned);

            try
            {
                var outInfo = outBitmapInfo;
                outInfo.ImageSize = (uint)destination.Length;
                var inInfo = inBitmapInfo;
                int outFlags;
                int chunkID;
                var flags = framesFromLastKey >= keyFrameRate ? VfwApi.ICCOMPRESS_KEYFRAME : 0;

                var result = VfwApi.ICCompress(compressorHandle, flags,
                                               ref outInfo, encodedHandle.AddrOfPinnedObject(), ref inInfo, sourceHandle.AddrOfPinnedObject(),
                                               out chunkID, out outFlags, frameIndex,
                                               0, quality, IntPtr.Zero, IntPtr.Zero);
                CheckICResult(result);
                frameIndex++;


                isKeyFrame = (outFlags & VfwApi.AVIIF_KEYFRAME) == VfwApi.AVIIF_KEYFRAME;
                if (isKeyFrame)
                {
                    framesFromLastKey = 1;
                }
                else
                {
                    framesFromLastKey++;
                }

                return((int)outInfo.ImageSize);
            }
            finally
            {
                sourceHandle.Free();
                encodedHandle.Free();
            }
        }
 /// <summary>
 /// Encodes a frame.
 /// </summary>
 /// <seealso cref="IVideoEncoder.EncodeFrame"/>
 public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
 {
     BitmapUtils.FlipVertical(source, srcOffset, destination, destOffset, _height, _width * _bytesPerPixel);
     isKeyFrame = true;
     return(MaxEncodedSize);
 }