/// <summary> // Gets a free frame for output. The frame is allocated by // <code>Configure()</code>. The caller should fill it with frame data, and // then use |PutFrame()| to send the frame back. /// </summary> /// <returns>Error code</returns> public PPError GetEmptyFrame() { var action = new Action <PPError, PPResource>((result, resource) => { OnGetEmptyFrame(new VideoFrameInfo(result, resource)); }); var callback = new CompletionCallbackWithOutput <PPResource>(new CompletionCallbackWithOutputFunc <PPResource>(action)); return((PPError)PPBMediaStreamVideoTrack.GetEmptyFrame(this, out callback.OutputAdapter.output, callback)); }
private async Task <PPError> ConfigureAsyncCore(MediaStreamVideoTrackAttributes attributes, MessageLoop messageLoop = null) { var tcs = new TaskCompletionSource <PPError>(); EventHandler <PPError> handler = (s, e) => { tcs.TrySetResult(e); }; try { HandleConfigure += handler; if (MessageLoop == null && messageLoop == null) { Configure(attributes); } else { Action <PPError> action = new Action <PPError>((e) => { var result = (PPError)PPBMediaStreamVideoTrack.Configure(this, attributes.ToAttributes(), new BlockUntilComplete() ); tcs.TrySetResult(result); } ); InvokeHelper(action, messageLoop); } return(await tcs.Task); } catch (Exception exc) { Console.WriteLine(exc.Message); tcs.SetException(exc); return(PPError.Aborted); } finally { HandleConfigure -= handler; } }
private async Task <VideoFrameInfo> GetEmptyFrameAsyncCore(MessageLoop messageLoop = null) { var tcs = new TaskCompletionSource <VideoFrameInfo>(); EventHandler <VideoFrameInfo> handler = (s, e) => { tcs.TrySetResult(e); }; try { HandleEmptyFrame += handler; if (MessageLoop == null && messageLoop == null) { GetFrame(); } else { Action <PPError> action = new Action <PPError>((e) => { var output = new APIArgumentAdapter <PPResource>(); var result = (PPError)PPBMediaStreamVideoTrack.GetEmptyFrame(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 { HandleEmptyFrame -= handler; } }
private async Task <PPError> CloseAsyncCore(MessageLoop messageLoop = null) { var tcs = new TaskCompletionSource <PPError>(); EventHandler <PPError> handler = (s, e) => { tcs.TrySetResult(e); }; try { HandleClose += handler; if (MessageLoop == null && messageLoop == null) { Close(); } else { Action <PPError> action = new Action <PPError>((e) => { PPBMediaStreamVideoTrack.Close(this); tcs.TrySetResult(PPError.Ok); } ); InvokeHelper(action, messageLoop); } return(await tcs.Task); } catch (Exception exc) { Console.WriteLine(exc.Message); tcs.SetException(exc); return(PPError.Aborted); } finally { HandleClose -= handler; } }
/// <summary> /// Configures underlying buffer buffers for incoming audio samples. /// If the application doesn't want to drop samples, then the /// <code>Buffers</code> should be /// chosen such that inter-buffer processing time variability won't overrun /// all input buffers. If all buffers are filled, then samples will be /// dropped. The application can detect this by examining the timestamp on /// returned buffers. If <code>Configure()</code> is not called, default /// settings will be used. Calls to Configure while the plugin holds /// buffers will fail. /// Example usage from plugin code: /// <code> /// var attribs = new MediaStreamAudioTrackAttributes() { /// Buffers = 4, /// Duration, 10 /// }; /// track.Configure(attribs); /// </code> /// </summary> /// <param name="attributes">A MediaStreamAudioTrackAttributes instance</param> /// <returns>Error code</returns> public PPError Configure(MediaStreamAudioTrackAttributes attributes) => (PPError)PPBMediaStreamVideoTrack.Configure(this, attributes.ToAttributes(), new CompletionCallback(OnConfigure));
/// <summary> /// Sends a frame returned by |GetEmptyFrame()| to the output track. /// After this function, the |frame| should not be used anymore and the /// caller should release the reference that it holds. /// </summary> /// <param name="frame"></param> /// <returns>Error code</returns> public PPError PutFrame(VideoFrame frame) => (PPError)PPBMediaStreamVideoTrack.PutFrame(this, frame);
public MediaStreamVideoTrack(Instance instance) { handle = PPBMediaStreamVideoTrack.Create(instance); }
/// <summary> /// Closes the MediaStream video track, and disconnects it from video source. /// After calling <code>Close()</code>, no new frames will be received. /// </summary> public void Close() { PPBMediaStreamVideoTrack.Close(this); OnClose(PPError.Ok); }
/// <summary> /// Recycles a frame returned by <code>GetFrame()</code>, so the track can /// reuse the underlying buffer of this frame. And the frame will become /// invalid. The caller should release all references it holds to /// <code>frame</code> and not use it anymore. /// </summary> /// <param name="frame">A VideoFrame returned by <code>GetFrame()</code>.</param> /// <returns>Error code</returns> public PPError RecycleFrame(VideoFrame frame) => (PPError)PPBMediaStreamVideoTrack.RecycleFrame(this, frame);