Partager via


Cet article a fait l'objet d'une traduction automatique.

Encodage vidéo

Enregistrement et réutilisation des paramètres d'encodage vidéo

ADI Shavit

Téléchargez l'exemple de Code

Des systèmes de surveillance à distance aux plates-formes robotiques embarqués, automatiquement ou de façon autonome enregistrent de la vidéo, les applications deviennent toujours plus omniprésentes que le prix du matériel comme les caméras et gouttes d'espace de stockage et performance computational augmente.Cependant, la configuration de tels systèmes à distance souvent pas une option, tandis que le déploiement et l'installation doivent être simple et automatique.

Récemment, j'avais besoin d'un moyen de préconfigurer les paramètres de l'enregistrement vidéo sur un système distant donc il serait automatiquement charger et utiliser les mêmes paramètres au moment du démarrage.Une recherche sur le Web grandie beaucoup de questions similaires dans plusieurs forums remontant plus d'une décennie, mais avec des solutions seulement partielles et insatisfaisante.

Dans cet article, je vais présente une façon simple mais générale pour permettre aux applications de traitement vidéo enregistrer la vidéo avec les paramètres de compression compatible, évitant ainsi d'avoir à spécifier manuellement les paramètres de codec démarrage de l'application ou la machine.Je montrerai comment accéder les tampons de paramètre interne d'un codec afin qu'ils peuvent être facilement enregistrés, rechargés et réutilisés.Cela fonctionnera pour tout codec vidéo installé sur la machine, sans nécessiter l'utilisation d'une quelconque des APIs codec spécifique.

Vidéo 101

