2008-11-27 7 views
2

Existe-t-il un moyen de détecter qu'un filtre DirectShow a atteint la fin de son fichier? À la fin de son fichier, je veux dire qu'un filtre avec un filtre SampleGrabber ne recevra jamais un autre appel SampleCB.eof détection pour DirectShow

Voici quelques choses qui ne fonctionnent pas:

  • confiance IMediaDet::get_StreamLength (il est dit souvent, il y a plus d'images dans une vidéo que existe vraiment)
  • confiance IMediaSeeking::GetDuration (il est compatible avec IMediaDet, +/- un cadre)
  • Utilisez IMediaControl::GetState (le filtergraph reste en cours d'exécution, même si tous les cadres ont déjà été traitées à partir d'un fichier)

Arrière-plan:

Je fais du traitement vidéo et j'ai une classe qui crée un filtre graphique avec un SampleGrabber. Chaque fois que SampleGrabber::SampleCB est appelé, je le bloque avec un mutex afin que je puisse exécuter le filtre en mode pull. Quand je suis prêt pour une autre image, je débloque le mutex dans mon thread principal et j'attends SampleGrabber::SampleCB pour m'envoyer un signal que c'est fait. Pour certaines vidéos, IMediaDet::get_StreamLength m'indique que la vidéo a plus d'images qu'il n'en existe réellement. Une fois que j'ai extrait le cadre final et en demande un de plus que ce qui existe réellement, le thread principal bloque pour toujours car SampleGrabber::SampleCB ne sera plus jamais appelé. Je voudrais être en mesure de détecter quand SampleGrabber::SampleCB ne sera jamais appelé pour les sources de fichiers. Des applications comme Windows Media Player sont en mesure de le faire parce que l'interface graphique signale que la vidéo s'est terminée après la dernière image réelle, donc apparemment il y a un moyen de le faire.

EDIT:

J'utilise WaitForSingleObject pour mettre en œuvre le principal blocage de fil. La solution de contournement que j'ai utilisée jusqu'ici est de faire ce que Greg a suggéré: avoir un timeout fini. Malheureusement, cela devient un peu difficile. L'attente peut échouer pour de nombreuses raisons, telles qu'un eof, un système de fichiers réseau lent, une connexion réseau perdue, un décodeur lent, etc.

Répondre

3

Peut-être utiliser l'interface IMediaEventEx? L'un des codes d'événement est EC_COMPLETE documenté comme 'Toutes les données d'un flux particulier ont été rendues.'

1

En supposant que le thread principal bloque sur WaitForSingleObject, ne pouvez-vous pas spécifier de délai d'attente? Ensuite, si l'attente revient parce qu'elle a expiré plutôt que parce qu'elle a reçu un signal, vous saurez que c'est la dernière image.

+0

C'est ce que j'ai fait jusqu'ici. Malheureusement, l'attente peut échouer pour plusieurs raisons (true eof, système de fichiers réseau lent, connexion réseau perdue, décodeur lent, etc.). –

+0

Ouais c'est vrai - malheureusement, c'est la meilleure solution que j'ai trouvée parce que, comme vous l'avez également constaté, IMediaDet ne renvoie jamais vraiment les bonnes informations, surtout s'il y a des filtres non-Microsoft comme ffdshow dans le graphique. faire beaucoup de saisie de cadre récemment). –

Questions connexes