Differenze tra le versioni di "Gestione dei dati media con GStreamer"

Da Gambas-it.org - Wikipedia.
 
(22 versioni intermedie di uno stesso utente non sono mostrate)
Riga 3: Riga 3:
  
 
==Impostare un ''Elemento'' per la gestione del flusso dei dati==
 
==Impostare un ''Elemento'' per la gestione del flusso dei dati==
Un ''Elemento'' è la Classe di oggetti più importante in ''GStreamer''. Esso svolge una determinata funzione, ed è utilizzato per gestire il flusso di dati, come ad esempio lettura, decodifica ed invio dei medesimi alla scheda audio. Concatenando più ''Elementi'' (''pipeline'') è possibile sfruttare le loro funzionalità ed ottenere gli obiettivi desiderati (come ad esmepio la riproduzione audio) multimediali.
+
Un ''Elemento'' è la Classe di oggetti più importante in ''GStreamer''. Esso svolge una determinata funzione, ed è utilizzato per gestire il flusso di dati, come ad esempio lettura, decodifica ed invio dei medesimi alla scheda audio. Di solito si crea una catena di Elementi collegati insieme (''Pipeline'') e si lascia che i dati passino attraverso questa catena di Elementi. In tal modo è possibile sfruttare le loro funzionalità ed ottenere gli obiettivi multimediali desiderati (come ad esempio la riproduzione audio).
  
 
Il modo più semplice per creare un ''Elemento'' è utilizzare la funzione:
 
Il modo più semplice per creare un ''Elemento'' è utilizzare la funzione:
Riga 104: Riga 104:
 
    
 
    
 
   Print durata
 
   Print durata
 
  
  
Riga 128: Riga 127:
 
   
 
   
 
   Print pos
 
   Print pos
 
  
  
Riga 146: Riga 144:
 
  Dim timeout As Long
 
  Dim timeout As Long
 
   
 
   
   state = Alloc(4)
+
   state = Alloc(SizeOf(gb.Byte), 4)
   pending = Alloc(4)
+
   pending = Alloc(SizeOf(gb.Byte), 4)
 
   
 
   
 
   gst_element_get_state(player, state, pending, timeout)
 
   gst_element_get_state(player, state, pending, timeout)
 
   
 
   
 
   Print Int@(state)
 
   Print Int@(state)
 
  
  
Riga 162: Riga 159:
 
anche questa precedentementre vista, alla quale in Gambas attribuiremo il secondo parametro a ''Null'':
 
anche questa precedentementre vista, alla quale in Gambas attribuiremo il secondo parametro a ''Null'':
 
  gst_element_set_state(elem, GST_STATE_NULL)
 
  gst_element_set_state(elem, GST_STATE_NULL)
 
  
  
Riga 168: Riga 164:
 
In conclusione possiamo dire che bastano solo poche funzioni esterne del API di ''GStreamer'' per effettuare la riproduzione di un file audio.
 
In conclusione possiamo dire che bastano solo poche funzioni esterne del API di ''GStreamer'' per effettuare la riproduzione di un file audio.
  
Riportiamo un esempio pratico funzionante con un'applicazione in ambiente grafico:
+
Riportiamo alcuni esempi con applicazioni in ambiente grafico ed applicazione ''a riga di comando''.
  Private play As Pointer
+
 
 +
 
 +
===Esempio con applicazione in ambiente grafico usando la Classe ''Timer''===
 +
Mostriamo di seguito un esempio pratico e funzionante di un'applicazione in ambiente grafico che fa uso della la Classe ''Timer'' per consentire l'estrazione della durata totale e del tempo trascorso di esecuzione del file mediale:
 +
  Private elem As Pointer
 +
Private tempus As Timer
 
   
 
   
Library "libgstreamer-1.0"
 
 
   
 
   
  Private Const GST_STATE_NULL As Integer = 1
+
Library "libgstreamer-1.0:0.2407.0"
  Private Const GST_STATE_PLAYING As Integer = 4
+
 +
  Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
 +
  Private GST_FORMAT_TIME As Integer = 3
 
   
 
   
 
  <FONT color=gray>' ''gst_init (int *argc, char **argv[])''
 
  <FONT color=gray>' ''gst_init (int *argc, char **argv[])''
Riga 194: Riga 196:
 
  <FONT color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 
  <FONT color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 
  ' ''Sets the state of the element.''</font>
 
  ' ''Sets the state of the element.''</font>
  Private Extern gst_element_set_state(gstobject As Pointer, state As Integer) As Integer
+
  Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer
 +
 +
<FONT color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 +
' ''Queries an element for the total stream duration in nanoseconds.''</font>
 +
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean
 +
 +
<FONT color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 +
' ''Queries an element for the stream position in nanoseconds.''</font>
 +
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''void gst_object_unref(gpointer object)''
 
  <FONT color=gray>' ''void gst_object_unref(gpointer object)''
Riga 201: Riga 211:
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 +
 +
  gst_init(0, 0)
 +
 +
  With tempus = New Timer As "Tempus"
 +
    .Delay = 70
 +
  End With
 +
 
 +
End
 
   
 
   
  Dim fileaudio as string
 
 
   
 
   
  gst_init(0, Null)
+
Public Sub Button1_Click()   <FONT color=gray>' ''Avvia la riproduzione del file mediale''</font>
 
   
 
   
  play = gst_element_factory_make("playbin", "Riproduzione")
