Il presente articolo è stato tradotto automaticamente.

Codifica video

Salvataggio e riutilizzo di impostazioni per la codifica video

Adi Shavit

Scaricare il codice di esempio

Dai sistemi di telesorveglianza per piattaforme embedded robotici, applicazioni che automaticamente o autonomamente registrare video stanno diventando sempre più onnipresente come il prezzo di attrezzature quali telecamere e gocce di spazio di archiviazione e aumenta le prestazioni computazionali.Tuttavia, la configurazione di tali sistemi da remoto spesso non un'opzione, mentre la distribuzione e l'installazione deve essere semplice e automatico.

Recente, ho bisogno di un modo per preconfigurare le impostazioni di registrazione video su un sistema remoto, quindi sarebbe automaticamente caricare e utilizzare le stesse impostazioni in fase di avvio.Una ricerca Web portata molte domande simili nei forum più risalenti a più di un decennio, ma con soluzioni solo parziale e insoddisfacente.

In questo articolo, sarà presente un modo semplice ma generale per consentire alle applicazioni di elaborazione video salvare il video con le impostazioni di compressione coerente, evitando così di dover specificare manualmente le impostazioni codec ogni volta che viene avviata l'applicazione o la macchina.Mostrerò come accedere i buffer di regolazione interna di un codec in modo che essi possono essere facilmente salvati, reloaded e riutilizzati.Questo funziona per qualsiasi codec video installato sul computer, senza richiedere l'uso di qualsiasi API specifiche di codec.

Video 101

Dati grezzi video sono enormi.Si consideri un modesto fotocamera VGA ambio insieme a un umile tasso di 15 fotogrammi al secondo.Ogni fotogramma di tre canali 640 × 480 pixel è di 900 KB e genera una velocità dati di oltre 13MBps (che è di circa 105Mbps)!Un po' meno modesta apparecchiature video, del tipo che si potrebbe trovare su un telefono cellulare, potrebbero avere risoluzioni ad alta definizione (HD), più elevati frame rate o superiore a 8 bit di profondità di colore.Un film di 90 minuti HD si consumano circa 1 TB in forma grezza.Fortunatamente, i dati video contengono un sacco di ridondanza e algoritmi di compressione video possono memorizzare i file video in modo molto efficiente.Il tipo di algoritmo di compressione scelto dipende dalla particolare applicazione, i requisiti e i vincoli.Diversi fattori variano tra i metodi di compressione, tra cui tariffe in tempo reale, le considerazioni sulle prestazioni e il compromesso tra qualità visiva e le dimensioni del file risultante.

Su Windows, compressione video servizi sono forniti da codec (compressore-decompressore).Mi concentrerò sul Video per Windows (VfW) API per il salvataggio di file video. AVI compresso.Audio Video Interleave (AVI) è un formato di file contenitore multimediale che può contenere più flussi di audio e video e consentire sincrona con audio e video la riproduzione di flussi selezionati.Vi mostrerò come impostazioni codec di compressione possono essere manualmente selezionate e memorizzate in modo persistente, così può essere caricati torna più tardi e riutilizzati automaticamente dall'applicazione su qualsiasi computer su cui è installato lo stesso codec.

Video di risparmio con VfW

Anche se è stato introdotto nel 1992, VfW è un'API duratura, ancora ampiamente utilizzata oggi.Nuove implementazioni di codec e codec, come ad esempio la suite di ffmpeg (ffmpeg.org), continuare a fornire un'interfaccia VfW su Microsoft Windows.

Il flusso tipico per un programma di registrazione video prende solitamente la forma i seguenti passaggi:

  1. Creare un nuovo file AVI, creare un nuovo flusso video non compresso all'interno di esso, scegliere le impostazioni di compressione richiesto e creare un nuovo flusso compresso da quello non compresso.
  2. Aggiungere nuovi fotogrammi come desiderato.
  3. Una volta fatto, rilasciare le risorse in ordine inverso.

Utilizzando VfW sembra come segue:

  1. Aprire e preparare il file video AVI utilizzando il seguente:
    1. AVIFileInit: Inizializza la libreria AVIFile.Deve essere chiamato prima di utilizzare altre funzioni di AVIFile.
    2. AVIFileOpen: Apre un file AVI.
    3. AVIFileCreateStream: Crea un nuovo flusso video all'interno del file AVI.Un file AVI può includere più flussi (di vario tipo).
    4. AVISaveOptions: Presenta una finestra di dialogo Opzioni di compressione (vedere Figura 1).Quando è finito l'utente selezionando le opzioni di compressione, le opzioni vengono restituite in una struttura AVICOMPRESSOPTIONS.
    5. AVIMakeCompressedStream: Crea un flusso compresso dal flusso compresso restituito da AVIFileCreateStream e il filtro di compressione restituito da AVISaveOptions.
    6. AVIStreamSetFormat: Imposta il formato di immagine per il flusso.
  2. Aggiungere fotogrammi del video stream:
    1. AVIStreamWrite: Aggiungere un singolo fotogramma del video stream.Chiamare ripetutamente con cornici aggiuntive come desiderato.
  3. Pulire e chiudere:
    1. AVIStreamRelease: Chiude il flusso compresso (da AVIMakeCompressedStream).
    2. AVIStreamRelease: Chiude il flusso non compresso (da AVIFileCreateStream).
    3. AVISaveOptionsFree: Libera le risorse stanziate dalla funzione AVISaveOptions (questo è spesso dimenticato, che porta a perdite di memoria).
    4. AVIFileRelease: Chiude il file AVI (da AVIFileOpen).
    5. AVIFileExit: Uscita la libreria AVIFile.

