public async void SeparateThreadToSaveVideoStream()
        {
            while (isRecording == true)
            {
                //thread is counting
                //sometimes stuck at thread at frame : 0, depending on the window chosen to record
                //meaning OnFrameArrived is not called
                if (parent != null)
                {
                    DateTime currentTimeLocal = DateTime.Now;
                    TimeSpan elpasedTimeLocal = currentTimeLocal - initialRecordTime;
                    string   debugstr         = "At frame: " + counter.ToString() + "  Threadcounter: " + threadcounter.ToString();
                    //debugstr += "  StreamSize: " + ((int)(videostream.Size / 1024.0)).ToString() + "KB  TimeElapsed: " + ((int)elpasedTimeLocal.TotalSeconds).ToString();
                    debugstr += "  StreamSize: " + ((int)(totalMemoryUsed / 1024.0)).ToString() + " KB";
                    debugstr += "  TimeElapsed: " + ((int)elpasedTimeLocal.TotalSeconds).ToString();
                    parent.msg(debugstr);
                }

                threadcounter++;
                if (threadcounter > 200000)
                {
                    threadcounter = 0;
                }


                if (currentFrame != null)
                {
                    CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromDirect3D11Surface(
                        canvasDevice,
                        currentFrame.Surface);

                    using (var inputstream = new InMemoryRandomAccessStream())
                    {
                        CancellationToken ct = new CancellationToken();
                        await canvasBitmap.SaveAsync(inputstream, CanvasBitmapFileFormat.Png, 1f).AsTask(ct);

                        ulong currentFrameLength = inputstream.Size;

                        _currentVideoStreamPos = 0;
                        totalMemoryUsed       += currentFrameLength;

                        DateTime currentTimeLocal = DateTime.Now;
                        TimeSpan diff             = currentTimeLocal - previousRecordTime;
                        previousRecordTime = currentTimeLocal;


                        UnpackItem unpackItem = new UnpackItem();
                        unpackItem.pos       = _currentVideoStreamPos;
                        unpackItem.length    = currentFrameLength;
                        unpackItem.frameTime = diff;


                        unpackItem.compressedBuffer = new Windows.Storage.Streams.Buffer((uint)inputstream.Size);
                        inputstream.Seek(0);
                        await inputstream.ReadAsync(unpackItem.compressedBuffer, (uint)inputstream.Size, InputStreamOptions.None); //read from stream to buffer

                        await inputstream.FlushAsync();


                        unpackList.Add(unpackItem);
                    }


                    currentFrame?.Dispose();
                    currentFrame = null; //need this line so this thread will continue loop when new frame is not yet ready
                }
                else
                {
                    Thread.Sleep(10);
                }
            }

            //await CloseVideoStream();

            int      len         = unpackList.Count;
            DateTime currentTime = DateTime.Now;
            TimeSpan elpasedTime = currentTime - initialRecordTime;
            string   debugstrx   = "Num frame: " + len.ToString() + "  Threadcounter: " + threadcounter.ToString();

            debugstrx += "  TimeElapsed: " + ((int)elpasedTime.TotalSeconds).ToString();

            if (elpasedTime.TotalSeconds > 0)
            {
                debugstrx += "  Frame Rate (fps) : " + (len / (double)elpasedTime.TotalSeconds).ToString();
            }

            if (parent != null)
            {
                parent.StartWritingReport(debugstrx);
            }

            //await UnpackVideoStream();
        }
        /// <summary>
        /// //Encoding a Win2D surface (CanvasRenderTarget) as a video frame
        /// </summary>
        private async void OnMSSSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args)
        {
            if (parent != null)
            {
                parent.StartWritingOutput("OnSampleRequested " + frameCounter.ToString(), 0);
            }


            if (unpackList == null)
            {
                if (parent != null)
                {
                    parent.StartWritingOutput("Unpack List Null Error!", 1);
                }

                //this will stop the encoding
                args.Request.Sample = null;
                return;
            }


            int len = unpackList.Count;

            if (frameCounter >= len)
            {
                if (parent != null)
                {
                    parent.StartWritingOutput("Encoding Completed.", 1);
                }

                //this will stop the encoding
                args.Request.Sample = null;
                return;
            }

            if ((frameCounter < 0) || (0 == len))
            {
                if (parent != null)
                {
                    parent.StartWritingOutput("Invalid Frame", 1);
                }

                //this will stop the encoding
                args.Request.Sample = null;
                return;
            }


            //need deferral because CanvasBitmap.LoadAsync takes some time to complete ?
            var deferral = args.Request.GetDeferral();

            ///
            UnpackItem unpackItem = unpackList[frameCounter];

            Windows.Storage.Streams.Buffer buffer = unpackItem.compressedBuffer;

            InMemoryRandomAccessStream inMemoryRandomAccessStream = null;

            using (inMemoryRandomAccessStream = new InMemoryRandomAccessStream())
            {
                await inMemoryRandomAccessStream.WriteAsync(buffer);

                await inMemoryRandomAccessStream.FlushAsync();

                inMemoryRandomAccessStream.Seek(0);


                CanvasBitmap tempBitmap = null;
                try
                {
                    tempBitmap = await CanvasBitmap.LoadAsync(CanvasDevice.GetSharedDevice(), inMemoryRandomAccessStream);
                }
                catch (Exception e)
                {
                    if (parent != null)
                    {
                        parent.StartWritingOutput("CBM Error : " + e.Message, 1);
                    }
                }


                if (tempBitmap != null)
                {
                    CanvasRenderTarget canvasRenderTarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), tempBitmap.SizeInPixels.Width, tempBitmap.SizeInPixels.Height, tempBitmap.Dpi);
                    using (CanvasDrawingSession session = canvasRenderTarget.CreateDrawingSession())
                    {
                        session.Clear(Colors.Black);
                        //session.DrawEllipse(new System.Numerics.Vector2(120 + frameCounter * 2, 100), 30, 20, Colors.White);
                        session.DrawImage(tempBitmap);
                    }

                    TimeSpan timeLapsed = unpackItem.frameTime;
                    Timestamp += timeLapsed;

                    //set sample after defferal ? nope ....stop at 1st frame...
                    MediaStreamSample sample = MediaStreamSample.CreateFromDirect3D11Surface(canvasRenderTarget, Timestamp);
                    args.Request.Sample = sample;

                    deferral.Complete();
                }
                else
                {
                    args.Request.Sample = null;
                    deferral.Complete();
                }

                frameCounter++;
            }
        }