+
  Dim fileaudio as string
 
   
 
   
  fileaudio = "<FONT color=gray>''/percorso/del/file/audio''</font>"
+
  elem = gst_element_factory_make("playbin", "Riproduzione")
 
   
 
   
  g_object_set(play, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
+
  fileaudio = "<FONT color=darkgreen>''/percorso/del/file/audio''</font>"
 
   
 
   
 +
  g_object_set(elem, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
 +
   
 
  <FONT color=gray>' ''Avviamo la riproduzione audio:''</font>
 
  <FONT color=gray>' ''Avviamo la riproduzione audio:''</font>
  gst_element_set_state(play, GST_STATE_PLAYING)
+
  gst_element_set_state(elem, GST_STATE_PLAYING)
 +
 +
  tempus.Start
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Button1_Click()   <FONT color=gray>' ''Arrestiamo la riproduzione audio''</font>
+
  Public Sub Button2_Click()   <FONT color=gray>' ''Arresta la riproduzione del file mediale''</font>
 
   
 
   
   Dim rit As Integer
+
   tempus.Stop
    
+
 
  rit = gst_element_set_state(play, GST_STATE_NULL)
+
   gst_element_set_state(elem, GST_STATE_NULL)
  Print "Stato di cambiamento = "; rit
 
 
      
 
      
  gst_object_unref(play)
+
  gst_object_unref(elem)
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub ToggleButton1_Click()  <FONT color=gray>' ''Poniamo in pausa e riprendiamo la riproduzione audio''</font>
+
  Public Sub ToggleButton1_Click()  <FONT color=gray>' ''Pone in pausa e riprende la riproduzione del file mediale''</font>
 
   
 
   
   Dim rit As Integer
+
   If ToggleButton1.Value Then
 +
    tempus.Stop
 +
    gst_element_set_state(elem, GST_STATE_PAUSED)
 +
  Else
 +
    gst_element_set_state(elem, GST_STATE_PLAYING)
 +
    tempus.Start
 +
  Endif
 +
   
 +
End
 
   
 
   
  If ToggleButton1.Value Then
 
    rit = gst_element_set_state(play, GST_STATE_PAUSED)
 
  Else
 
    rit = gst_element_set_state(play, GST_STATE_PLAYING)
 
  Endif
 
 
   
 
   
   Print "Stato di cambiamento = "; rit
+
Public Sub Tempus_Timer()
 +
 
 +
  Dim positio, durata As Long
 +
 
 +
  gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
 +
 
 +
  gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(positio))
 +
    
 +
  Write #File.Out, "\rDurata: " & Time(0, 0, 0, durata / 1000000) & "  -  Posizione: " & Time(0, 0, 0, positio / 1000000)
 +
 
 +
  If (positio > 0) And (durata = positio) Then
 +
    tempus.Stop
 +
    gst_element_set_state(elem, GST_STATE_NULL)
 +
    gst_object_unref(elem)
 +
  Endif
 
   
 
   
  '''End'''
+
  End
  
  
 
+
===Esempio con applicazione in ambiente grafico usando la funzione ''Wait''===
Quest'altro esempio, invece, prevede un'applicazione ''a riga di comando''. Saranno mostrati anche la durata del brano e la posizione temporale corrente durante l'esecuzione:
+
Mostriamo di seguito un esempio pratico e funzionante di un'applicazione in ambiente grafico che fa uso della funzione ''Wait'' per consentire l'estrazione della durata totale e del tempo trascorso di esecuzione del file mediale:
  Library "libgstreamer-1.0"
+
Private elem As Pointer
 +
Private v As Boolean
 +
 +
 +
  Library "libgstreamer-1.0:0.2407.0"
 
   
 
   
  Private Const GST_STATE_NULL As Integer = 1
+
  Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
  Private Const GST_FORMAT_TIME As Integer = 3
+
  Private GST_FORMAT_TIME As Integer = 3
Private Const GST_STATE_PLAYING As Integer = 4
 
 
   
 
   
 
  <FONT color=gray>' ''gst_init (int *argc, char **argv[])''
 
  <FONT color=gray>' ''gst_init (int *argc, char **argv[])''
Riga 276: Riga 316:
 
  <FONT color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 
  <FONT color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 
  ' ''Queries an element for the total stream duration in nanoseconds.''</font>
 
  ' ''Queries an element for the total stream duration in nanoseconds.''</font>
  Private Extern gst_element_query_duration(gstelement As Pointer, GstFormat As Pointer, duration As Pointer) As Boolean
+
  Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 
  <FONT color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 
  ' ''Queries an element for the stream position in nanoseconds.''</font>
 
  ' ''Queries an element for the stream position in nanoseconds.''</font>
  Private Extern gst_element_query_position(gstelement As Pointer, GstFormat As Pointer, cur As Pointer) As Boolean
+
  Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''void gst_object_unref(gpointer object)''
 
  <FONT color=gray>' ''void gst_object_unref(gpointer object)''
Riga 287: Riga 327:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Form_Open()
 +
 +
  gst_init(0, 0)
 +
     
 +
End
 +
 +
 +
Public Sub Button1_Click()  <FONT color=gray>' ''Avvia la riproduzione del file mediale''</font>
 
   
 
   
  Dim play As Pointer
 
 
   Dim fileaudio as string
 
   Dim fileaudio as string
   Dim posizione, durata As Long
+
   Dim durata As Long = 1
 +
  Dim positio As Long
 +
 
 +
  elem = gst_element_factory_make("playbin", "Riproduzione")
 +
 +
  fileaudio = "<FONT color=darkgreen>''/percorso/del/file/audio''</font>"
 +
 +
  g_object_set(elem, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
 +
   
 +
<FONT color=gray>' ''Avviamo la riproduzione audio:''</font>
 +
  gst_element_set_state(elem, GST_STATE_PLAYING)
 +
 
 +
  v = False
 +
 
 +
  While (positio < durata) And (v = False)
 +
    Wait 0.01
 +
    gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
 +
    gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(positio))
 +
    Write #File.Out, "\rDurata: " & Time(0, 0, 0, durata / 1000000) & "  -  Posizione: " & Time(0, 0, 0, positio / 1000000)
 +
  Wend
 +
 
 +
  gst_element_set_state(elem, GST_STATE_NULL)
 +
 
 +
  gst_object_unref(elem)
 +
 
 +
End
 +
 +
 +
Public Sub Button2_Click()  <FONT color=gray>' ''Arresta la riproduzione del file mediale''</font>
 +
 +
  v = True
 +
 +
End
 +
 +
 +
Public Sub ToggleButton1_Click()  <FONT color=gray>' ''Pone in pausa e riprende la riproduzione del file mediale''</font>
 +
   
 +
  If ToggleButton1.Value Then
 +
    gst_element_set_state(elem, GST_STATE_PAUSED)
 +
  Else
 +
    gst_element_set_state(elem, GST_STATE_PLAYING)
 +
  Endif
 +
 
 +
End
 +
 
 +
 
 +
===Esempio con applicazione ''a riga di comando''===
 +
Mostriamo di seguito un esempio pratico e funzionante di un'applicazione ''a riga di comando'':
 +
Library "libgstreamer-1.0:0.2407.0"
 +
 +
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
 +
Private Const GST_FORMAT_TIME As Integer = 3
 +
 +
<FONT color=gray>' ''gst_init (int *argc, char **argv[])''
 +
' ''Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.''</font>
 +
Private Extern gst_init(argc As Pointer, argv As Pointer)
 +
 +
<FONT color=gray>' ''GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)''
 +
' ''Create a new element of the type defined by the given element factory.''</font>
 +
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer
 +
 +
<FONT color=gray>' ''gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)''
 +
' ''Converts an absolute filename to an escaped ASCII-encoded URI.''</font>
 +
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String
 +
 +
<FONT color=gray>' ''void g_object_set(gpointer object, const gchar *first_property_name, ...)''
 +
' ''Sets properties on an object.''</font>
 +
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)
 +
 +
