Пример #1
0
        void IAviStreamWriteHandler.WriteStreamFormat(AviVideoStream videoStream)
        {
            // See BITMAPINFOHEADER structure
            fileWriter.Write(40U); // size of structure
            fileWriter.Write(videoStream.Width);
            fileWriter.Write(videoStream.Height);
            fileWriter.Write((short)1);                         // planes
            fileWriter.Write((ushort)videoStream.BitsPerPixel); // bits per pixel
            fileWriter.Write((uint)videoStream.Codec);          // compression (codec FOURCC)
            var sizeInBytes = videoStream.Width * videoStream.Height * (((int)videoStream.BitsPerPixel) / 8);

            fileWriter.Write((uint)sizeInBytes); // image size in bytes
            fileWriter.Write(0);                 // X pixels per meter
            fileWriter.Write(0);                 // Y pixels per meter

            // Writing grayscale palette for 8-bit uncompressed stream
            // Otherwise, no palette
            if (videoStream.BitsPerPixel == BitsPerPixel.Bpp8 && videoStream.Codec == KnownFourCCs.Codecs.Uncompressed)
            {
                fileWriter.Write(256U); // palette colors used
                fileWriter.Write(0U);   // palette colors important
                for (int i = 0; i < 256; i++)
                {
                    fileWriter.Write((byte)i);
                    fileWriter.Write((byte)i);
                    fileWriter.Write((byte)i);
                    fileWriter.Write((byte)0);
                }
            }
            else
            {
                fileWriter.Write(0U); // palette colors used
                fileWriter.Write(0U); // palette colors important
            }
        }
Пример #2
0
        /// <summary>Adds new video stream.</summary>
        /// <param name="width">Frame's width.</param>
        /// <param name="height">Frame's height.</param>
        /// <param name="bitsPerPixel">Bits per pixel.</param>
        /// <returns>Newly added video stream.</returns>
        /// <remarks>
        /// Stream is initialized to be ready for uncompressed video (bottom-up BGR) with specified parameters.
        /// However, properties (such as <see cref="IAviVideoStream.Codec"/>) can be changed later if the stream is
        /// to be fed with pre-compressed data.
        /// </remarks>
        public IAviVideoStream AddVideoStream(int width = 1, int height = 1, BitsPerPixel bitsPerPixel = BitsPerPixel.Bpp32)
        {
            Argument.IsPositive(width, nameof(width));
            Argument.IsPositive(height, nameof(height));
            Argument.IsEnumMember(bitsPerPixel, nameof(bitsPerPixel));

            return(AddStream <IAviVideoStreamInternal>(index =>
            {
                var stream = new AviVideoStream(index, this, width, height, bitsPerPixel);
                var asyncStream = new AsyncVideoStreamWrapper(stream);
                return asyncStream;
            }));
        }
Пример #3
0
        /// <summary>Adds new encoding video stream.</summary>
        /// <param name="encoder">Encoder to be used.</param>
        /// <param name="ownsEncoder">Whether encoder should be disposed with the writer.</param>
        /// <param name="width">Frame's width.</param>
        /// <param name="height">Frame's height.</param>
        /// <returns>Newly added video stream.</returns>
        /// <remarks>
        /// <para>
        /// Stream is initialized to be to be encoded with the specified encoder.
        /// Method <see cref="IAviVideoStream.WriteFrame"/> expects data in the same format as encoders,
        /// that is top-down BGR32 bitmap. It is passed to the encoder and the encoded result is written
        /// to the stream.
        /// Parameters <c>isKeyFrame</c> and <c>length</c> are ignored by encoding streams,
        /// as encoders determine on their own which frames are keys, and the size of input bitmaps is fixed.
        /// </para>
        /// <para>
        /// Properties <see cref="IAviVideoStream.Codec"/> and <see cref="IAviVideoStream.BitsPerPixel"/>
        /// are defined by the encoder, and cannot be modified.
        /// </para>
        /// </remarks>
        public IAviVideoStream AddEncodingVideoStream(IVideoEncoder encoder, bool ownsEncoder = true, int width = 1, int height = 1)
        {
            Contract.Requires(encoder != null);
            Contract.Requires(Streams.Count < 100);
            Contract.Ensures(Contract.Result <IAviVideoStream>() != null);

            return(AddStream <IAviVideoStreamInternal>(index =>
            {
                var stream = new AviVideoStream(index, this, width, height, BitsPerPixel.Bpp32);
                var encodingStream = new EncodingVideoStreamWrapper(stream, encoder, ownsEncoder);
                var asyncStream = new AsyncVideoStreamWrapper(encodingStream);
                return asyncStream;
            }));
        }