Пример #3
0
        public async Task UnpackToMp4()
        {
            MediaComposition mediacomposition = new MediaComposition();

            StorageFolder pictureFolder = KnownFolders.SavedPictures;

            {
                int len = simpleRecorder.unpackList.Count;
                for (int i = 0; i < len; i++)
                {
                    UnpackItem unpackItem = simpleRecorder.unpackList[i];
                    Windows.Storage.Streams.Buffer buffer = unpackItem.compressedBuffer;

                    InMemoryRandomAccessStream inMemoryRandomAccessStream = null;
                    using (inMemoryRandomAccessStream = new InMemoryRandomAccessStream())
                    {
                        await inMemoryRandomAccessStream.WriteAsync(buffer);

                        await inMemoryRandomAccessStream.FlushAsync();

                        inMemoryRandomAccessStream.Seek(0);
                        CanvasBitmap tempBitmap = await CanvasBitmap.LoadAsync(CanvasDevice.GetSharedDevice(), inMemoryRandomAccessStream);

                        if (tempBitmap != null)
                        {
                            CanvasRenderTarget canvasRenderTarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), tempBitmap.SizeInPixels.Width, tempBitmap.SizeInPixels.Height, 96);
                            using (CanvasDrawingSession session = canvasRenderTarget.CreateDrawingSession())
                            {
                                session.Clear(Colors.Black);
                                session.DrawImage(tempBitmap);

                                TimeSpan frameTime30Mil = TimeSpan.FromMilliseconds(30f);
                                TimeSpan frameTime      = unpackItem.frameTime;
                                //if (frameTime < frameTime30Mil)
                                //    frameTime = frameTime30Mil;

                                MediaClip mediaclip = MediaClip.CreateFromSurface(canvasRenderTarget, frameTime);
                                mediacomposition.Clips.Add(mediaclip);
                            }

                            string str = "Adding Clips " + (i + 1).ToString() + " / " + len.ToString();
                            if (i == len - 1)
                            {
                                str += "  ...  Please wait for file rendering  ...";
                            }
                            TextOutput.Text = str;
                        }
                    }

                    //free up memory recources as each frame is unpacked
                    if (unpackItem.compressedBuffer != null)
                    {
                        unpackItem.compressedBuffer = null;
                    }
                } //for
            }

            StorageFile mp4file = null;

            if (simpleRecorder.savefile != null)
            {
                mp4file = simpleRecorder.savefile;
            }
            else
            {
                string mp4filename = "SavedVideo" + ".mp4";
                mp4file = await pictureFolder.CreateFileAsync(
                    mp4filename,
                    CreationCollisionOption.ReplaceExisting);
            }

            //await mediacomposition.RenderToFileAsync(mp4file, MediaTrimmingPreference.Precise, MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p));
            var rendering = mediacomposition.RenderToFileAsync(mp4file, MediaTrimmingPreference.Precise, MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p));

            rendering.Progress  += ProgressReport;
            rendering.Completed += CompletedReport;
        }