示例#1
0
        /// <inheritdoc />
        /// <summary>
        ///   Encodes a video frame.
        /// </summary>
        /// <param name="data">Bitmap data.</param>
        /// <param name="time">Time in ticks.</param>
        /// <param name="stream">Output stream.</param>
        public void Encode(BitmapData data, long time, Stream stream)
        {
            // create sample
            Sample      sample = MediaFactory.CreateSample();
            MediaBuffer buffer;

            if (this.surface == null)
            {
                // create buffer
                MediaFactory.Create2DMediaBuffer(
                    data.Width,
                    data.Height,
                    new FourCC((int)Format.X8R8G8B8),
                    new RawBool(false),
                    out buffer);

                // calculate length
                buffer.CurrentLength = data.Stride * data.Height;

                // copy data
                Utilities.CopyMemory(buffer.Lock(out _, out _), data.Scan0, buffer.CurrentLength);

                // unlock bits
                buffer.Unlock();
            }
            else
            {
                // create buffer
                MediaFactory.CreateDXGISurfaceBuffer(typeof(Texture2D).GUID,
                                                     this.surface,
                                                     0,
                                                     new RawBool(false),
                                                     out buffer);

                // set buffer length
                buffer.CurrentLength = buffer.QueryInterface <Buffer2D>().ContiguousLength;
            }

            // add buffer to sample
            sample.AddBuffer(buffer);
            sample.SampleTime = time;

            try { this.sinkWriter.WriteSample(this.streamIdx, sample); } catch (SharpDXException) { } finally {
                buffer.Dispose();
                sample.Dispose();
            }
        }
        /// <inheritdoc />
        /// <summary>
        ///   Processes and encodes a frame into the destination stream
        /// </summary>
        /// <param name="frame">
        ///   A <see cref="VideoFrame" /> instance containing information about the locked frame bitmap or texture
        /// </param>
        public override void Feed(VideoFrame frame)
        {
            // create sample
            Sample      sample = MediaFactory.CreateSample();
            MediaBuffer buffer;

            switch (frame)
            {
            case D3D11VideoFrame d3D11Frame: // Direct3D 11 texture
                // create media buffer
                MediaFactory.CreateDXGISurfaceBuffer(typeof(Texture2D).GUID,
                                                     d3D11Frame.Texture,
                                                     0,
                                                     new RawBool(false),
                                                     out buffer);

                // set buffer length
                using (Buffer2D buffer2D = buffer.QueryInterface <Buffer2D>()) {
                    buffer.CurrentLength = buffer2D.ContiguousLength;
                }

                break;

            case BitmapVideoFrame bmpFrame: // WIC bitmap
                // create media buffer
                MediaFactory.CreateWICBitmapBuffer(typeof(Bitmap).GUID, bmpFrame.Bitmap, out buffer);

                // calculate buffer length
                buffer.CurrentLength = bmpFrame.BitmapLock.Stride * bmpFrame.Height;

                // copy pixels
                Utilities.CopyMemory(buffer.Lock(out _, out _), bmpFrame.BitmapLock.Data.DataPointer, buffer.CurrentLength);

                // unlock bits
                buffer.Unlock();

                break;

            case GdiBitmapVideoFrame gdiFrame: // GDI-compatible bitmap
                // create media buffer
                // create buffer for copying the bitmap data
                MediaFactory.Create2DMediaBuffer(frame.Width,
                                                 frame.Height,
                                                 new FourCC((int)Format.X8R8G8B8),
                                                 new RawBool(false), out buffer);

                // calculate buffer length
                buffer.CurrentLength = gdiFrame.BitmapData.Stride * frame.Height;

                // copy data
                Utilities.CopyMemory(buffer.Lock(out _, out _), gdiFrame.BitmapData.Scan0, buffer.CurrentLength);

                // unlock bits
                buffer.Unlock();
                break;

            default:
                throw new NotSupportedException("The supplied frame does not have a supported type");
            }

            // add buffer to sample
            sample.AddBuffer(buffer);

            // set up sample timing
            if (this.lastFrameTime != 0)
            {
                sample.SampleTime     = frame.PresentTime - this.firstFramePresentTime;
                sample.SampleDuration = frame.PresentTime - this.lastFrameTime;
            }
            else
            {
                // set first frame present time so that we can set the timestamp of subsequent frames relative to the
                // beggining of the video
                this.firstFramePresentTime = frame.PresentTime;
            }

            this.lastFrameTime = frame.PresentTime;

            try {
                this.sinkWriter.WriteSample(this.streamIdx, sample);
            } finally {
                buffer.Dispose();
                sample.Dispose();
            }
        }