J'ai utilisé la dernière version du WPFMediaKit. Ce que j'essaye de faire est d'écrire un exemple d'application qui utilisera le Samplegrabber pour capturer les images vidéo des fichiers vidéo afin que je puisse les avoir comme Bitmaps individuels.Samplegrabber fonctionne très bien sur les fichiers AVI/MPEG, mais saccadée avec WMV
Jusqu'ici, j'ai eu de la chance avec le code suivant lors de la construction et du rendu de mon graphe. Toutefois, lorsque j'utilise ce code pour lire un fichier vidéo .wmv, lorsque le samplegrabber est connecté, il lit jumpy ou hachy. Si je commente la ligne où j'ajoute le filtre samplegrabber, cela 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();
}
Et:
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 petites choses en disant que les formats .wmv ou .asf sont asynchrones ou quelque chose . J'ai essayé d'insérer un WMAsfReader pour décoder ce qui fonctionne, mais une fois qu'il va à la VMR9, il donne le même comportement. En outre, je l'ai eu pour fonctionner correctement quand je commente la ligne IBaseFilter renderer = CreateVideoMixingRenderer9(m_graph, 1);
et ai filterGraph.Render(pins[0]);
- le seul inconvénient est que maintenant il rend dans une veuve d'Activemovie de son propre au lieu de mon contrôle, cependant le samplegrabber fonctionne correctement et sans aucun saut . Donc je pense que le bug est dans le VMR9/samplegrabbing quelque part.
Une aide? Je suis nouveau à cela.
Merci, je vais faire quelques recherches pour voir s'il est possible d'utiliser le VMR7 à la place dans le WPFMediakit, ou bien lancer le mien en se basant sur un code similaire à la façon dont le VMR9 est implémenté. Quelque chose que j'ai découvert avec ce problème est que j'obtiens différents résultats sur différents ordinateurs (c.-à-d. Que j'ai apporté cette maison pour travailler la nuit dernière et aucune lecture agitée pour WMV). Je vais étudier graphedit si le graphique sort le même ou quoi sur chacun. Ou vous pouvez être sur quelque chose avec l'accélération matérielle. –