Exemple #1
0
        /// <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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
            }
        }