<FONT color=gray>' ''void g_object_set(gpointer object, const gchar *first_property_name, ...)''
 +
' ''Sets properties on an object.''</font>
 +
Private Extern g_object_set_Volume(gobject As Pointer, key As String, value As Float, tertium As String) Exec "g_object_set"
 +
 +
<FONT color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 +
' ''Sets the state of the element.''</font>
 +
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer
 +
 +
<FONT color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 +
' ''Queries an element for the total stream duration in nanoseconds.''</font>
 +
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean
 
   
 
   
  gst_init(0, Null)
+
<FONT color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 +
' ''Queries an element for the total stream position in nanoseconds.''</font>
 +
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
   
 
   
  play = gst_element_factory_make("playbin", "audio")
+
<FONT color=gray>' ''void gst_object_unref(gpointer object)''
 +
' ''Decrements the reference count on object .''</font>
 +
Private Extern gst_object_unref(gobject As Pointer)
 
   
 
   
  fileaudio = "<FONT color=gray>''/percorso/del/file/audio''</font>"
 
 
   
 
   
  g_object_set(play, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
+
Public Sub Main()
 
   
 
   
  <FONT color=gray>' ''Avviamo la riproduzione audio:''</font>
+
  Dim elem As Pointer
  gst_element_set_state(play, GST_STATE_PLAYING)
+
  Dim fileaudio as string
 +
  Dim durata, pos As Long
 +
  Dim volume As Float
 +
 
 +
  gst_init(0, 0)
 +
 +
  elem = gst_element_factory_make("playbin", "riproduzione")
 +
 +
  fileaudio = "<FONT color=darkgreen>''/percorso/del/file/audio''</font>"
 +
 +
  g_object_set(elem, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
 +
 
 +
<FONT color=gray>' ''Imposta il valore del volume (da 0.0 a 1.0) di esecuzione:''</font>
 +
  volume = 0.7
 +
  g_object_set_Volume(elem, "volume", volume, Null)
 +
 
 +
  <FONT color=gray>' ''Avvia la riproduzione audio:''</font>
 +
  gst_element_set_state(elem, GST_STATE_PLAYING)
 
    
 
    
  While (posizione = 0) Or (durata > posizione)
+
  Repeat
    gst_element_query_duration(play, GST_FORMAT_TIME, VarPtr(durata))
+
    gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
    gst_element_query_position(play, GST_FORMAT_TIME, VarPtr(posizione))
+
    Wait 0.01
    Write #File.Out, "\rDurata: " & Date(0, 0, 0, 0, 0, 0, durata / 1000000) & "      Pos. " & Date(0, 0, 0, 0, 0, 0, posizione / 1000000)
+
  Until durata > -1
  Wend
+
 +
  Repeat
 +
    gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(pos))
 +
    Write "\r\e[0mDurata: " & Time(0, 0, 0, durata / 1000000) & "      Pos. \e[31m" & Time(0, 0, 0, pos / 1000000)
 +
    Wait 0.001
 +
  Until pos >= durata
 
      
 
      
  gst_object_unref(play)
+
  gst_object_unref(elem)
 +
  Print "\nEsecuzione terminata."
 
    
 
    
  '''End'''
+
  End
 +
 
 +
 
 +
=La gestione dei dati audio con GStreamer mediante una ''Pipeline'' di elementi=
 +
Gstreamer fornisce una potente struttura per consentire agli utenti esperti di gestire flussi audio e video in modi estremamente flessibili.
 +
 
 +
Gstreamer con tutti i codec abilitati supporta un'enorme varietà di formati di file.
 +
 
 +
Per creare e gestire "Pipeline" personalizzate di plugin media, è possibile utilizzare il programma integrato "gst-launch" (e più precisamente ''gst-launch-1.0'').
 +
<BR>Il formato generale di "Pipeline" di GStreamer da utilizzare è il seguente:
 +
gst-launch-1.0 -v xxxsrc ! xxxdemuxer ! xxxdecoder ! xxxprocessing ! xxxencoding ! xxxmux ! xxxsink
 +
 
 +
Invece nel codice la corrispondente funzione specifica di Gstreamer è la seguente:
 +
GstElement * gst_parse_launch (const gchar *pipeline_description, GError **error)
 +
Facciamo un elenco di questi plugin in ordine:
 +
 
 +
'''xxxsrc''': un sorgente di dati audio, da cui provengono i dati di input originari. Un plugin specifico al riguardo è, ad esempio, è "''filesrc location = /...''", che legge i dati da un file.
 +
 
 +
'''xxxdemuxer''': un ''demuxer'' - la maggior parte, ma non tutti, i media vengono commutati e miscelati in una sorta di formato contenitore. Ad esempio, si può avere l'audio Ogg/Vorbis e il video Ogg/Theora messi insieme in un contenitore Matroska (mkv). Il demuxer "rimuove" il contenitore, rendendo disponibili i suoi flussi interni di dati, che sono ancora codificati.
 +
 
 +
'''xxxdecoder''': un decodificatore - questo è, ad esempio, un decodificatore Vorbis o un decodificatore Theora. È possibile utilizzare lo strumento integrato "''gst-inspect''" per ottenere un elenco di elementi plug-in disponibili e per esaminare le proprietà dei singoli elementi.
 +
 
 +
'''xxxprocessing''': in generale, dopo aver decodificato i dati di input codificati (audio, video o entrambi) in un tipo di dati non elaborati (che è fondamentalmente un flusso di numeri interi o numeri in virgola mobile, ad esempio uno dei tipi di dati non elaborati audio è PCM ), è possibile eseguire alcune elaborazioni su di esso. L'elaborazione può essere necessaria per cambiarne gli aspetti (modificare la frequenza di campionamento, la risoluzione del video, FPS, ecc.) O potrebbe essere necessario per soddisfare i requisiti degli elementi più avanti lungo la pipeline.
 +
 
 +
'''xxxencoding''': in generale, dopo aver decodificato ed elaborato i dati grezzi, è necessario codificare i dati non elaborati (audio, video o entrambi) in un formato compresso, indipendentemente dalla compressione senza perdita come l'audio FLAC (per la migliore qualità), o compressione con perdita come MP3 o H264 (per la migliore dimensione del file).
 +
 
 +
'''xxxmux''': a questo punto che si è in possesso dei bit codificati grezzi nel loro formato compresso, è necessario metterli in una sorta di contenitore. I contenitori sono molto utili, perché possono contenere metadati, come "Titolo", "Autore", "Copyright", "Album", "Anno", ecc., nonché informazioni su quali codec audio e video sono stati usati per codificare i dati . Il Muxer facilita anche il missaggio e l'abbinamento di vari formati di dati. Ci sono alcuni formati di contenitori che sono estremamente flessibili e permettono di comprimere quasi tutti i formati codificati; Matroska è uno di questi esempi, dove è possibile teoricamente mettere l'audio Ogg/Vorbis e il video H264, o il video VP8 e l'audio FLAC. Le possibilità sono tantissime.
 +
 
 +
'''xxxsink''': questa è la destinazione finale del flusso di dati e della ''Pipeline''. Se si effettua la conversione da un file a un altro file, quasi sempre si utilizzerà il plug-in "''filesink location = /...." .
 +
 
 +
====Esempio pratico====
 +
Qualche esempio pratico di utilizzo della funzione esterna "gst_parse_launch()" di GStreamer, può essere visto alla seguente pagina:
 +
* [[Eseguire un file audio usando una linea di pipeline con la funzione 'gst parse launch()']]

Versione attuale delle 14:23, 2 set 2024

Per gestire i dati, al fine di ottenere il risultato ed il fine desiderato: esecuzione sonora, video o altro, bisognerà utilizzare specifiche funzioni, anche finalizzate alla creazione ed all'uso delle funzionalità degli Elementi di GStreamer.


Impostare un Elemento per la gestione del flusso dei dati

Un Elemento è la Classe di oggetti più importante in GStreamer. Esso svolge una determinata funzione, ed è utilizzato per gestire il flusso di dati, come ad esempio lettura, decodifica ed invio dei medesimi alla scheda audio. Di solito si crea una catena di Elementi collegati insieme (Pipeline) e si lascia che i dati passino attraverso questa catena di Elementi. In tal modo è possibile sfruttare le loro funzionalità ed ottenere gli obiettivi multimediali desiderati (come ad esempio la riproduzione audio).

Il modo più semplice per creare un Elemento è utilizzare la funzione:

GstElement * gst_element_factory_make(const gchar *factoryname, const gchar *name)

alla quale si passa il nome di un Elemento fra quelli predisposti da GStreamer ed una denominazione per l'Elemento appena creato. È possibile passare NULL come argomento name per ottenere un unico nome predefinito.
Quando un Elemento viene creato, esso assume un riferimento numerico pari ad un'unità pari al numero di elementi in quel momento creati. Così se ad esempio il nuovo Elemento creato è il secondo, esso assumerà un riferimento numerico uguale a 2.
Detta funzione restituisce una variabile di tipo Puntatore al nuovo Elemento creato, che sarà utilizzata per richiamare appunto quell'Elemento.
Il nuovo Elemento creato con un nome previsto da GStreamer è in grado di gestire solitamente file audio e video, nonché, a seconda dell'Elemento richiamato, altre determinate caratteristiche.
In Gambas dichiareremo la funzione nel seguente modo:

Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer

e la richiameremo in routine ad esempio così:

Private elem As Pointer

Public Sub ......()

 elem = gst_element_factory_make("playbin", "esegui")
......


Eliminare un Elemento

Per eliminare un Elemento, precedentemente creato, si utilizza la funzione:

void gst_object_unref(gpointer object)

alla quale va passata la variabile di tipo Pointer che punta all'Elemento creato.
La distruzione dell'Elemento determina il decremento del riferimento numerico di un'unità.
In Gambas la funzione sarà così dichiarata:

Private Extern gst_object_unref(object As Pointer)

e sarà richiamata in routine ad esempio così:

gst_object_unref(elem)


Impostare lo stato di un Elemento

Per impostare un particolare stato di un Elemento, si utilizzerà la funzione:

GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)

