/// <summary> /// /// </summary> /// <param name="pGroup">Timeline group info</param> /// <param name="pCallback">Client callback</param> /// <param name="pEventSink">Event sync to call on file complete</param> /// <param name="ec">Event code to send on file completion</param> public AVCallback( MediaGroup pGroup, IDESCombineCB pCallback, IMediaEventSink pEventSink, EventCode ec ) { m_pCallback = pCallback; m_Group = pGroup; m_pEventSink = pEventSink; m_ec = ec; m_iCurFrame = 0; m_iCurFile = 0; MediaFile mf = m_Group.File(m_iCurFile); if (mf != null) { m_CurFileName = mf.FileName; m_iMaxFrame = mf.LengthInFrames; } else { m_CurFileName = null; m_iMaxFrame = int.MaxValue; } }
public int BufferCB(double SampleTime, System.IntPtr pBuffer, int BufferLen) { // Call the client int iRet; if (m_pCallback != null) { iRet = m_pCallback.BufferCB(m_CurFileName, SampleTime, pBuffer, BufferLen); } else { iRet = 0; } m_iCurFrame++; // Have we finished the current file? if (m_iCurFrame >= m_iMaxFrame) { // Send the notification int hr = m_pEventSink.Notify(m_ec, new IntPtr(m_iCurFile), new IntPtr(m_iCurFrame)); // Find the next file m_iCurFile++; if (m_iCurFile < m_Group.Count) { MediaFile mf = m_Group.File(m_iCurFile); m_CurFileName = mf.FileName; m_iMaxFrame += mf.LengthInFrames; } else { // A failsafe m_iMaxFrame = int.MaxValue; } } return(iRet); }
/// <summary> /// Called on a new thread to process events from the graph. The thread /// exits when the graph finishes. Cancelling is done here. /// </summary> private void EventWait() { // Returned when GetEvent is called but there are no events const int E_ABORT = unchecked ((int)0x80004004); int hr; IntPtr p1, p2; EventCode ec; EventCode exitCode = 0; IMediaEvent pEvent = (IMediaEvent)m_pGraph; do { // Read the event for ( hr = pEvent.GetEvent(out ec, out p1, out p2, 100); hr >= 0 && m_State < ClassState.GraphCompleted; hr = pEvent.GetEvent(out ec, out p1, out p2, 100) ) { switch (ec) { case EventCode.UserAbort: ChangeState(ClassState.Cancelling); exitCode = ec; // Release any resources the message allocated hr = pEvent.FreeEventParams(ec, p1, p2); DESError.ThrowExceptionForHR(hr); break; // If the clip is finished playing case EventCode.Complete: case EventCode.ErrorAbort: ChangeState(ClassState.GraphCompleting); exitCode = ec; // Release any resources the message allocated hr = pEvent.FreeEventParams(ec, p1, p2); DESError.ThrowExceptionForHR(hr); break; // Walked past the end of a video file, send an event case EC_VideoFileComplete: if (FileCompleted != null) { MediaFile mf = m_Video.File(p1.ToInt32()); FileCompletedArgs ca = new FileCompletedArgs(mf.FileName, FileCompletedArgs.FileType.Video); FileCompleted(this, ca); } break; // Walked past the end of a video file, send an event case EC_AudioFileComplete: if (FileCompleted != null) { MediaFile mf = m_Audio.File(p1.ToInt32()); FileCompletedArgs ca = new FileCompletedArgs(mf.FileName, FileCompletedArgs.FileType.Audio); FileCompleted(this, ca); } break; default: // Release any resources the message allocated hr = pEvent.FreeEventParams(ec, p1, p2); DESError.ThrowExceptionForHR(hr); break; } } // If the error that exited the loop wasn't due to running out of events if (hr != E_ABORT) { DESError.ThrowExceptionForHR(hr); } //FilterState fs; //m_pControl.GetState(200, out fs); ////DESError.ThrowExceptionForHR(hr); } while (m_State < ClassState.GraphCompleting); // If the user cancelled if (m_State == ClassState.Cancelling && m_pControl != null) { // Stop the graph, send an appropriate exit code hr = m_pControl.Stop(); exitCode = EventCode.UserAbort; } if (m_State == ClassState.GraphCompleting) { m_State = ClassState.GraphCompleted; } else { m_State = ClassState.Cancelled; } threadCompleted = true; // Send an event saying we are complete if (this.ThreadFinished != null) { DESCompletedArgs ca = new DESCompletedArgs(exitCode); this.ThreadFinished(this, ca); } } // Exit the thread