Question

Je voudrais ouvrir un petit fichier vidéo et mapper toutes les images en mémoire (pour appliquer un filtre personnalisé).Je ne veux pas gérer le codec vidéo, je préfère laisser la bibliothèque s'en occuper pour moi.

J'ai essayé d'utiliser Direct Show avec le filtre SampleGrabber (en utilisant cet exemple http://msdn.microsoft.com/en-us/library/ms787867(VS.85).aspx), mais je n'ai réussi à récupérer que quelques images (pas toutes les images !).Je suis assez nouveau dans la programmation de logiciels vidéo, peut-être que je n'utilise pas la meilleure bibliothèque ou que je le fais mal.

J'ai collé une partie de mon code (principalement un copier/coller modifié de l'exemple msdn), malheureusement il ne récupère pas les 25 premières images comme prévu...

[...]

hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);

pControl->Run(); // Run the graph.
pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.

// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);

for( int i = 0 ; i < 25 ; ++i )
{
    pControl->Run(); // Run the graph.
    pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.

    char *pBuffer = new char[cbBuffer];
    hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);

    AM_MEDIA_TYPE mt;
    hr = pGrabber->GetConnectedMediaType(&mt);
    VIDEOINFOHEADER *pVih;
    pVih = (VIDEOINFOHEADER*)mt.pbFormat;

    [...]
}

[...]

Y a-t-il quelqu'un, ayant une expérience en logiciels vidéo, qui peut me conseiller sur le code ou une autre bibliothèque plus simple ?

Merci

Modifier:Les liens Msdn ne semblent pas fonctionner (voir le bug)

Était-ce utile?

La solution

Actuellement, voici les frameworks vidéo les plus populaires disponibles sur les plateformes Win32 :

  1. Vidéo pour Windows :ancien framework Windows remontant à l'époque de Win95 mais encore largement utilisé car très simple à utiliser.Malheureusement, il ne prend en charge que les fichiers AVI pour lesquels le codec VFW approprié a été installé.

  2. Affichage direct :Framework WinXP standard, il peut essentiellement charger tous les formats que vous pouvez lire avec Windows Media Player.Assez difficile à utiliser.

  3. Ffmpeg:plus précisément libavcodec et libavformat fournis avec l'utilitaire multimédia open source Ffmpeg.Il est extrêmement puissant et peut lire de nombreux formats (presque tout ce avec quoi vous pouvez jouer). VLC) même si le codec n'est pas installé sur le système.C'est assez compliqué à utiliser mais vous pouvez toujours vous inspirer du code de ffplay qui l'accompagne ou d'autres implémentations dans des logiciels open source.Quoi qu'il en soit, je pense que c'est quand même beaucoup plus simple à utiliser que DS (et beaucoup plus rapide).Il doit être compilé par MinGW sous Windows, mais toutes les étapes sont très bien expliquées ici (en ce moment, le lien est en panne, j'espère qu'il n'est pas mort).

  4. Quick Time:le framework Apple n'est pas la meilleure solution pour la plate-forme Windows, car il nécessite l'installation de l'application QuickTime ainsi que le codec QuickTime approprié pour chaque format ;il ne supporte pas beaucoup de formats, mais c'est assez courant dans le domaine professionnel (donc certains codecs sont en fait uniquement destinés à QuickTime).Cela ne devrait pas être trop difficile à mettre en œuvre.

  5. Gstreamer:dernier framework open source.Je n'en sais pas grand-chose, je suppose que cela englobe certains des autres systèmes (mais je ne suis pas sûr).

Tous ces frameworks ont été implémentés en backend dans OpenCv Highgui, à l'exception de DirectShow.Le framework par défaut pour Win32 OpenCV utilise VFW (et donc capable d'ouvrir uniquement certains fichiers AVI), si vous souhaitez utiliser les autres, vous devez télécharger le CVS au lieu de la version officielle et quand même faire un peu de piratage du code et ce n'est de toute façon pas trop complet, par exemple le backend FFMPEG ne permet pas de chercher dans le flux.Si vous souhaitez utiliser QuickTime avec OpenCV ce peut vous aider.

Autres conseils

j'ai utilisé OuvrirCV pour charger des fichiers vidéo et les traiter.Il est également pratique pour de nombreux types de traitement vidéo, notamment ceux utiles à la vision par ordinateur.

L'utilisation du modèle « Callback » de SampleGrabber peut vous donner de meilleurs résultats.Consultez l’exemple dans Samples\C++\DirectShow\Editing\GrabBitmaps.

Il y a aussi beaucoup d'informations dans Samples\C++\DirectShow\Filters\Grabber2\grabber_text.txt et readme.txt.

Je sais qu'il est très tentant en C++ d'obtenir une ventilation appropriée des fichiers vidéo et de le faire vous-même.Mais bien que les informations soient disponibles, le processus de création de classes pour gérer chaque format de fichier et le rendre facilement modifiable pour prendre en compte les futurs changements de structure est un processus si long que, franchement, cela n'en vaut tout simplement pas la peine.

