static IntPtr AddStream(Stream stream, OpenMedia openMedia, ReadMedia readMedia, SeekMedia seekMedia, CloseMedia closeMedia) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } IntPtr handle; lock (DicStreams) { _streamIndex++; handle = new IntPtr(_streamIndex); DicStreams[handle] = new StreamData { Buffer = new byte[0x4000], Handle = handle, Stream = stream, OpenMedia = openMedia, ReadMedia = readMedia, SeekMedia = seekMedia, CloseMedia = closeMedia }; } return(handle); }
static IntPtr CtorFromCallbacks(LibVLC libVLC, Stream stream) { if (libVLC == null) { throw new ArgumentNullException(nameof(libVLC)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var openMedia = new OpenMedia(CallbackOpenMedia); var readMedia = new ReadMedia(CallbackReadMedia); var seekMedia = new SeekMedia(CallbackSeekMedia); var closeMedia = new CloseMedia(CallbackCloseMedia); var opaque = AddStream(stream, openMedia, readMedia, seekMedia, closeMedia); if (opaque == IntPtr.Zero) { throw new InvalidOperationException("Cannot create opaque parameter"); } return(Native.LibVLCMediaNewCallbacks(libVLC.NativeReference, Marshal.GetFunctionPointerForDelegate(openMedia), Marshal.GetFunctionPointerForDelegate(readMedia), Marshal.GetFunctionPointerForDelegate(seekMedia), Marshal.GetFunctionPointerForDelegate(closeMedia), opaque)); }
public StreamData(IntPtr handle, Stream stream, byte[] buffer, OpenMedia openMedia, ReadMedia readMedia, SeekMedia seekMedia, CloseMedia closeMedia) { Handle = handle; Stream = stream; Buffer = buffer; OpenMedia = openMedia; ReadMedia = readMedia; SeekMedia = seekMedia; CloseMedia = closeMedia; }
/// <summary>Load an mp4 media file; this runs on a background thread from the thread pool.</summary> void loadMediaImpl(string url, TaskCompletionSource <bool> completionSource) { try { // Deal with paths starting from "~/", transform that into user's home folder if (url.StartsWith("~/")) { string rel = url.Substring(2); string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); url = Path.Combine(home, rel); } // Parse the complete MP4, except the largest `mdat` box which has the actual payload of the video. file = OpenMedia.openMedia(File.OpenRead(url)); if (!shutdownHandle) { shutdownHandle = EventHandle.create(); } // Initialize the video if (null == file.videoTrack) { throw new ApplicationException("The file doesn’t have a video track"); } decoder?.Dispose(); decoder = new StatefulVideoDecoder(h264.device, shutdownHandle); int videoEncodedBuffers = encodedBuffersCount; int audioEncodedBuffers = this.audioEncodedBuffers; decoder.initialize(file.videoTrack, videoEncodedBuffers); decodedSize = file.videoTrack.decodedSize; decoder.captureSetup(file.videoTrack, decodedBuffersCount, decodedSize); // Initialize the audio audioPlayer?.Dispose(); audioPlayer = null; if (null != file.audioTrack) { try { audioPlayer = Audio.Player.create(file.audioTrack, audioEncodedBuffers, shutdownHandle); } catch (Exception ex) { // Logger.logError( ex.ToString() ); ex.logError("Error initializing audio"); } } else { Logger.logWarning("The file doesn’t have an audio track"); } // Initialize presentation clock source if (null != audioPlayer) { // Use audio player for the source of presentation time if (displayRefresh.HasValue) { presentationClock = new Clocks.AudioWithTimer(decoder, audioPlayer, displayRefresh.Value); } else { presentationClock = new Clocks.Audio(decoder, audioPlayer); } } else { // Use eClock.Monotonic OS clock for presentation time presentationClock = new Clocks.Video(decoder); } m_state = eState.Prepared; if (m_autoPlay) { play(); } completionSource.SetResult(true); } catch (Exception ex) { completionSource.SetException(ex); } }
public extern static void CallOpenMedia(OpenMedia callback);