La funzione può ritornare uno dei seguenti valori:

  • GST_STATE_CHANGE_FAILURE, uguale a 0, se l'ultimo stato di cambiamento è fallito;
  • GST_STATE_CHANGE_SUCCESS, uguale a 1, se l'Elemento non ha stato più attesa e l'ultimo cambiamento di stato è riuscito;
  • GST_STATE_CHANGE_ASYNC, uguale a 2, se l'Elemento sta ancora eseguendo un cambiamento di stato;
  • GST_STATE_CHANGE_NO_PREROLL, uguale a 3, se il cambiamento di stato è riuscito, ma l'Elemento non è in grado di produrre i dati in GST_STATE_PAUSED.

La funzione in Gambas sarà così dichiarata:

Private Extern gst_element_set_state(gstobject As Pointer, state As Integer) As Integer

Variando il parametro state, si varierà lo stato dell'Elemento di GStreamer. I possibili valori di stato di un Elemento sono:

  • GST_STATE_VOID_PENDING = 0 ' nessuno stato sospeso
  • GST_STATE_NULL = 1 ' lo stato con valore Null o lo stato iniziale di un "Elemento"
  • GST_STATE_READY = 2 ' l'Elemento è "pronto" per essere posto in pausa
  • GST_STATE_PAUSED = 3 ' l'Elemento è in "pausa"
  • GST_STATE_PLAYING = 4 ' l'Elemento sta eseguendo i dati che fluiscono


