Frage

Ich habe mit der neuesten Version des WPFMediaKit . Was ich versuche zu schreiben eine Beispielanwendung zu tun, die die Samplegrabber verwenden die Videobilder von Videodateien zu erfassen, damit ich sie als einzelne Bitmaps haben.

Bisher habe ich habe viel Glück mit dem folgenden Code bei der Konstruktion und mein Diagramm zu machen. Allerdings, wenn ich diesen Code verwenden, um eine .wmv-Videodatei abspielen, wenn der samplegrabber angebracht ist, wird er nervös oder abgehackt wiedergegeben werden. Wenn ich die Zeile aus kommentieren, wo ich die samplegrabber Filter hinzufügen, es funktioniert gut. Auch hier funktioniert es mit dem samplegrabber richtig mit AVI / MPEG, etc.

 protected virtual void OpenSource()
    {
        FrameCount = 0;
        /* Make sure we clean up any remaining mess */
        FreeResources();

        if (m_sourceUri == null)
            return;

        string fileSource = m_sourceUri.OriginalString;

        if (string.IsNullOrEmpty(fileSource))
            return;

        try
        {
            /* Creates the GraphBuilder COM object */
            m_graph = new FilterGraphNoThread() as IGraphBuilder;

            if (m_graph == null)
                throw new Exception("Could not create a graph");


            /* Add our prefered audio renderer */
            InsertAudioRenderer(AudioRenderer);

            var filterGraph = m_graph as IFilterGraph2;

            if (filterGraph == null)
                throw new Exception("Could not QueryInterface for the IFilterGraph2");

            IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1);                                

            IBaseFilter sourceFilter;

            /* Have DirectShow find the correct source filter for the Uri */
            var hr = filterGraph.AddSourceFilter(fileSource, fileSource, out sourceFilter);
            DsError.ThrowExceptionForHR(hr);

            /* We will want to enum all the pins on the source filter */
            IEnumPins pinEnum;

            hr = sourceFilter.EnumPins(out pinEnum);
            DsError.ThrowExceptionForHR(hr);

            IntPtr fetched = IntPtr.Zero;
            IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            int pinsRendered = 0;                

            m_sampleGrabber = (ISampleGrabber)new SampleGrabber();
            SetupSampleGrabber(m_sampleGrabber);
            hr = m_graph.AddFilter(m_sampleGrabber as IBaseFilter, "SampleGrabber");
            DsError.ThrowExceptionForHR(hr);

            /* Loop over each pin of the source filter */
            while (pinEnum.Next(pins.Length, pins, fetched) == 0)
            {
                if (filterGraph.RenderEx(pins[0],
                                         AMRenderExFlags.RenderToExistingRenderers,
                                         IntPtr.Zero) >= 0)
                pinsRendered++;

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pinEnum);
            Marshal.ReleaseComObject(sourceFilter);

            if (pinsRendered == 0)
                throw new Exception("Could not render any streams from the source Uri");

            /* Configure the graph in the base class */
            SetupFilterGraph(m_graph);

            HasVideo = true;
            /* Sets the NaturalVideoWidth/Height */
            //SetNativePixelSizes(renderer);
        }
        catch (Exception ex)
        {
            /* This exection will happen usually if the media does
             * not exist or could not open due to not having the
             * proper filters installed */
            FreeResources();

            /* Fire our failed event */
            InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex));
        }

        InvokeMediaOpened();
    }

Und:

 private void SetupSampleGrabber(ISampleGrabber sampleGrabber)
    {
        FrameCount = 0;
        var mediaType = new AMMediaType
        {
            majorType = MediaType.Video,
            subType = MediaSubType.RGB24,
            formatType = FormatType.VideoInfo
        };

        int hr = sampleGrabber.SetMediaType(mediaType);

        DsUtils.FreeAMMediaType(mediaType);
        DsError.ThrowExceptionForHR(hr);

        hr = sampleGrabber.SetCallback(this, 0);
        DsError.ThrowExceptionForHR(hr);
    }

Ich habe ein paar Dinge sagen, die die .wmv oder asf Formate asynchron lesen oder so etwas. Ich habe versucht, eine WMAsfReader zu dekodieren eingefügt, die funktioniert, aber sobald er an den VMR9 geht gibt es das gleiche Verhalten. Außerdem habe ich es bekommen richtig zu arbeiten, wenn ich die IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1); Zeile aus kommentieren und haben filterGraph.Render(pins[0]); - der einzige Nachteil ist, dass jetzt macht es in einer Active Witwe seines eigenen statt meiner Kontrolle, aber die samplegrabber Funktionen korrekt und ohne Skipping . Also habe ich den Fehler denke im VMR9 / samplegrabbing irgendwo.

Jede Hilfe? Ich bin neu in diesem.

War es hilfreich?

Lösung

wird Manche Decoder-Hardware-Beschleunigung mit DXVA verwenden. Dies wird implementiert, indem ein teilweise decodierten Format verhandeln, und Leiten dies zum Teil an die Renderer dekodierten Daten zu vervollständigen Decodierung und macht. Wenn Sie Einfügen einer Probe Grabber konfiguriert RGB24 zwischen dem Decoder und dem Renderer, werden Sie deaktivieren Hardware-Beschleunigung.

Das, ich bin sicher, ist der Kern des Problems. Die Details sind noch ein wenig vage, fürchte ich, wie, warum es funktioniert, wenn Sie die Standard-VMR-7 verwenden, aber schlägt fehl, wenn Sie VMR-9 verwenden. Ich würde vermuten, dass der Decoder zur Verwendung DXVA versucht, und andernfalls in dem VMR-9 Fall, hat aber eine vernünftige Software-only-Sicherung, die auch in VMR-7 arbeitet.

Ich bin mit dem WPFMediaKit nicht vertraut, aber ich würde denken, die einfachste Lösung ist die explizite VMR-9-Erstellung mit einer expliziten VMR-7 Schöpfung zu ersetzen. Das heißt, wenn der Decoder-Software-only mit VMR-7 arbeitet, dann verwenden Sie das und konzentrieren sich auf die Festsetzung der Fenster-Neuzuordnung Ausgabe.

Andere Tipps

Es endete die den Code auf denen ich geschrieben habe (was an sich war ziemlich schamlos etwas von mir geändert von Jeremiah Morrill des WPFMediakit Quellcode) war in der Tat ausreichend, um die WMV-Dateien zu machen und sein Probe gepackt.

Es scheint, die choppiness etwas mit Laufen durch die VS-Debugger oder VS2008 selbst zu tun. Nach Messing für eine Weile im visuellen Editor mit dem XAML um, dann die App läuft, muß ich das abgehackt Verhalten eingeführt. Das Herunterfahren VS2008 scheint es, Abhilfe zu schaffen. : P

Also nicht viel von einer Antwort, aber zumindest ein (ärgerlich - Neustart VS2008). Fix, wenn es taucht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top