/// <summary>Determines whether the specified IMediaSeeking can be used to retrieve duration and current position.</summary> /// <param name="seeking">The interface to check.</param> /// <returns>true if it can be used to retrieve duration and current position; false, otherwise.</returns> private static bool CanGetPositionAndDuration(IMediaSeeking seeking) { if (seeking == null) { return(false); } SeekingCapabilities caps = seeking.GetCapabilities(); if ((caps & SeekingCapabilities.CanGetDuration) != SeekingCapabilities.CanGetDuration) { return(false); } if ((caps & SeekingCapabilities.CanGetCurrentPos) != SeekingCapabilities.CanGetCurrentPos) { return(false); } return(true); }
public override void BuildUp(FilterGraphBuilderParameters parameters) { // Create filter graph manager InitializeGraphBuilder(() => { object comobj = null; try { var type = Type.GetTypeFromCLSID(Clsid.FilterGraph, true); comobj = Activator.CreateInstance(type); var graphBuilder = (IGraphBuilder)comobj; comobj = null; // important! (see the finally block) return(graphBuilder); } catch (Exception e) { throw new FilterGraphBuilderException(GraphBuilderError.FilterGraphManager, e); } finally { if (comobj != null) { Marshal.FinalReleaseComObject(comobj); } } }); // Adding a source filter for a specific video file _sourceFilterHandler = SourceFilterHandlerFactory.AddSourceFilter(GraphBuilder, parameters.Source); // QUERY the filter graph interfaces InitializeMediaEventEx(parameters.MediaWindowHandle); InitializeFilterGraph2(); InitializeMediaControl(); InitializeMediaSeeking(); InitializeBasicAudio(); // create a renderer ThrowExceptionForHRPointer errorFunc = delegate(int hrCode, GraphBuilderError error) { hrCode.ThrowExceptionForHR(error); }; Renderer = RendererBase.AddRenderer(GraphBuilder, parameters.PreferredVideoRenderer, errorFunc, parameters.MediaWindowHandle); DoBuildGraph(); SeekingCapabilities caps = SeekingCapabilities.CanGetDuration; int hr = MediaSeeking.CheckCapabilities(ref caps); if (hr == DsHlp.S_OK) { _isGraphSeekable = true; long rtDuration; MediaSeeking.GetDuration(out rtDuration); _duration = rtDuration; } // MEDIA SIZE int height, arWidth; int width, arHeight; Renderer.GetNativeVideoSize(out width, out height, out arWidth, out arHeight); double w = arWidth; double h = arHeight; _aspectRatio = w / h; _sourceRect = new GDI.RECT { left = 0, top = 0, right = width, bottom = height }; // if (FindSplitter(pFilterGraph)) // ReportUnrenderedPins(pFilterGraph); // then we can raise OnFailedStreamsAvailable GatherMediaInfo(parameters.Source); }
/// <summary> /// Worker thread. /// </summary> /// private void WorkerThread() { ReasonToFinishPlaying reasonToStop = ReasonToFinishPlaying.StoppedByUser; // grabber Grabber grabber = new Grabber(this); // objects object graphObject = null; object grabberObject = null; // interfaces IGraphBuilder graph = null; IBaseFilter sourceBase = null; IBaseFilter grabberBase = null; ISampleGrabber sampleGrabber = null; IMediaControl mediaControl = null; IMediaEventEx mediaEvent = null; IMediaSeeking mediaSeeking = null; try { // get type for filter graph Type type = Type.GetTypeFromCLSID(Clsid.FilterGraph); if (type == null) { throw new ApplicationException("Failed creating filter graph"); } // create filter graph graphObject = Activator.CreateInstance(type); graph = (IGraphBuilder)graphObject; // create source device's object graph.AddSourceFilter(_fileName, "source", out sourceBase); if (sourceBase == null) { throw new ApplicationException("Failed creating source filter"); } // get type for sample grabber type = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (type == null) { throw new ApplicationException("Failed creating sample grabber"); } // create sample grabber grabberObject = Activator.CreateInstance(type); sampleGrabber = (ISampleGrabber)grabberObject; grabberBase = (IBaseFilter)grabberObject; // add grabber filters to graph graph.AddFilter(grabberBase, "grabber"); // set media type AMMediaType mediaType = new AMMediaType { MajorType = MediaType.Video, SubType = MediaSubType.RGB24 }; sampleGrabber.SetMediaType(mediaType); // connect pins int pinToTry = 0; IPin inPin = Tools.GetInPin(grabberBase, 0); IPin outPin = null; // find output pin acceptable by sample grabber while (true) { outPin = Tools.GetOutPin(sourceBase, pinToTry); if (outPin == null) { Marshal.ReleaseComObject(inPin); throw new ApplicationException("Did not find acceptable output video pin in the given source"); } if (graph.Connect(outPin, inPin) < 0) { Marshal.ReleaseComObject(outPin); outPin = null; pinToTry++; } else { break; } } Marshal.ReleaseComObject(outPin); Marshal.ReleaseComObject(inPin); // get media type if (sampleGrabber.GetConnectedMediaType(mediaType) == 0) { VideoInfoHeader vih = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader)); grabber.Width = vih.BmiHeader.Width; grabber.Height = vih.BmiHeader.Height; mediaType.Dispose(); } // let's do rendering, if we don't need to prevent freezing if (!_preventFreezing) { // render pin graph.Render(Tools.GetOutPin(grabberBase, 0)); // configure video window IVideoWindow window = (IVideoWindow)graphObject; window.put_AutoShow(false); window = null; } // configure sample grabber sampleGrabber.SetBufferSamples(false); sampleGrabber.SetOneShot(false); sampleGrabber.SetCallback(grabber, 1); // disable clock, if someone requested it if (!_referenceClockEnabled) { IMediaFilter mediaFilter = (IMediaFilter)graphObject; mediaFilter.SetSyncSource(null); } // get media control mediaControl = (IMediaControl)graphObject; // get media events' interface mediaEvent = (IMediaEventEx)graphObject; // Get media seeking & check seeking capability mediaSeeking = (IMediaSeeking)graphObject; mediaSeeking.GetDuration(out _duration); _onVideoLoad(_duration); const SeekingCapabilities caps = SeekingCapabilities.CanSeekAbsolute | SeekingCapabilities.CanGetDuration; SeekingCapabilities canSeekCap; int hr = mediaSeeking.GetCapabilities(out canSeekCap); if (hr < 0) { throw new ApplicationException("Failed getting seeking capabilities"); } _isSeekEnabled = (canSeekCap & caps) == caps; // run mediaControl.Run(); IsPlaying = true; do { // GetCurrentTime if (_isGetCurrentTime) { mediaSeeking.GetCurrentPosition(out _currentGetTime); _isGetCurrentTime = false; } if (IsSetPause) { mediaControl.Pause(); IsSetPause = false; IsPlaying = false; } if (IsSetPlay) { mediaControl.Run(); IsSetPlay = false; IsPlaying = true; } // SetCurrentTime if (_isSetCurrentTime) { long stop = 0; mediaSeeking.SetPositions(ref _currentSetTime, SeekingFlags.AbsolutePositioning, ref stop, SeekingFlags.NoPositioning); _isSetCurrentTime = false; } IntPtr p1; IntPtr p2; DsEvCode code; if (mediaEvent.GetEvent(out code, out p1, out p2, 0) >= 0) { mediaEvent.FreeEventParams(code, p1, p2); if (code == DsEvCode.Complete) { reasonToStop = ReasonToFinishPlaying.EndOfStreamReached; break; } } } while (!_stopEvent.WaitOne(100, false)); IsPlaying = false; mediaControl.Stop(); } catch (Exception exception) { // provide information to clients if (VideoSourceError != null) { VideoSourceError(this, new VideoSourceErrorEventArgs(exception.Message)); } } finally { // release all objects graph = null; grabberBase = null; sampleGrabber = null; mediaControl = null; mediaEvent = null; mediaSeeking = null; if (graphObject != null) { Marshal.ReleaseComObject(graphObject); graphObject = null; } if (sourceBase != null) { Marshal.ReleaseComObject(sourceBase); sourceBase = null; } if (grabberObject != null) { Marshal.ReleaseComObject(grabberObject); grabberObject = null; } } if (PlayingFinished != null) { PlayingFinished(this, reasonToStop); } }