public MainPage() { this.InitializeComponent(); var videoProperties = VideoEncodingProperties.CreateH264();//.CreateUncompressed(MediaEncodingSubtypes.H264, 720, 480); var vd = VideoEncodingProperties.CreateUncompressed(MediaEncodingSubtypes.H264, 720, 480); videoDesc = new VideoStreamDescriptor(videoProperties); videoDesc.EncodingProperties.FrameRate.Numerator = 29970; videoDesc.EncodingProperties.FrameRate.Denominator = 1000; videoDesc.EncodingProperties.Width = 720; videoDesc.EncodingProperties.Height = 480; mss = new MediaStreamSource(videoDesc); mss.CanSeek = false; //mss.BufferTime = new TimeSpan(0, 0, 0, 0, 250); mss.Starting += mss_Starting; mss.SampleRequested += Mss_SampleRequested; mss.SampleRendered += Mss_SampleRendered; //initialize some buffers buff = new Windows.Storage.Streams.Buffer(1024 * 4); bStream = buff.AsStream(); //this seems needed for start-up threadSync = new System.Threading.AutoResetEvent(false); //get the frame time in ms double ms = 1000.0 * videoDesc.EncodingProperties.FrameRate.Denominator / videoDesc.EncodingProperties.FrameRate.Numerator; //get the frame time in ticks T0 = System.TimeSpan.FromTicks((long)(ms * System.TimeSpan.TicksPerMillisecond)); //our demuxer extractor = new MpegTS.BufferExtractor(); running = true; //give the file IO a head start Task.Run(() => RunreadFromFile()); }
private void Mss_SampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args) { if (!(args.Request.StreamDescriptor is VideoStreamDescriptor)) { return; } Debug.WriteLine("requesting sample"); MediaStreamSourceSampleRequest request = args.Request; MpegTS.VideoSample rawSample = null; MediaStreamSourceSampleRequestDeferral deferal = request.GetDeferral(); try { //block here for signal from mpegTS parser that a sample is ready //if (extractor.SampleCount == 0) // threadSync.WaitOne(); //dequeue the raw sample here if (!foundKeyFrame) { do { threadSync.WaitOne(); rawSample = extractor.DequeueNextSample(false); }while (rawSample == null || extractor.SampleCount == 0); } else { if (extractor.SampleCount > 0) { rawSample = extractor.DequeueNextSample(false); } if (rawSample == null) { request.Sample = emptySample; deferal.Complete(); return; } } //if (!gotT0) //{ // gotT0 = true; // //T0.TotalMilliseconds = 33.3667; //} //check max size of current buffer, increase if needed. if (buff.Capacity < rawSample.Length) { buff = new Windows.Storage.Streams.Buffer((uint)rawSample.Length); bStream.Dispose(); //bStream = sample.Buffer.AsStream(); bStream = buff.AsStream(); } //create our sample here may need to keep initial time stamp for relative time? sample = MediaStreamSample.CreateFromBuffer(buff, new TimeSpan(T0.Ticks * frameCount)); bStream.Position = 0; //write the raw sample to the reqest sample stream; rawSample.WriteToStream(bStream); sample.Buffer.Length = (uint)rawSample.Length; Debug.WriteLine("sample length: {0}", rawSample.Length); //sample.DecodeTimestamp = new TimeSpan(T0.Ticks * frameCount); sample.Duration = T0; sample.KeyFrame = ScanForKeyframe(bStream);//rawSample.Length > 3000;// //not sure if this is correct... sample.Discontinuous = !lastFrame; //this just tells us if the MpegTS Continuity Counter //for all Mpeg packets in the sample were in order. (0-15) lastFrame = rawSample.IsComplete; //if (!foundKeyFrame) // sample = emptySample; //else ++frameCount; // create the MediaStreamSample and assign to the request object. // You could also create the MediaStreamSample using createFromBuffer(...) //MediaStreamSample sample = await MediaStreamSample.CreateFromStreamAsync(inputStream, sampleSize, timeOffset); //sample.Duration = sampleDuration; //sample.KeyFrame = true; // increment the time and byte offset //byteOffset += sampleSize; //timeOffset = timeOffset.Add(sampleDuration); request.Sample = sample; } catch (Exception ex) { var exStr = ex.ToString(); } finally { deferal.Complete(); } Debug.WriteLine("exit request sample"); }