Domanda

Sono stato con la versione più recente del WPFMediaKit . Quello che sto cercando di fare è scrivere un'applicazione di esempio che utilizzerà il Samplegrabber per catturare i fotogrammi video di file video in modo che io possa avere come singoli bitmap.

Finora, ho avuto la fortuna buona con il seguente codice nel costruire e rendere il mio grafico. Tuttavia, quando uso questo codice per riprodurre un file video wmv, quando il samplegrabber è collegato, si giocherà di nuovo nervosi o troppo veloce. Se io commento la riga in cui aggiungo il filtro samplegrabber, funziona benissimo. Anche in questo caso, funziona con la samplegrabber correttamente con AVI / MPEG, ecc.

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

E

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

Ho letto alcune cose dicendo che il i formati .wmv o .asf sono asincrone o qualcosa del genere. Ho tentato l'inserimento di un WMAsfReader di decodifica che funziona, ma una volta che va al VMR9 dà lo stesso comportamento. Inoltre, ho ottenuto a farlo funzionare correttamente quando ho commentare la riga IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1); e hanno filterGraph.Render(pins[0]); - l'unico inconveniente è che ora rende in una vedova ActiveMovie del proprio posto di mio controllo, tuttavia le funzioni samplegrabber correttamente e senza alcun salto . Così sto pensando il bug è nel VMR9 / da qualche parte samplegrabbing.

Qualsiasi aiuto? Sono nuovo di questo.

È stato utile?

Soluzione

Alcuni decoder utilizzerà l'accelerazione hardware con DXVA. Questo è implementato negoziando un formato parzialmente decodificato, e passando questi dati parzialmente decodificati al rendering per completare la decodifica e rendering. Se si inserisce un grabber campione configurata per RGB24 tra il decoder e il renderer, si disabiliterà l'accelerazione hardware.

Questo, ne sono sicuro, è il nocciolo del problema. I dettagli sono ancora un po 'vago, ho paura, come ad esempio perché funziona quando si utilizza il valore di default VMR-7, ma non riesce quando si utilizza VMR-9. Direi che il decoder sta cercando di utilizzare DXVA e non riuscendo, nel caso VMR-9, ma ha un backup solo software ragionevole che funziona bene in VMR-7.

Non ho dimestichezza con il WPFMediaKit, ma penso che la soluzione più semplice è quella di sostituire la creazione esplicita VMR-9 con una creazione esplicita VMR-7. Cioè, se il decoder funziona solo software con VMR-7, quindi utilizzare tale e concentrato, che fissa il problema della finestra-reparenting.

Altri suggerimenti

E 'finito il codice che ho postato (che di per sé era abbastanza spudoratamente leggermente modificato da me dal codice sorgente WPFMediakit di Geremia Morrill) è stato infatti sufficiente per rendere i file .WMV e di essere campione afferrato.

Sembra che il choppiness ha qualcosa a che fare con l'esecuzione tramite il debugger VS, o VS2008 stesso. Dopo fare in giro con il codice XAML per un po 'l'editor visuale, poi eseguire l'applicazione, avrò questo comportamento instabile introdotto. Spegnimento VS2008 sembra per porvi rimedio. : P

Quindi, non molto di una risposta, ma almeno una (fastidiosa - il riavvio VS2008). Fix quando si pota in su

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top