Au lieu de cela, je recommande ffmpeg.Il a été mentionné ci-dessus, mais dit que c'est difficile, ce n'est pas difficile.Il existe beaucoup plus d’options que ce dont la plupart des gens auraient besoin, ce qui rend les choses plus difficiles qu’elles ne le sont.Pour la majorité des opérations, vous pouvez simplement laisser ffmpeg se débrouiller tout seul.

Par exemple, une conversion de fichiers ffmpeg -i inputfile.mp4 outputfile.avi

Décidez dès le départ que les opérations ffmpeg seront exécutées dans un thread, ou plus précisément dans une bibliothèque de threads.Mais demandez à votre propre classe de thread de l'envelopper afin que vous puissiez avoir vos propres EventAgs et que les méthodes de vérification du thread sont terminées.Quelque chose comme :-

ThreadLibManager()
{
  List<MyThreads> listOfActiveThreads;
  public AddThread(MyThreads);
}
Your thread class is something like:-
class MyThread
{
 public Thread threadForThisInstance { get; set; }
 public MyFFMpegTools mpegTools { get; set; }
}
MyFFMpegTools performs many different video operations, so you want your own event  
args to tell your parent code precisely what type of operation has just raised and 
event.
enum MyFmpegArgs
{
public int thisThreadID { get; set; } //Set as a new MyThread is added to the List<>
public MyFfmpegType operationType {get; set;}
//output paths etc that the parent handler will need to find output files
}
enum MyFfmpegType
{
  FF_CONVERTFILE = 0, FF_CREATETHUMBNAIL, FF_EXTRACTFRAMES ...
}

Voici un petit extrait de ma classe d'outils ffmpeg, cette partie collectant des informations sur une vidéo.J'ai placé FFmpeg dans un emplacement particulier, et au démarrage du logiciel, il s'assure qu'il est là.Pour cette version, je l'ai déplacé sur le bureau, je suis presque sûr d'avoir écrit le chemin correctement pour vous (je déteste vraiment le système de dossiers spéciaux de MS, donc je l'ignore autant que possible).

Quoi qu'il en soit, c'est un exemple d'utilisation de ffmpeg sans fenêtre.

        public string GetVideoInfo(FileInfo fi)
    {
        outputBuilder.Clear();
        string strCommand = string.Concat(" -i \"", fi.FullName, "\"");
        string ffPath =   
  System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";
        string oStr = "";

        try
        {
            Process build = new Process();
            //build.StartInfo.WorkingDirectory = @"dir";
            build.StartInfo.Arguments = strCommand;
            build.StartInfo.FileName = ffPath;

            build.StartInfo.UseShellExecute = false;
            build.StartInfo.RedirectStandardOutput = true;
            build.StartInfo.RedirectStandardError = true;
            build.StartInfo.CreateNoWindow = true;
            build.ErrorDataReceived += build_ErrorDataReceived;
            build.OutputDataReceived += build_ErrorDataReceived;
            build.EnableRaisingEvents = true;
            build.Start();
            build.BeginOutputReadLine();
            build.BeginErrorReadLine();
            build.WaitForExit();


            string findThis = "start";
            int offset = 0;
            foreach (string str in outputBuilder)
            {
                if (str.Contains("Duration"))
                {
                    offset = str.IndexOf(findThis);
                    oStr = str.Substring(0, offset);
                }
            }
        }
        catch
        {
            oStr = "Error collecting file information";
        }

        return oStr;
    }
    private void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        string strMessage = e.Data;
        if (outputBuilder != null && strMessage != null)
        {
            outputBuilder.Add(string.Concat(strMessage, "\n"));
        }
    } 

Essayez d'utiliser le OuvrirCV bibliothèque.Il possède certainement les capacités dont vous avez besoin.

Ce guide contient une section sur l'accès aux images d'un fichier vidéo.

S'il s'agit de fichiers AVI, je lirais moi-même les données du fichier AVI et extrairais les images.Utilisez maintenant le gestionnaire de compression vidéo pour le décompresser.

Le format de fichier AVI est très simple, voir : http://msdn.microsoft.com/en-us/library/dd318187(VS.85).aspx (et utilisez Google).

Une fois le fichier ouvert, extrayez simplement chaque image et transmettez-la à ICDecompress() pour la décompresser.

Cela semble demander beaucoup de travail, mais c'est le moyen le plus fiable.

Si cela demande trop de travail ou si vous voulez plus que des fichiers AVI, utilisez ffmpeg.

OpenCV est la meilleure solution si la vidéo dans votre cas doit uniquement conduire à une séquence d'images.Si vous êtes prêt à effectuer un véritable traitement vidéo, donc ViDeo équivaut à "Visual Audio", vous devez suivre ceux proposés par "martjno".Les nouvelles solutions Windows également pour Win7 incluent 3 nouvelles possibilités supplémentaires :

  1. Fondation Windows Media :Successeur de DirectShow ;interface nettoyée
  2. Encodeur Windows Media 9 :Il n'inclut pas seulement le programme, il fournit également des bibliothèques pour le codage.
  3. Expression Windows 4 :Successeur de 2.

Les 2 dernières sont des solutions uniquement commerciales, mais la première est gratuite.Pour coder WMF, vous devez installer le SDK Windows.

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