The Video Compression Dialog Box Opened by the AVISaveOptions FunctionFigura 1 nella finestra di dialogo di compressione Video aperti con la funzione AVISaveOptions

Che spiega in dettaglio come utilizzare VfW per registrazione video esula dallo scopo di questo articolo.È possibile trovare molti esempi e tutorial on-line.Qui mi concentrerò solo sul passo 1.4: la parte di impostazioni compressore selezione e codec.Il codice sorgente che accompagna questo articolo si basa sull'applicazione C++ dal progetto open source OpenCV (opencv.willowgarage.com) e può essere scaricato da code.msdn.microsoft.com/mag201112Video.Tuttavia, le tecniche che vi mostro qui sono applicabili a — e facilmente integrata in — qualsiasi applicazione che utilizza l'API di VfW e non è specificamente mirato a una particolare implementazione di registrazione video o linguaggio di programmazione.

Soluzioni comuni

Come illustrato in precedenza, il modo più comune per specificare le impostazioni di compressione è possibile chiamare la funzione AVISaveOptions per visualizzare la finestra di dialogo Opzioni di compressione.L'utente può quindi manualmente selezionare il codec desiderato.Il codec scelto può o non può avere un codec opzione "Configure…", che consente di effettuare personalizzazioni impostazioni specifiche codec.Naturalmente, su sistemi senza nemmeno una GUI o un utente attivo, questa finestra di dialogo non è un'opzione.

Il comune alternativa a selezione manuale è quello di selezionare a livello di codice un codec particolare utilizzando fourcc del codec (codice di quattro caratteri; identificatore di v. fourcc.org) e per impostare alcune impostazioni aggiuntive, generali comuni a tutti i codec, come ad esempio la velocità di trasmissione dati, la qualità e la frequenza dei fotogrammi chiave.Il principale svantaggio di questo metodo è che non consente l'impostazione di eventuali impostazioni specifiche del codec.Inoltre, rende il codec utilizzare qualunque siano i suoi attuali impostazioni interne.Questi possono essere valori predefiniti o, peggio ancora, le impostazioni configurate arbitrariamente da altri programmi.Inoltre, non tutti i codec fourcc disponibili su un sistema supportano l'API VfW, che può causare la creazione di flusso compresso a fallire.

Alcuni codec fornire strumenti di configurazione speciale che consentono di modificare le loro impostazioni interne esternamente.Questi strumenti possono assumere la forma di una GUI o uno strumento della riga di comando.Tuttavia, la maggior parte dei codec non forniscono tali strumenti, e perché ogni strumento è personalizzato per un particolare codec, dovete imparare la sua particolare sintassi e l'utilizzo di trarre vantaggio da esso.

Quello che volevo era la flessibilità della modalità di selezione manuale con selezione automatica del codec e tutte le sue impostazioni interne.

Il meglio dei due mondi

Nel primo approccio, la chiamata di AVISaveOptions restituisce un oggetto completamente riempita in AVICOMPRESSOPTIONS.Il secondo approccio è, essenzialmente, riempimento di alcuni dei valori nell'oggetto AVICOMPRESSOPTIONS, all'interno del codice, senza l'utilizzo di AVISaveOptions.

In realtà, è possibile salvare lo stato di piena, internal codec dopo una chiamata a AVISaveOptions così questo stato può essere ripristinato in seguito senza dover chiamare AVISaveOptions nuovamente.Il segreto di dati specifici di compressore video interno e il formato è opaco puntatori lpParms e lpFormat di AVICOMPRESSOPTIONS.Quando tornò dalla AVISaveOptions, questi due puntatori contengono tutto il AVIMakeCompressedStream funzione deve rendere un flusso compresso (questi sono presumibilmente le risorse rilasciate da AVISaveOptionsFree).

L'essenza della mia tecnica, poi, è salvare i dati opachi di lpParms e lpFormat per consentirle di essere riutilizzato.Fortunatamente, questo è semplice da fare.Struct AVICOMPRESSOPTIONS contiene membri di due interi utile, cbParms e cbFormat, che le dimensioni del buffer del binario opaco ha sottolineato da lpParms e lpFormat, rispetto di stato­ively.Queste dimensioni cambiano a seconda il particolare codec selezionato.