Пример #4
0
        /// <summary>Adds new encoding video stream.</summary>
        /// <param name="encoder">Encoder to be used.</param>
        /// <param name="ownsEncoder">Whether encoder should be disposed with the writer.</param>
        /// <param name="width">Frame's width.</param>
        /// <param name="height">Frame's height.</param>
        /// <returns>Newly added video stream.</returns>
        /// <remarks>
        /// <para>
        /// Stream is initialized to be to be encoded with the specified encoder.
        /// Method <see cref="IAviVideoStream.WriteFrame"/> expects data in the same format as encoders,
        /// that is top-down BGR32 bitmap. It is passed to the encoder and the encoded result is written
        /// to the stream.
        /// Parameters <c>isKeyFrame</c> and <c>length</c> are ignored by encoding streams,
        /// as encoders determine on their own which frames are keys, and the size of input bitmaps is fixed.
        /// </para>
        /// <para>
        /// Properties <see cref="IAviVideoStream.Codec"/> and <see cref="IAviVideoStream.BitsPerPixel"/>
        /// are defined by the encoder, and cannot be modified.
        /// </para>
        /// </remarks>
        public IAviVideoStream AddEncodingVideoStream(IVideoEncoder encoder, bool ownsEncoder = true, int width = 1, int height = 1)
        {
            Argument.IsNotNull(encoder, nameof(encoder));
            Argument.IsPositive(width, nameof(width));
            Argument.IsPositive(height, nameof(height));

            return(AddStream <IAviVideoStreamInternal>(index =>
            {
                var stream = new AviVideoStream(index, this, width, height, BitsPerPixel.Bpp32);
                var encodingStream = new EncodingVideoStreamWrapper(stream, encoder, ownsEncoder);
                var asyncStream = new AsyncVideoStreamWrapper(encodingStream);
                return asyncStream;
            }));
        }
Пример #5
0
        /// <summary>Adds new video stream.</summary>
        /// <param name="width">Frame's width.</param>
        /// <param name="height">Frame's height.</param>
        /// <param name="bitsPerPixel">Bits per pixel.</param>
        /// <returns>Newly added video stream.</returns>
        /// <remarks>
        /// Stream is initialized to be ready for uncompressed video (bottom-up BGR) with specified parameters.
        /// However, properties (such as <see cref="IAviVideoStream.Codec"/>) can be changed later if the stream is
        /// to be fed with pre-compressed data.
        /// </remarks>
        public IAviVideoStream AddVideoStream(int width = 1, int height = 1, BitsPerPixel bitsPerPixel = BitsPerPixel.Bpp32)
        {
            Contract.Requires(width > 0);
            Contract.Requires(height > 0);
            Contract.Requires(Enum.IsDefined(typeof(BitsPerPixel), bitsPerPixel));
            Contract.Requires(Streams.Count < 100);
            Contract.Ensures(Contract.Result <IAviVideoStream>() != null);

            return(AddStream <IAviVideoStreamInternal>(index =>
            {
                var stream = new AviVideoStream(index, this, width, height, bitsPerPixel);
                var asyncStream = new AsyncVideoStreamWrapper(stream);
                return asyncStream;
            }));
        }
Пример #6
0
        void IAviStreamWriteHandler.WriteStreamHeader(AviVideoStream videoStream)
        {
            // See AVISTREAMHEADER structure
            fileWriter.Write((uint)videoStream.StreamType);
            fileWriter.Write((uint)videoStream.Codec);
            fileWriter.Write(0U);                                                    // StreamHeaderFlags
            fileWriter.Write((ushort)0);                                             // priority
            fileWriter.Write((ushort)0);                                             // language
            fileWriter.Write(0U);                                                    // initial frames
            fileWriter.Write(frameRateDenominator);                                  // scale (frame rate denominator)
            fileWriter.Write(frameRateNumerator);                                    // rate (frame rate numerator)
            fileWriter.Write(0U);                                                    // start
            fileWriter.Write((uint)streamsInfo[videoStream.Index].FrameCount);       // length
            fileWriter.Write((uint)streamsInfo[videoStream.Index].MaxChunkDataSize); // suggested buffer size
            fileWriter.Write(0U);                                                    // quality
            fileWriter.Write(0U);                                                    // sample size
            fileWriter.Write((short)0);                                              // rectangle left
            fileWriter.Write((short)0);                                              // rectangle top
            short right  = (short)(videoStream != null ? videoStream.Width : 0);
            short bottom = (short)(videoStream != null ? videoStream.Height : 0);

            fileWriter.Write(right);  // rectangle right
            fileWriter.Write(bottom); // rectangle bottom
        }
Пример #7
0
 void IAviStreamWriteHandler.WriteVideoFrame(AviVideoStream stream, bool isKeyFrame, byte[] frameData, int startIndex, int count)
 {
     WriteStreamFrame(stream, isKeyFrame, frameData, startIndex, count);
 }
Пример #8
0
 void IAviStreamWriteHandler.WriteVideoFrame(AviVideoStream stream, bool isKeyFrame, ReadOnlySpan <byte> frameData)
 => WriteStreamFrame(stream, isKeyFrame, frameData);