public int AddClip(string path, out ClipEntry pClip) { int it = m_Clips.Count; pClip = new ClipEntry(); m_Clips.Add(pClip); int hr = pClip.Create(m_pController, path); // if we expect both audio and video, then all clips // must have both audio and video. // If the first clip is video only, then switch // to video-only automatically if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) { // new controller, different options (only one video stream) if (m_pController != null) { Marshal.ReleaseComObject(m_pController); m_pController = null; } m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(m_hwndApp, m_msgSegment); m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.SetBufferMinimum(200); // try again hr = pClip.Create(m_pController, path); } if (hr >= 0) { pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); // if this is the first clip, create the render graph if (m_Clips.Count == 1) { m_pRenderGraph = new FilterGraph() as IGraphBuilder; hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); if (hr >= 0 && m_hwndApp != IntPtr.Zero) { IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; if (pME != null) { pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); } } } } else { pClip.Dispose(); m_Clips.RemoveAt(it); } return(hr); }
public int AddClip(string path, out ClipEntry pClip) { int it = m_Clips.Count; pClip = new ClipEntry(); m_Clips.Add(pClip); int hr = pClip.Create(m_pController, path); // if we expect both audio and video, then all clips // must have both audio and video. // If the first clip is video only, then switch // to video-only automatically if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) { // new controller, different options (only one video stream) if (m_pController != null) { Marshal.ReleaseComObject(m_pController); m_pController = null; } m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(m_hwndApp, m_msgSegment); m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.SetBufferMinimum(200); // try again hr = pClip.Create(m_pController, path); } if (hr >= 0) { pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); // if this is the first clip, create the render graph if (m_Clips.Count == 1) { m_pRenderGraph = new FilterGraph() as IGraphBuilder; hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); if (hr >= 0 && m_hwndApp != IntPtr.Zero) { IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; if (pME != null) { pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); } } } } else { pClip.Dispose(); m_Clips.RemoveAt(it); } return hr; }
public void OnEndOfSegment() { if (m_itCurrent == m_Clips.Count) { // ? already at the end return; } int itOld = m_itCurrent; // locate next graph m_itCurrent++; if (m_pPlayNext >= 0) { // jump to specified clip m_itCurrent = m_pPlayNext; m_pPlayNext = -1; } if (m_itCurrent == m_Clips.Count) { if (!m_bLoop) { // no more clips, so allow EOS to propagate through // render graph. We will receive EC_COMPLETE eventually. m_pController.NoMoreSegments(); // disconnect graphs -- but we cannot do that until NoMoreSegments has // sent the EndOfStream through the bridge m_pController.BridgeGraphs(null, null); return; } // disconnect graphs before seeking the source graph m_pController.BridgeGraphs(null, null); m_itCurrent = 0; m_tStartPosition = 0; } ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; // has this graph been rewound? ce.Prime(); // now we are about to connect it, so as soon as data is delivered out of the graph it // is no longer primed for re-use (it will need a new seek before using again) ce.InUse(); // reconnect m_pController.BridgeGraphs(ce.SinkFilter(), m_pRenderGraphSourceFilter); if (m_bLoop && (m_itCurrent != itOld)) { ce = (ClipEntry)m_Clips[itOld]; // need to rewind clip for next time round // unless we are reusing it immediately (ie looping single clip) // it's better to do this when not in use ce.Prime(0); } }