Per riassumere, ci sono tre binari "blob" che devono essere salvati dopo una chiamata a AVISaveOptions.Queste sono l'oggetto AVICOMPRESSOPTIONS stesso, e i due binari buffer indicato dai suoi lpParms e lpFormat membri.La lunghezza in byte del buffer di questi è data, rispettivamente, da cbParms e cbFormat.Ripristinando le impostazioni codec è appena invertire il processo: Leggere l'oggetto AVICOMPRESSOPTIONS dal file e impostare i propri membri lpParms e lpFormat a punto presso i rispettivi buffer binari letti dal file.I buffer restaurati binari sono allocati e gestiti dall'applicazione stessa.

Ci sono molti modi per memorizzare dati binari.Come illustrato Figura 2, il mio codice di esempio salva i dati in formato binario.In alternativa, in casi dove i caratteri non stampabili dovrebbero essere evitati (ad esempio i file. txt o XML), ho utilizzato con successo Base-64 codifica per memorizzare i buffer.

Figura 2 esempio di memorizzazione e ripristinare le impostazioni 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;
}

Esempio codice note

Il codice di esempio cattura video da una videocamera o webcam e lo salva in un file AVI. Utilizza la classe OpenCV VideoCapture per accedere la fotocamera e catturare il video. Salvare il video viene eseguita utilizzando una versione della classe OpenCV CvVideoWriter_VFW che ho modificato per supportare il salvataggio delle impostazioni codec. Ho cercato di mantenere le modifiche al codice originale più piccola possibile. Nel codice, il secondo argomento di CvVideoWriter_VFW::open è un std:: String. Se questa stringa è quattro personaggi lungo (come in un fourcc), si presume di essere un fourcc e viene scelto il codec corrispondente a questa fourcc — conversione da quattro personaggi di 1 byte al codice integer fourcc è comunemente fatto con la macro mmioFOURCC, come in mmioFOURCC('D','I','V','X'); vedere tinyurl.com/mmioFOURCC per i dettagli. In caso contrario, la stringa viene considerata il nome di un file di impostazioni codec. Se il file esiste, le impostazioni vengono letti dal file e usate per la compressione video. Se non esiste, quindi apre la finestra di dialogo Opzioni di compressione e un codec e le relative impostazioni possono essere selezionate manualmente; le impostazioni scelte sono quindi salvate nel file del nome selezionato per essere riutilizzata la prossima volta che l'applicazione venga eseguita. Nota: Avrete bisogno di un'installazione OpenCV per compilare ed eseguire il codice di esempio.

Diversi vantaggi

La soluzione che ho presentato ha diversi vantaggi. Modificare le impostazioni di compressione per un'applicazione è solo una questione di cambiare uno dei suoi argomenti. Non non c'è nessuna necessità di ricompilarlo o addirittura fermare l'applicazione in esecuzione. Il metodo è indipendente dal codec e funziona per tutti i codec VfW. Alcuni codec consentono anche come cornice ridimensionamento e deinterlacciamento di elaborazione delle immagini personalizzate aggiuntive. Tutte queste opzioni sono acquisite automaticamente all'interno del file di impostazioni codec.

Il metodo funziona altrettanto bene su sistemi legacy di Microsoft Windows (da Windows 2000 in poi) e anche con i compilatori più anziani, come Visual Studio 6.0. Inoltre, può essere utilizzato con una varietà di lingue che espongono l'interfaccia VfW, ad esempio Visual Basic e c#. Può essere distribuito a più macchine indipendentemente dallo stato corrente codec interne di ogni macchina.

L'avvertenza principale è che questa soluzione è garantita il funzionamento solo quando si utilizza la stessa esatta versione del codec. Se un codec mancante su un determinato computer, o è una versione diversa di quella usata per rendere il file delle impostazioni, i risultati potrebbero essere indeterminati. Ovviamente, non può essere utilizzato nonVfW codec, perché questa soluzione si basa sull'API VfW.

Possibili estensioni a questo lavoro includono Analogamente salvataggio delle impostazioni di compressore audio, che vengono gestite in modo identico alle impostazioni di compressore video. Inoltre, perché AVISaveOptions supporta nativamente AVIs con più flussi, la stessa soluzione si lavorerà anche in questi casi, e le impostazioni di codec per ognuno dei flussi possono essere scritti in un singolo file.

L'altri comuni e più moderno audio e video processing API su Windows è DirectShow. Dovrebbe essere possibile implementare una soluzione simile per DirectShow pure, ma questo è un argomento per un articolo futuro.

Adi Shavit è un consulente di visione del computer. Ha lavorato su immagini e video, sistemi di elaborazione per più di 15 anni, specializzandosi in analisi video in tempo reale. Può essere raggiunto a adishavit@gmail.com.

Grazie ai seguenti esperti tecnici per la revisione di questo articolo: Dana Shavit e Matthew Wilson