Question

J'utilise la dernière version du WPFMediaKit . Ce que je suis en train de faire est d'écrire un exemple d'application qui utilisera le Samplegrabber pour capturer les images vidéo de fichiers vidéo afin que je puisse les avoir comme bitmaps individuels.

Jusqu'à présent, j'ai eu bonne chance avec le code suivant lors de la construction et de rendre mon graphique. Cependant, quand j'utiliser ce code pour lire un fichier vidéo .wmv, lorsque le samplegrabber est attaché, il lecture saccadée ou saccadé. Si je commente la ligne où ajouter le filtre samplegrabber, il fonctionne très bien. Encore une fois, cela fonctionne avec le samplegrabber correctement avec 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();
    }

 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);
    }

J'ai lu quelques choses disant que les formats .wmv ou .asf sont asynchrones ou quelque chose. J'ai essayé d'insérer un WMAsfReader à decode qui fonctionne, mais une fois qu'il va à l'VMR9 lui donne le même comportement. De plus, je l'ai obtenu qu'il fonctionne correctement quand je commenter la ligne IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1); et ont filterGraph.Render(pins[0]); - le seul inconvénient est que maintenant il rend dans une veuve ActiveMovie de son propre lieu de mon contrôle, cependant correctement les fonctions de samplegrabber et sans sauter . Donc, je pense le bug est dans le VMR9 / quelque part samplegrabbing.

Toute aide? Je suis nouveau à cela.

Était-ce utile?

La solution

Certains décodeurs utilisera l'accélération matérielle en utilisant DXVA. Ceci est mis en œuvre par la négociation d'un format partiellement décodé, et en passant ces données partiellement décodées au générateur de terminer le décodage et le rendu. Si vous insérez une carte d'acquisition d'échantillon configuré pour RGB24 entre le décodeur et le moteur de rendu, vous désactivez l'accélération matérielle.

Ce, je suis sûr, est le nœud du problème. Les détails sont encore un peu vague, je crains, comme pourquoi il fonctionne lorsque vous utilisez la valeur par défaut VMR-7, mais échoue lorsque vous utilisez VMR-9. Je suppose que le décodeur tente d'utiliser DXVA et, à défaut, dans le VMR-9 cas, mais dispose d'un logiciel de sauvegarde uniquement raisonnable qui fonctionne bien dans VMR-7.

Je ne suis pas familier avec le WPFMediaKit, mais je pense que la solution la plus simple est de remplacer la création explicite VMR-9 avec une création explicite VMR-7. Autrement dit, si le décodeur logiciel fonctionne uniquement avec VMR-7, puis utilisez cela et se concentrer sur la résolution du problème de fenêtre reparentage.

Autres conseils

Il a fini par le code que j'ai posté (qui, en lui-même était assez sans vergogne légèrement modifié par moi à partir du code source WPFMediakit Jeremiah Morrill) était en fait suffisante pour rendre les fichiers .WMV et être échantillon saisi.

Il semble que le clapotis a quelque chose à voir avec la gestion par le débogueur VS ou VS2008 lui-même. Après déconner avec le XAML pendant un certain temps dans l'éditeur visuel, puis en exécutant l'application, je vais avoir ce comportement saccadé introduit. Arrêt de VS2008 semble y remédier. : P

Donc pas beaucoup d'une réponse, mais au moins un (gênant - le redémarrage VS2008). Solution quand il affleure

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top