Impostare lo stato per la Riproduzione di un flusso di dati

Per poter ottenere la riproduzione di un flusso di dati, ad esempio caricati da un file audio, si imposterà il parametro state con la costante GST_STATE_PLAYING di GStreamer, che equivale al valore 4. Pertanto la predetta funzione sarà in routine impostata:

Private Const GST_STATE_PLAYING As Integer = 4

Public Sub ......()

gst_element_set_state(elem, GST_STATE_PLAYING)
......

Richiamata detta funzione, si avrà la riproduzione audio dei dati caricati.


Caricare un file da gestire

Per far gestire (ad esempio farlo eseguire) un file audio, è necessario attribuire detto file come proprietà all'Elemento creato. Si utilizzerà la seguente funzione esterna:

void g_object_set(gpointer object, const gchar *first_property_name, const gchar *value, Null)

laddove in particolare la varibile di tipo Puntatore *value conterrà il percorso del file da gestire.
In Gambas detta funzione sarà così dichiarata:

Private Extern g_object_set(object As Pointer, nomeProprietà As String, value As String, nl As String)

Va precisato che il nom del file va passato con la codifica della Universal Resource Identifiers (URIs). Per trasformare un ordinario indirizzo del file nella sua codifica URI, potremo servirci della funzione esterna:

gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)

che dichiareremo come segue:

Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String

Pertanto avremo in routine ad esempio:

Dim percorsoFile As String

 percorsoFile = Dialog.Path

 g_object_set(elem, "nome", g_filename_to_uri(percorsoFile, Null, 0), Null)


Conoscere la durata del flusso di dati da eseguire

Per conoscere la durata del flusso di dati da eseguire, ad esempio la durata di un brano audio, si utilizzerà la funzione esterna:

gboolean gst_element_query_duration(GstElement *element, GstFormat format, gint64 *duration)

