/// <summary> /// Gets the next video frame from the MediaStream track. /// If internal processing is slower than the incoming frame rate, new frames /// will be dropped from the incoming stream. Once the input buffer is full, /// frames will be dropped until <code>RecycleFrame()</code> is called to free /// a spot for another frame to be buffered. /// If there are no frames in the input buffer, /// <code>OkCompletionPending</code> will be returned immediately and the /// <code>HandleFrame</code> event handler will be called when a new frame is received or some /// error happens. /// </summary> /// <returns>Error code</returns> public PPError GetFrame() { var action = new Action <PPError, PPResource>((result, resource) => { OnGetFrame(new VideoFrameInfo(result, resource)); }); var callback = new CompletionCallbackWithOutput <PPResource>(new CompletionCallbackWithOutputFunc <PPResource>(action)); return((PPError)PPBMediaStreamVideoTrack.GetFrame(this, out callback.OutputAdapter.output, callback)); }
private async Task <VideoFrameInfo> GetFrameAsyncCore(MessageLoop messageLoop = null) { var tcs = new TaskCompletionSource <VideoFrameInfo>(); EventHandler <VideoFrameInfo> handler = (s, e) => { tcs.TrySetResult(e); }; try { HandleFrame += handler; if (MessageLoop == null && messageLoop == null) { GetFrame(); } else { Action <PPError> action = new Action <PPError>((e) => { var output = new APIArgumentAdapter <PPResource>(); var result = (PPError)PPBMediaStreamVideoTrack.GetFrame(this, out output.output, new BlockUntilComplete()); tcs.TrySetResult(new VideoFrameInfo(result, output.Output)); } ); InvokeHelper(action, messageLoop); } return(await tcs.Task); } catch (Exception exc) { Console.WriteLine(exc.Message); tcs.SetException(exc); return(new VideoFrameInfo(PPError.Aborted, PPResource.Empty)); } finally { HandleFrame -= handler; } }