Pregunta

He estado usando la versión más reciente de la WPFMediaKit . Lo que estoy tratando de hacer es escribir una aplicación de ejemplo que va a utilizar el Samplegrabber para capturar los fotogramas de vídeo de los archivos de vídeo para que pueda tenerlos como mapas de bits individuales.

Hasta ahora, he tenido buena suerte con el siguiente código en la construcción y de la representación gráfica de mi. Sin embargo, cuando se utiliza este código para reproducir un archivo de vídeo WMV, cuando se une el samplegrabber, se reproducirá con saltos o entrecortada. Si comento hacia fuera de la línea donde agrego el filtro samplegrabber, funciona bien. Una vez más, funciona con el samplegrabber correctamente con 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();
    }

Y:

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

He leído algunas cosas diciendo que los formatos .wmv .asf o son asíncronos o algo así. He intentado insertar un WMAsfReader de decodificación que funciona, pero una vez que va a la VMR9 se da el mismo comportamiento. Además, he conseguido que funcione correctamente cuando comente la línea IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1); y tienen filterGraph.Render(pins[0]); - el único inconveniente es que ahora se hace en una viuda ActiveMovie de su propio lugar de mi control, sin embargo las funciones samplegrabber correctamente y sin ningún tipo de saltar . Así que estoy pensando en el error está en el directorio / algún lugar samplegrabbing VMR9.

Cualquier ayuda? Soy nuevo en esto.

¿Fue útil?

Solución

Algunos decodificadores usará la aceleración por hardware usando DXVA. Esto se implementa mediante la negociación de un formato decodificado parcialmente, y pasando estos datos decodificados en parte al procesador para completar la decodificación y render. Si inserta un capturador de muestra configurado para RGB24 entre el decodificador y el procesador, desactivará la aceleración de hardware.

Eso, estoy seguro, es el quid de la cuestión. Los detalles son aún un poco vaga, me temo, como por ejemplo por qué funciona cuando se utiliza el valor por defecto VMR-7, pero falla cuando utiliza VMR-9. Me imagino que el decodificador está tratando de usar DXVA y en su defecto, en el caso VMR-9, pero tiene una copia de seguridad sólo de software razonable que funciona bien en VMR-7.

No estoy familiarizado con el WPFMediaKit, pero yo creo que la solución más simple es reemplazar la creación explícita VMR-9 con una explícita creación VMR-7. Es decir, si el decodificador funciona sólo de software con VMR-7, a continuación, utilizar eso y concentrado en arreglar el problema ventana reparentalización.

Otros consejos

Se terminó el código que he publicado (que en sí mismo era bastante descaradamente ligeramente modificado por mí desde el código fuente WPFMediakit de Jeremías Morrill) era de hecho suficiente para hacer que los archivos .WMV y se agarró de la muestra.

Parece que la choppiness tiene algo que ver con el funcionamiento a través del depurador de VS, o la propia VS2008. Después de jugar un poco con el XAML por un tiempo en el editor visual, a continuación, ejecutar la aplicación, voy a tener este comportamiento volátil introducido. El cierre de VS2008 parece remediarlo. : P

Así que no hay mucho de una respuesta, pero al menos un (molesto - reiniciar VS2008). Fix cuando surge

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top