/// <summary> /// Starts the presentation clock. /// </summary> /// <param name="presentationClock">A valid IMFPresentationClock instance.</param> /// <param name="clockStartOffset">The initial starting time</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> /// <remarks>Use TimeSpan.MaxValue in the <paramref name="clockStartOffset"/> parameter to start the clock from its current position. Use this value if the clock is paused and you want to restart it from the same position.</remarks> public static HResult Start(this IMFPresentationClock presentationClock, TimeSpan clockStartOffset) { if (presentationClock == null) { throw new ArgumentNullException("presentationClock"); } return(presentationClock.Start(clockStartOffset.Ticks)); }
public SimpleFastEncode() { // Create objects and bind the background worker events this.EncodeProgress = null; this.presentationClock = null; this.mediaSession = null; this.mediaSource = null; this.progressTimer = new Timer(500); this.progressTimer.Elapsed += this.ProgressTimer_Tick; }
////////////////////////////////////////////////////////////////////////// // Name: CPlayer::Initialize // Description: // Intializes Media Foundation // Creates a media session // Creates a sequencer source // Creates a presentation clock // Creates an audio renderer // Starts the event queue // ///////////////////////////////////////////////////////////////////////// public HResult Initialize() { Debug.WriteLine("\nCPlayer::Initialize"); HResult hr = 0; try { IMFClock pClock; // Initialize Media Foundation. hr = MFExtern.MFStartup(0x10070, MFStartup.Full); MFError.ThrowExceptionForHR(hr); // Create the media session. hr = MFExtern.MFCreateMediaSession(null, out m_pMediaSession); MFError.ThrowExceptionForHR(hr); // Start the event queue. hr = m_pMediaSession.BeginGetEvent(this, null); MFError.ThrowExceptionForHR(hr); // Create a sequencer Source. hr = MFExtern.MFCreateSequencerSource(null, out m_pSequencerSource); MFError.ThrowExceptionForHR(hr); //setup clock hr = m_pMediaSession.GetClock(out pClock); MFError.ThrowExceptionForHR(hr); m_pPresentationClock = (IMFPresentationClock)pClock; // Create an IMFActivate object for the audio renderer. hr = MFExtern.MFCreateAudioRendererActivate(out m_pAudioRendererActivate); MFError.ThrowExceptionForHR(hr); //Set the player state to Initialized m_State = PlayerState.Initialized; // Notify the app that the player is initialized. PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)PlayerEvent.Initialized), new IntPtr((int)m_State)); } catch (Exception e) { hr = (HResult)Marshal.GetHRForException(e); } //Clean up. return(hr); }
// ----- Public Methods ----------------------------------------------- ////////////////////////////////////////////////////////////////////////// // Name: CPlayer // Description: Constructor // ///////////////////////////////////////////////////////////////////////// public CPlayer(IntPtr hWnd) { m_hWnd = hWnd; m_pMediaSession = null; m_pSequencerSource = null; m_pAudioRendererActivate = null; m_pPresentationClock = null; m_PresentationTimeOffset = 0; m_phnsTimePairStart = null; m_phnsTimePairEnd = null; m_State = PlayerState.PlayerCreated; m_ActiveSegment = -1; m_hCloseEvent = new AutoResetEvent(false); }
/// <summary> /// Gets the latest clock time. /// </summary> /// <param name="presentationClock">A valid IMFPresentationClock instance.</param> /// <param name="clockTime">Receives the latest clock time.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult GetTime(this IMFPresentationClock presentationClock, out TimeSpan clockTime) { if (presentationClock == null) { throw new ArgumentNullException("presentationClock"); } long tmp; HResult hr = presentationClock.GetTime(out tmp); clockTime = hr.Succeeded() ? TimeSpan.FromTicks(tmp) : default(TimeSpan); return(hr); }
public HResult GetPresentationClock(out IMFPresentationClock ppPresentationClock) { Debug.WriteLine("MediaSink:GetPResentationClock"); ppPresentationClock = null; lock (this) { if (PresentationClock == null) { return(MF_E_NO_CLOCK); } else { ppPresentationClock = PresentationClock; } } return(S_OK); }
public HResult SetPresentationClock(IMFPresentationClock pPresentationClock) { Debug.WriteLine("MediaSink:SetPresentationClock"); HResult hr = S_OK; lock (this) { if (IsShutdown) { return(MF_E_SHUTDOWN); } if (PresentationClock != null) { hr = PresentationClock.RemoveClockStateSink(this); if (Failed(hr)) { return(hr); } } if (pPresentationClock != null) { hr = pPresentationClock.AddClockStateSink(this); if (Failed(hr)) { return(hr); } } if (pPresentationClock != null) { PresentationClock = pPresentationClock; } } return(hr); }
//------------------------------------------------------------------- // Name: Shutdown // Description: Releases resources held by the media sink. //------------------------------------------------------------------- public int Shutdown() { // Make sure we *never* leave this entry point with an exception try { TRACE("CWavSink::Shutdown"); GC.SuppressFinalize(this); lock (this) { try { CheckShutdown(); m_pStream.Shutdown(); } finally { m_IsShutdown = true; SafeRelease(m_pClock); m_pClock = null; if (m_pStream != null) { m_pStream.Dispose(); m_pStream = null; } } } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
//------------------------------------------------------------------- // Name: SetPresentationClock // Description: Sets the presentation clock. // // pPresentationClock: Pointer to the clock. Can be null. //------------------------------------------------------------------- public int SetPresentationClock(IMFPresentationClock pPresentationClock) { // Make sure we *never* leave this entry point with an exception try { int hr; TRACE("CWavSink::SetPresentationClock"); lock (this) { CheckShutdown(); // If we already have a clock, remove ourselves from that clock's // state notifications. if (m_pClock != pPresentationClock) { if (m_pClock != null) { hr = m_pClock.RemoveClockStateSink(this); MFError.ThrowExceptionForHR(hr); } // Register ourselves to get state notifications from the new clock. if (pPresentationClock != null) { hr = pPresentationClock.AddClockStateSink(this); MFError.ThrowExceptionForHR(hr); } // Release the pointer to the old clock. // Store the pointer to the new clock. //SAFE_RELEASE(m_pClock); m_pClock = pPresentationClock; } } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
//------------------------------------------------------------------- // Name: GetPresentationClock // Description: Returns a pointer to the presentation clock. //------------------------------------------------------------------- public int GetPresentationClock(out IMFPresentationClock ppPresentationClock) { // Make sure we *never* leave this entry point with an exception try { TRACE("CWavSink::GetPresentationClock"); lock (this) { CheckShutdown(); if (m_pClock == null) { throw new COMException("There is no presentation clock.", MFError.MF_E_NO_CLOCK); } else { // Return the pointer to the caller. ppPresentationClock = m_pClock; } } return S_Ok; } catch (Exception e) { ppPresentationClock = null; return Marshal.GetHRForException(e); } }
////////////////////////////////////////////////////////////////////////// // Name: CPlayer::Initialize // Description: // Intializes Media Foundation // Creates a media session // Creates a sequencer source // Creates a presentation clock // Creates an audio renderer // Starts the event queue // ///////////////////////////////////////////////////////////////////////// public int Initialize() { Debug.WriteLine("\nCPlayer::Initialize"); int hr = 0; try { IMFClock pClock; // Initialize Media Foundation. hr = MFExtern.MFStartup(0x10070, MFStartup.Full); MFError.ThrowExceptionForHR(hr); // Create the media session. hr = MFExtern.MFCreateMediaSession(null, out m_pMediaSession); MFError.ThrowExceptionForHR(hr); // Start the event queue. hr = m_pMediaSession.BeginGetEvent(this, null); MFError.ThrowExceptionForHR(hr); // Create a sequencer Source. hr = MFExtern.MFCreateSequencerSource(null, out m_pSequencerSource); MFError.ThrowExceptionForHR(hr); //setup clock hr = m_pMediaSession.GetClock(out pClock); MFError.ThrowExceptionForHR(hr); m_pPresentationClock = (IMFPresentationClock)pClock; // Create an IMFActivate object for the audio renderer. hr = MFExtern.MFCreateAudioRendererActivate(out m_pAudioRendererActivate); MFError.ThrowExceptionForHR(hr); //Set the player state to Initialized m_State = PlayerState.Initialized; // Notify the app that the player is initialized. PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)PlayerEvent.Initialized), new IntPtr((int)m_State)); } catch (Exception e) { hr = Marshal.GetHRForException(e); } //Clean up. return hr; }
public static extern void MFCreatePresentationClock( out IMFPresentationClock ppPresentationClock );
/// <summary> /// Starts the asychronous encode operation /// </summary> /// <param name="inputURL">Source filename</param> /// <param name="outputURL">Targe filename</param> /// <param name="audioOutput">Audio format that will be used for audio streams</param> /// <param name="videoOutput">Video format that will be used for video streams</param> /// <param name="startPosition">Starting position of the contet</param> /// <param name="endPosition">Position where the new content will end</param> public void Encode(string inputURL, string outputURL, AudioFormat audioOutput, VideoFormat videoOutput, ulong startPosition, ulong endPosition) { // If busy with other operation ignore and return if (this.IsBusy()) { return; } try { this.presentationClock = null; this.startPosition = startPosition; this.endPosition = endPosition; object objectSource = null; // Create the media source using source resolver and the input URL uint objectType = default(uint); this.mediaSource = null; // Init source resolver IMFSourceResolver sourceResolver = null; MFHelper.MFCreateSourceResolver(out sourceResolver); sourceResolver.CreateObjectFromURL(inputURL, Consts.MF_RESOLUTION_MEDIASOURCE, null, out objectType, out objectSource); this.mediaSource = (IMFMediaSource)objectSource; // Create the media session using a global start time so MF_TOPOLOGY_PROJECTSTOP can be used to stop the session this.mediaSession = null; IMFAttributes mediaSessionAttributes = null; MFHelper.MFCreateAttributes(out mediaSessionAttributes, 1); mediaSessionAttributes.SetUINT32(new Guid(Consts.MF_SESSION_GLOBAL_TIME), 1); MFHelper.MFCreateMediaSession(mediaSessionAttributes, out this.mediaSession); // Create the event handler AsyncEventHandler mediaEventHandler = new AsyncEventHandler(this.mediaSession); mediaEventHandler.MediaEvent += this.MediaEvent; // Get the stream descriptor IMFPresentationDescriptor presentationDescriptor = null; mediaSource.CreatePresentationDescriptor(out presentationDescriptor); // Get the duration presentationDescriptor.GetUINT64(new Guid(Consts.MF_PD_DURATION), out this.duration); IMFTranscodeProfile transcodeProfile = null; Guid containerType = new Guid(Consts.MFTranscodeContainerType_MPEG4); if (outputURL.EndsWith(".wmv", StringComparison.OrdinalIgnoreCase) || outputURL.EndsWith(".wma", StringComparison.OrdinalIgnoreCase)) { containerType = new Guid(Consts.MFTranscodeContainerType_ASF); } // Generate the transcoding profile transcodeProfile = SimpleFastEncode.CreateProfile(audioOutput, videoOutput, containerType); // Create the MF topology using the profile IMFTopology topology = null; MFHelper.MFCreateTranscodeTopology(this.mediaSource, outputURL, transcodeProfile, out topology); // Set the end position topology.SetUINT64(new Guid(Consts.MF_TOPOLOGY_PROJECTSTART), 0); topology.SetUINT64(new Guid(Consts.MF_TOPOLOGY_PROJECTSTOP), (endPosition == 0) ? this.duration : endPosition); // Set the session topology this.mediaSession.SetTopology((uint)Enums.MFSESSION_SETTOPOLOGY_FLAGS.None, topology); } catch (Exception ex) { this.mediaSession = null; // Fire the EncodeError event if (this.EncodeError != null) { this.EncodeError(new Exception(ex.Message, ex)); } } }
private void MediaEvent(uint eventType, int eventStatus) { if (eventStatus < 0) { this.mediaSession = null; // A session event reported an error if (this.EncodeError != null) { this.EncodeError(new COMException("Exception from HRESULT: 0x" + eventStatus.ToString("X", System.Globalization.NumberFormatInfo.InvariantInfo) + " (Media session event #" + eventType + ").", eventStatus)); } } else { switch (eventType) { case Consts.MESessionTopologySet: // Start playback from the start position MediaSessionStartPosition startPositionVar = new MediaSessionStartPosition((long)this.startPosition); this.mediaSession.Start(Guid.Empty, startPositionVar); break; case Consts.MESessionStarted: // Get the presentation clock IMFClock clock = null; this.mediaSession.GetClock(out clock); this.presentationClock = (IMFPresentationClock)clock; this.progressTimer.Start(); break; case Consts.MESessionEnded: // Close the media session. this.presentationClock = null; this.mediaSession.Close(); break; case Consts.MESessionStopped: // Close the media session. this.presentationClock = null; this.mediaSession.Close(); break; case Consts.MESessionClosed: // Stop the progress timer this.presentationClock = null; this.progressTimer.Stop(); // Shutdown the media source and session this.mediaSource.Shutdown(); this.mediaSession.Shutdown(); this.mediaSource = null; this.mediaSession = null; // Fire the EncodeCompleted event if (this.EncodeCompleted != null) { this.EncodeCompleted(this, null); } break; } } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Called when the presentation clock is set. /// </summary> /// <param name="pPresentationClock">the presentation clock</param> /// <history> /// 01 Nov 18 Cynic - Ported in /// </history> public HResult OnSetPresentationClock(IMFPresentationClock pPresentationClock) { return(HResult.S_OK); }