Les données vidéos brutes sont énormes.Envisager une modeste caméra VGA amble le long à un taux humble de 15 images par seconde.Chaque cadre de trois canaux 640 × 480 pixels est de 900 ko et génère un débit de données de plus 13MBps (c'est à propos de 105Mbps) !Légèrement moins modeste équipement vidéo, du type que vous pourriez trouver sur un téléphone mobile, pourrait avoir des résolutions de la haute définition (HD), des taux plus élevés de frame ou plus de 8 bits de la profondeur de couleur.Un film HD de 90 minutes consommera environ 1To sous forme brute.Heureusement, les données vidéo contient beaucoup de redondance, et les algorithmes de compression vidéo peuvent stocker les fichiers vidéo très efficacement.Le type d'algorithme de compression choisi dépend de l'application particulière, ses exigences et ses contraintes.Plusieurs facteurs varient selon les méthodes de compression, y compris les tarifs en temps réel, des considérations de performance et le compromis entre la qualité visuelle et la taille du fichier résultant.

Sous Windows, les services de compression vidéo sont fournis par codecs (Compresseur-Décompresseur).Je me concentrerai sur la vidéo pour Windows (VfW) API pour enregistrer des fichiers vidéo compressé .avi.Audio Video Interleave (.avi) est un format de fichier conteneur multimédia qui peut contenir plusieurs flux de données audio et vidéo et permettre synchrone avec audio-video playback de certains cours d'eau.Je vous montrerai comment paramètres codec de compression peuvent être manuellement sélectionnés et stockées de façon persistante de sorte qu'ils peuvent être chargés revenir plus tard et réutilisées automatiquement par l'application sur tout ordinateur sur lequel est installé le même codec.

Enregistrement vidéo avec VfW

Bien qu'elle fut introduite en 1992, VfW est une API durable, encore largement utilisée aujourd'hui.Nouvelles implémentations de codecs et codec, tels que la suite de ffmpeg (ffmpeg.org), continuer de fournir une interface VfW sur Microsoft Windows.

Le flux typique pour un programme d'enregistrement vidéo prend habituellement la forme des étapes suivantes :

  1. Créez un nouveau fichier AVI, créer un nouveau flux vidéo non compressé au sein de ce, choisissez les paramètres de compression requis et créer un nouveau flux compressé de celle non compressé.
  2. Ajouter de nouveaux cadres que désiré.
  3. Une fois terminée, libérer les ressources dans l'ordre inverse.

À l'aide de VfW-on dirait comme suit :

  1. Ouvrez et préparer le fichier vidéo AVI, à l'aide de ce qui suit :
    1. AVIFileInit : Initialise la bibliothèque AVIFile.Doit être appelée avant d'utiliser les autres fonctions de AVIFile.
    2. AVIFileOpen : Ouvre un fichier AVI.
    3. AVIFileCreateStream : Crée un nouveau flux vidéo dans le fichier AVI.Un fichier AVI peut inclure plusieurs flux de données (de types différents).
    4. AVISaveOptions : Présente une boîte de dialogue Options de Compression standard (voir Figure 1).Lorsque l'utilisateur a fini sélectionner les options de compression, les options sont retournées dans une structure AVICOMPRESSOPTIONS.
    5. AVIMakeCompressedStream : Crée un flux compressé de flux non compressé retourné de AVIFileCreateStream et le filtre de compression retourné par AVISaveOptions.
    6. AVIStreamSetFormat : Définit le format d'image pour le flux.
  2. Ajoutez des cadres dans le flux vidéo :
    1. AVIStreamWrite : Ajouter un cadre unique pour le flux vidéo.Appelez à plusieurs reprises avec des images supplémentaires que souhaité.
  3. Nettoyer et fermer :
    1. AVIStreamRelease : Ferme le flux compressé (de AVIMakeCompressedStream).
    2. AVIStreamRelease : Ferme le flux non compressé (de AVIFileCreateStream).
    3. AVISaveOptionsFree : Libère les ressources allouées par la fonction AVISaveOptions (Ceci est souvent oublié, conduisant à des fuites de mémoire).
    4. AVIFileRelease : Ferme le fichier AVI (de AVIFileOpen).
    5. AVIFileExit : Sortie de la bibliothèque de AVIFile.

The Video Compression Dialog Box Opened by the AVISaveOptions FunctionLa figure 1 la boîte de dialogue de Compression vidéo ouverts par la fonction de AVISaveOptions

Expliquant en détail comment utiliser VfW pour enregistrement vidéo est au-delà de la portée de cet article.Vous trouverez de nombreux exemples et didacticiels en ligne.Je me concentrerai ici uniquement sur 1.4 étape : la partie de paramètres de compresseur sélection et codec.Le code source qui accompagne cet article est basé sur la mise en œuvre de C++ du projet open source OpenCV (opencv.willowgarage.com) et peut être téléchargé à code.msdn.microsoft.com/mag201112Video.Cependant, les techniques de montrer ici sont applicables aux — et facilement intégré — toute application qui utilise l'API VfW et n'est pas spécifiquement ciblée à une implémentation particulière d'enregistrement vidéo ou de langage de programmation.

Solutions communes

Comme indiqué précédemment, la façon courante pour spécifier les paramètres de compression est en appelant la fonction AVISaveOptions pour afficher la boîte de dialogue Options de Compression.L'utilisateur peut sélectionner ensuite manuellement le codec désiré.Le codec choisi peut ou non avoir un codec option « Configure… », ce qui permet de faire des personnalisations de paramètres spécifiques codec.Naturellement, sur les systèmes sans un utilisateur active ou même une GUI, cette boîte de dialogue n'est pas une option.

L'alternative commun à sélection manuelle est de sélectionner par programme un codec particulier à l'aide de fourcc du codec (code à quatre caractères ; identificateur de voir fourcc.org) et pour définir certains paramètres supplémentaires, générales communes à tous les codecs, tels que le débit de données, la qualité et la fréquence d'images clés.L'inconvénient majeur de cette méthode est qu'elle ne permet pas définir tous les paramètres de codec spécifique.De plus, il utilise le codec quelles que soient les paramètres internes en cours.Il peut s'agir de paramètres par défaut ou, pire encore, les paramètres fixés arbitrairement par d'autres programmes.En outre, pas tous les codecs fourcc disponibles sur un système en charge l'API VfW, ce qui peut entraîner la création de flux compressés à l'échec.

Certains codecs fournissent des outils de configuration spéciale qui permettent de changer leurs paramètres internes à l'externe.Ces outils peuvent prendre la forme d'une interface graphique ou un outil de ligne de commande.Cependant, la plupart des codecs ne fournissent pas de tels outils, et parce que chaque outil est personnalisé pour un codec particulier, vous devez apprendre sa syntaxe particulière et l'utilisation d'en profiter.

Ce que je voulais, c'était la souplesse de la mode de sélection manuelle avec sélection automatisée de codec et tous ses paramètres internes.

Le meilleur des deux mondes

Dans la première approche, l'appel de AVISaveOptions renvoie un objet AVICOMPRESSOPTIONS entièrement rempli dans.La deuxième approche est, essentiellement, remplissant certaines valeurs dans l'objet AVICOMPRESSOPTIONS, partir au sein du code, sans l'aide de AVISaveOptions.

En fait, il est possible de sauvegarder l'état complet, interne codec après un appel à AVISaveOptions afin que cet État peut plus tard être restauré sans avoir à appeler AVISaveOptions à nouveau.Le secret des données vidéo spécifique-compresseur interne et le format est dans la lpParms de pointeurs opaque et lpFormat de AVICOMPRESSOPTIONS.Lorsque le retour de AVISaveOptions, ces deux pointeurs contiennent tout le AVIMakeCompressedStream fonction doit faire un flux compressé (ce sont probablement les ressources dégagées par AVISaveOptionsFree).

L'essence même de ma technique, puis, est en enregistrant les données opaques de lpParms et lpFormat pour lui permettre d'être réutilisés.Heureusement, c'est simple de le faire.Le struct AVICOMPRESSOPTIONS contient les membres de deux entiers utile, cbParms et cbFormat, dont la taille des tampons binaires opaques pointé par lpParms et lpFormat, respect d'état­efficacement.Ces tailles changent selon le codec particulier sélectionné.

Pour résumer, il y a trois binaire « blob » qui doivent être enregistrées après un appel à AVISaveOptions.Il s'agit de l'objet AVICOMPRESSOPTIONS lui-même, et les deux tampons binaires indiqué par ses lpParms et les lpFormat membres.La longueur en octets de ces tampons est donnée, respectivement, par cbParms et cbFormat.Restaurer les paramètres de codec est juste inverser le processus : lire les AVICOMPRESSOPTIONS d'objet à partir du fichier et de définir ses lpParms et lpFormat membres à pointer les tampons binaires respectifs lire le fichier.Les tampons binaires restaurés sont alloués et gérées par l'application elle-même.

Il y a plusieurs façons de stocker des données binaires.Comme le montre Figure 2, mon code échantillon enregistre les données sous forme binaire.Par ailleurs, dans les cas où les caractères non imprimables devraient être évitées (tels que les fichiers .txt ou .xml), j'ai utilisé avec succès Base-64 de codage pour stocker les tampons.

Figure 2 exemple de stockage et de restaurer les paramètres de Codec

bool CvVideoWriter_VFW::writeCodecParams( char const* configFileName ) const
{
  using namespace std;   
  try
  { // Open config file
    ofstream cfgFile(configFileName, ios::out | ios::binary);          
    cfgFile.exceptions ( fstream::failbit | fstream::badbit );
    // Write AVICOMPRESSOPTIONS struct data
    cfgFile.write(reinterpret_cast<char const*>(&copts_), sizeof(copts_)); 
    if (copts_.cbParms != 0)// Write codec param buffer
      cfgFile.write(reinterpret_cast<char const*>(copts_.lpParms), copts_.cbParms);
    if (copts_.cbFormat != 0)// Write codec format buffer
      cfgFile.write(reinterpret_cast<char const*>(copts_.lpFormat),
        copts_.cbFormat);
  }
  catch (fstream::failure const&)
  { return false; } // Write failed
  return true;
}
bool CvVideoWriter_VFW::readCodecParams( char const* configFileName )
{ 
  using namespace std;
  try
  { // Open config file
    ifstream cfgFile(configFileName, ios::in | ios::binary);
    cfgFile.exceptions (
      fstream::failbit | fstream::badbit | fstream::eofbit );
    // Read AVICOMPRESSOPTIONS struct data
    cfgFile.read(reinterpret_cast<char*>(&copts_), sizeof(copts_));        
    if (copts_.cbParms != 0)
    { copts_Parms_.resize(copts_.cbParms,0);                // Allocate buffer
      cfgFile.read(&copts_Parms_[0], copts_Parms_.size());  // Read param buffer
      copts_.lpParms = &copts_Parms_[0];                    // Set lpParms to buffer
    }
    else
    { copts_Parms_.clear();
      copts_.lpParms = NULL;
    }
    if (copts_.cbFormat != 0)
    { copts_Format_.resize(copts_.cbFormat,0);              // Allocate buffer
      cfgFile.read(&copts_Format_[0], copts_Format_.size());// Read format buffer
      copts_.lpFormat = &copts_Format_[0];                  // Set lpFormat to buffer
    }
    else
    { copts_Format_.clear();
      copts_.lpFormat = NULL;
    }
  }
  catch (fstream::failure const&)
  { // A read failed, clean up
    ZeroMemory(&copts_,sizeof(AVICOMPRESSOPTIONS));
    copts_Parms_.clear();
    copts_Format_.clear();   
    return false; 
  }
  return true;
}

Notes de Code échantillon

L'exemple de code capture vidéo à partir d'une webcam ou une caméra vidéo et l'enregistre dans un fichier AVI. Il utilise la classe OpenCV VideoCapture pour accéder à la caméra et de capturer la vidéo. Sauver la vidéo est effectuée à l'aide d'une version de la classe OpenCV CvVideoWriter_VFW que j'ai modifié à l'appui de sauver les paramètres de codec. J'ai essayé de garder les changements du code original aussi petite que possible. Dans le code, le deuxième argument de CvVideoWriter_VFW::open est un std::string. Si cette chaîne est de quatre caractères longtemps (comme dans un fourcc), il est supposé pour être un fourcc et le codec correspondant à cette fourcc est choisi — conversion à partir de quatre personnages 1 octet au code fourcc entier est généralement fait avec la macro mmioFOURCC, comme dans mmioFOURCC('D','I','V','X') ; voir tinyurl.com/mmioFOURCC pour plus de détails. Sinon, la chaîne est considérée comme le nom d'un fichier de paramètres de codec. Si le fichier existe, les paramètres sont lues à partir du fichier et utilisés pour la compression vidéo. Si il n'existe pas, puis ouvre la boîte de dialogue Options de Compression et un codec et ses paramètres peuvent être sélectionnés manuellement ; les paramètres choisis sont ensuite enregistrées au fichier le nom sélectionné pour être réutilisée à la prochaine exécution de l'application. Note : Vous aurez besoin une installation OpenCV pour compiler et exécuter l'exemple de code.

Plusieurs avantages

La solution que j'ai présenté comporte plusieurs avantages. Changer les paramètres de compression pour une application, c'est juste une question de changer un de ses arguments. Il n'y a aucune nécessité de recompiler ou même arrêter l'application courante. La méthode est indépendante du codec et fonctionne pour tous les codecs VfW. Certains codecs permettent même de traitement comme cadre de redimensionnement et de désentrelacement d'images personnalisées supplémentaires. Toutes ces options sont automatiquement capturées dans le fichier de paramètres de codec.

La méthode fonctionne aussi bien sur les systèmes Microsoft Windows (de Windows 2000 onward) et aussi avec les compilateurs plus âgés comme Visual Studio 6.0. En outre, il peut être utilisé avec une variété de langues qui exposent l'interface VfW, tels que Visual Basic et c#. Il peut être déployé pour plusieurs machines indépendamment de l'état actuel du codec interne de chaque machine.

L'opposition principale est que cette solution est garantie à travailler uniquement lorsqu'il est utilisée de la même version exacte du codec. Si un codec est manquant sur une machine donnée ou est une version différente de celle utilisée pour faire le fichier de paramètres, les résultats pourraient être indéterminés. De toute évidence, les codecs nonVfW ne peut être utilisés, parce que cette solution est basée sur l'API VfW.

Les extensions possibles de ce travail comprennent de même enregistrer les paramètres de compression audio, qui sont gérés de façon identique aux paramètres de compression vidéo. Aussi, parce que AVISaveOptions supporte nativement les AVIs avec plusieurs flux de données, la même solution travaillera également dans ces cas, et les paramètres de codec pour chacun des volets peuvent être écrites dans un fichier unique.

L'autre commun et plus modern audio et vidéo traitement API sur Windows est DirectShow. Il devrait être possible de mettre en œuvre une solution similaire pour DirectShow ainsi, mais c'est un sujet d'un article de futur.

ADI Shavit est un consultant de vision de l'ordinateur. Il a travaillé sur l'image et vidéo, des systèmes de traitement de plus de 15 ans, qui se spécialise dans l'analyse vidéo en temps réel. Il peut être joint à adishavit@gmail.com.

Grâce à des experts techniques suivants pour l'examen de cet article : Dana Shavit et Matthew Wilson