laddove il parametro format è un intero che può assumere uno dei seguenti valori da impostare preventivamente a seconda del bisogno:

  • GST_FORMAT_UNDEFINED = 0 ' formato indefinito
  • GST_FORMAT_DEFAULT = 1 ' il formato di default dell'lemento, che può essere in campioni per l'audio, fotogrammi per il video
  • GST_FORMAT_BYTES = 2 ' byte
  • GST_FORMAT_TIME = 3 ' nanosecondi
  • GST_FORMAT_BUFFERS = 4 ' buffer
  • GST_FORMAT_PERCENT = 5 ' percentuale di dati

Il parametro duration è la variabile di tipo Pointer nella quale viene immagazzinata la durata complessiva. Parametro per i ritorni derivanti. Il default è il trasferimento completo. Può assumere il valore 0.
La funzione ritorna un valore booleano True se l'interrogazione, al fine di conoscere la durata dei dati, può essere effettuata. In Gambas questa funzione sarà così dichiarata:

Private Extern gst_element_query_duration(gselement As Pointer, formatI As Integer, duration As Pointer) As Boolean

e sarà richiamata in routine ad esempio così:

Dim Dim GST_FORMAT_TIME As Integer = 3
Dim durata As Long

 gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
 
 Print durata


Conoscere durante l'esecuzione la posizione nel flusso dei dati

Per conoscere la posizione corrente all'interno dei dati da processare, si farà uso della funzione esterna:

gboolean gst_element_query_position(GstElement *element, GstFormat format, gint64 *cur)

laddove il parametro format è un intero che può assumere uno dei seguenti valori da impostare preventivamente a seconda del bisogno:

  • GST_FORMAT_UNDEFINED = 0 ' formato indefinito
  • GST_FORMAT_DEFAULT = 1 ' il formato di default dell'lemento, che può essere in campioni per l'audio, fotogrammi per il video
  • GST_FORMAT_BYTES = 2 ' byte
  • GST_FORMAT_TIME = 3 ' nanosecondi
  • GST_FORMAT_BUFFERS = 4 ' buffer
  • GST_FORMAT_PERCENT = 5 ' percentuale di dati

Il parametro cur è la variabile di tipo Pointer nella quale viene immagazzinata la posizione corrente.
La funzione ritorna un valore booleano True se l'interrogazione, al fine di conoscere la durata dei dati, può essere effettuata. In Gambas questa funzione sarà così dichiarata:

Private Extern gst_element_query_position(gselement As Pointer, formatI As Integer, cur As Pointer) As Boolean

e sarà richiamata in routine ad esempio così:

Dim GST_FORMAT_TIME As Integer = 3
Dim pos As Long

 gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(pos))

 Print pos


Conocere lo stato dell'Elemento

Per conoscere lo stato corrente di un Elemento, si utilizzerà la funzione esterna:

GstStateChangeReturn gst_element_get_state(GstElement *element, GstState *state, GstState *pending, GstClockTime timeout)

laddove il parametro state è una variabile di tipo Pointer che punta alla zona di memoria, nella quale è contenuto il valore dello stato corrente dell'Elemento. La funzione può ritornare uno dei seguenti valori:

  • GST_STATE_CHANGE_FAILURE, uguale a 0, se l'ultimo stato di cambiamento è fallito;
  • GST_STATE_CHANGE_SUCCESS, uguale a 1, se l'elemento non ha stato più attesa e l'ultimo cambiamento di stato è riuscito;
  • GST_STATE_CHANGE_ASYNC, uguale a 2, se l'elemento sta ancora eseguendo un cambiamento di stato.

Per gli elementi che non ritornano il valore GST_STATE_CHANGE_ASYNC, questa funzione restituisce immediatamente lo stato attuale e in sospeso.
In Gambas questa funzione sarà così dichiarata:

Private Extern gst_element_get_state(gstobject As Pointer, stateP As Pointer, pendingP As Pointer, timeLout As Long) As Integer

e sarà richiamata in routine ad esempio così:

Dim state, pending As Pointer
Dim timeout As Long

 state = Alloc(SizeOf(gb.Byte), 4)
 pending = Alloc(SizeOf(gb.Byte), 4)

 gst_element_get_state(player, state, pending, timeout)

 Print Int@(state)


Termine e chiusura di GStreamer

Nel caso in cui si intendano chiudere o comunque interrompere le risorse di GStreamer, ad esempio quando si procede alla chiusura del programma, è buona abitudine effettuare la chiusura mediante la funzione:

void gst_object_unref(gpointer object)

precedentementre vista, che eliminerà l'Elemento; nonché la funzione:

GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)

anche questa precedentementre vista, alla quale in Gambas attribuiremo il secondo parametro a Null:

gst_element_set_state(elem, GST_STATE_NULL)


Riassunto essenziale per la Riproduzione audio

In conclusione possiamo dire che bastano solo poche funzioni esterne del API di GStreamer per effettuare la riproduzione di un file audio.

Riportiamo alcuni esempi con applicazioni in ambiente grafico ed applicazione a riga di comando.


Esempio con applicazione in ambiente grafico usando la Classe Timer

Mostriamo di seguito un esempio pratico e funzionante di un'applicazione in ambiente grafico che fa uso della la Classe Timer per consentire l'estrazione della durata totale e del tempo trascorso di esecuzione del file mediale:

Private elem As Pointer
Private tempus As Timer


Library "libgstreamer-1.0:0.2407.0"

Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
Private GST_FORMAT_TIME As Integer = 3

' gst_init (int *argc, char **argv[])
' Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Private Extern gst_init(argc As Pointer, argv As Pointer)

' GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)
' Create a new element of the type defined by the given element factory.
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer

' gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)
' Converts an absolute filename to an escaped ASCII-encoded URI.
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String

' void g_object_set(gpointer object, const gchar *first_property_name, ...)
' Sets properties on an object.
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)

' GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)
' Sets the state of the element.
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer

' gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)
' Queries an element for the total stream duration in nanoseconds.
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean

' gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)
' Queries an element for the stream position in nanoseconds.
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean

' void gst_object_unref(gpointer object)
' Decrements the reference count on object .
Private Extern gst_object_unref(gobject As Pointer)


Public Sub Form_Open()

 gst_init(0, 0)

 With tempus = New Timer As "Tempus"
   .Delay = 70
 End With
  
End


Public Sub Button1_Click()   ' Avvia la riproduzione del file mediale

 Dim fileaudio as string

 elem = gst_element_factory_make("playbin", "Riproduzione")

 fileaudio = "/percorso/del/file/audio"

 g_object_set(elem, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
   
' Avviamo la riproduzione audio:
 gst_element_set_state(elem, GST_STATE_PLAYING)

 tempus.Start
 
End


Public Sub Button2_Click()   ' Arresta la riproduzione del file mediale

 tempus.Stop
  
 gst_element_set_state(elem, GST_STATE_NULL)
   
 gst_object_unref(elem)

End


Public Sub ToggleButton1_Click()   ' Pone in pausa e riprende la riproduzione del file mediale

 If ToggleButton1.Value Then
   tempus.Stop
   gst_element_set_state(elem, GST_STATE_PAUSED)
 Else
   gst_element_set_state(elem, GST_STATE_PLAYING)
   tempus.Start
 Endif
   
End


Public Sub Tempus_Timer()
 
 Dim positio, durata As Long
 
 gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
 
 gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(positio))
  
 Write #File.Out, "\rDurata: " & Time(0, 0, 0, durata / 1000000) & "  -   Posizione: " & Time(0, 0, 0, positio / 1000000)
  
 If (positio > 0) And (durata = positio) Then
   tempus.Stop
   gst_element_set_state(elem, GST_STATE_NULL)
   gst_object_unref(elem)
 Endif

End


Esempio con applicazione in ambiente grafico usando la funzione Wait

Mostriamo di seguito un esempio pratico e funzionante di un'applicazione in ambiente grafico che fa uso della funzione Wait per consentire l'estrazione della durata totale e del tempo trascorso di esecuzione del file mediale:

Private elem As Pointer
Private v As Boolean


Library "libgstreamer-1.0:0.2407.0"

Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
Private GST_FORMAT_TIME As Integer = 3

' gst_init (int *argc, char **argv[])
' Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Private Extern gst_init(argc As Pointer, argv As Pointer)

' GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)
' Create a new element of the type defined by the given element factory.
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer

' gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)
' Converts an absolute filename to an escaped ASCII-encoded URI.
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String

' void g_object_set(gpointer object, const gchar *first_property_name, ...)
' Sets properties on an object.
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)

' GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)
' Sets the state of the element.
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer

' gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)
' Queries an element for the total stream duration in nanoseconds.
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean

' gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)
' Queries an element for the stream position in nanoseconds.
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean

' void gst_object_unref(gpointer object)
' Decrements the reference count on object .
Private Extern gst_object_unref(gobject As Pointer)


Public Sub Form_Open()

 gst_init(0, 0)
     
End


Public Sub Button1_Click()   ' Avvia la riproduzione del file mediale

 Dim fileaudio as string
 Dim durata As Long = 1
 Dim positio As Long
  
 elem = gst_element_factory_make("playbin", "Riproduzione")

 fileaudio = "/percorso/del/file/audio"

 g_object_set(elem, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
   
' Avviamo la riproduzione audio:
 gst_element_set_state(elem, GST_STATE_PLAYING)
  
 v = False
  
 While (positio < durata) And (v = False)
   Wait 0.01
   gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
   gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(positio))
   Write #File.Out, "\rDurata: " & Time(0, 0, 0, durata / 1000000) & "  -   Posizione: " & Time(0, 0, 0, positio / 1000000)
 Wend
  
 gst_element_set_state(elem, GST_STATE_NULL)
  
 gst_object_unref(elem)
  
End


Public Sub Button2_Click()   ' Arresta la riproduzione del file mediale

 v = True

End


Public Sub ToggleButton1_Click()   ' Pone in pausa e riprende la riproduzione del file mediale
   
 If ToggleButton1.Value Then
   gst_element_set_state(elem, GST_STATE_PAUSED)
 Else
   gst_element_set_state(elem, GST_STATE_PLAYING)
 Endif
  
End


Esempio con applicazione a riga di comando

Mostriamo di seguito un esempio pratico e funzionante di un'applicazione a riga di comando:

Library "libgstreamer-1.0:0.2407.0"

Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
Private Const GST_FORMAT_TIME As Integer = 3

' gst_init (int *argc, char **argv[])
' Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Private Extern gst_init(argc As Pointer, argv As Pointer)

' GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)
' Create a new element of the type defined by the given element factory.
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer

' gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)
' Converts an absolute filename to an escaped ASCII-encoded URI.
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String

' void g_object_set(gpointer object, const gchar *first_property_name, ...)
' Sets properties on an object.
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)

' void g_object_set(gpointer object, const gchar *first_property_name, ...)
' Sets properties on an object.
Private Extern g_object_set_Volume(gobject As Pointer, key As String, value As Float, tertium As String) Exec "g_object_set"

' GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)
' Sets the state of the element.
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer

' gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)
' Queries an element for the total stream duration in nanoseconds.
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean

' gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)
' Queries an element for the total stream position in nanoseconds.
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean

' void gst_object_unref(gpointer object)
' Decrements the reference count on object .
Private Extern gst_object_unref(gobject As Pointer)


Public Sub Main()

 Dim elem As Pointer
 Dim fileaudio as string
 Dim durata, pos As Long
 Dim volume As Float
 
 gst_init(0, 0)

 elem = gst_element_factory_make("playbin", "riproduzione")

 fileaudio = "/percorso/del/file/audio"

 g_object_set(elem, "uri", g_filename_to_uri(fileaudio, Null, 0), Null)
 
' Imposta il valore del volume (da 0.0 a 1.0) di esecuzione:
 volume = 0.7
 g_object_set_Volume(elem, "volume", volume, Null)
 
' Avvia la riproduzione audio:
 gst_element_set_state(elem, GST_STATE_PLAYING)
 
 Repeat
   gst_element_query_duration(elem, GST_FORMAT_TIME, VarPtr(durata))
   Wait 0.01
 Until durata > -1

 Repeat
   gst_element_query_position(elem, GST_FORMAT_TIME, VarPtr(pos))
   Write "\r\e[0mDurata: " & Time(0, 0, 0, durata / 1000000) & "      Pos. \e[31m" & Time(0, 0, 0, pos / 1000000)
   Wait 0.001
 Until pos >= durata
   
 gst_object_unref(elem)
 Print "\nEsecuzione terminata."
  
End


La gestione dei dati audio con GStreamer mediante una Pipeline di elementi

Gstreamer fornisce una potente struttura per consentire agli utenti esperti di gestire flussi audio e video in modi estremamente flessibili.

Gstreamer con tutti i codec abilitati supporta un'enorme varietà di formati di file.

Per creare e gestire "Pipeline" personalizzate di plugin media, è possibile utilizzare il programma integrato "gst-launch" (e più precisamente gst-launch-1.0).
Il formato generale di "Pipeline" di GStreamer da utilizzare è il seguente:

gst-launch-1.0 -v xxxsrc ! xxxdemuxer ! xxxdecoder ! xxxprocessing ! xxxencoding ! xxxmux ! xxxsink

Invece nel codice la corrispondente funzione specifica di Gstreamer è la seguente:

GstElement * gst_parse_launch (const gchar *pipeline_description, GError **error)

Facciamo un elenco di questi plugin in ordine:

xxxsrc: un sorgente di dati audio, da cui provengono i dati di input originari. Un plugin specifico al riguardo è, ad esempio, è "filesrc location = /...", che legge i dati da un file.

xxxdemuxer: un demuxer - la maggior parte, ma non tutti, i media vengono commutati e miscelati in una sorta di formato contenitore. Ad esempio, si può avere l'audio Ogg/Vorbis e il video Ogg/Theora messi insieme in un contenitore Matroska (mkv). Il demuxer "rimuove" il contenitore, rendendo disponibili i suoi flussi interni di dati, che sono ancora codificati.

xxxdecoder: un decodificatore - questo è, ad esempio, un decodificatore Vorbis o un decodificatore Theora. È possibile utilizzare lo strumento integrato "gst-inspect" per ottenere un elenco di elementi plug-in disponibili e per esaminare le proprietà dei singoli elementi.

xxxprocessing: in generale, dopo aver decodificato i dati di input codificati (audio, video o entrambi) in un tipo di dati non elaborati (che è fondamentalmente un flusso di numeri interi o numeri in virgola mobile, ad esempio uno dei tipi di dati non elaborati audio è PCM ), è possibile eseguire alcune elaborazioni su di esso. L'elaborazione può essere necessaria per cambiarne gli aspetti (modificare la frequenza di campionamento, la risoluzione del video, FPS, ecc.) O potrebbe essere necessario per soddisfare i requisiti degli elementi più avanti lungo la pipeline.

xxxencoding: in generale, dopo aver decodificato ed elaborato i dati grezzi, è necessario codificare i dati non elaborati (audio, video o entrambi) in un formato compresso, indipendentemente dalla compressione senza perdita come l'audio FLAC (per la migliore qualità), o compressione con perdita come MP3 o H264 (per la migliore dimensione del file).

xxxmux: a questo punto che si è in possesso dei bit codificati grezzi nel loro formato compresso, è necessario metterli in una sorta di contenitore. I contenitori sono molto utili, perché possono contenere metadati, come "Titolo", "Autore", "Copyright", "Album", "Anno", ecc., nonché informazioni su quali codec audio e video sono stati usati per codificare i dati . Il Muxer facilita anche il missaggio e l'abbinamento di vari formati di dati. Ci sono alcuni formati di contenitori che sono estremamente flessibili e permettono di comprimere quasi tutti i formati codificati; Matroska è uno di questi esempi, dove è possibile teoricamente mettere l'audio Ogg/Vorbis e il video H264, o il video VP8 e l'audio FLAC. Le possibilità sono tantissime.

xxxsink: questa è la destinazione finale del flusso di dati e della Pipeline. Se si effettua la conversione da un file a un altro file, quasi sempre si utilizzerà il plug-in "filesink location = /...." .

Esempio pratico

Qualche esempio pratico di utilizzo della funzione esterna "gst_parse_launch()" di GStreamer, può essere visto alla seguente pagina: