2011-01-02 14 views
2

Für eine VoIP-Sprachqualitätsüberwachungsanwendung muss ich einen eingehenden RTP-Audiostream mit einem Referenzsignal vergleichen. Für den Signalvergleich selbst verwende ich bereits existierende Spezialwerkzeuge. Für die anderen Teile (außer Paketerfassung) schien die Gstreamer-Bibliothek eine gute Wahl zu sein. Ich verwende die folgende Pipeline ein Barebone-VoIP-Client zu simulieren:Gstreamer: RTP-Jitter-Puffer funktioniert nicht richtig mit Paketverlust?

filesrc location=foobar.pcap ! pcapparse ! "application/x-rtp, payload=0, clock-rate=8000" 
    ! gstrtpjitterbuffer ! rtppcmudepay ! mulawdec ! audioconvert 
    ! audioresample ! wavenc ! filesink location=foobar.wav 

Die pcap-Datei enthält einen einzelnen Medienstrom RTP. Ich habe eine Capture-Datei erstellt, in der 50 der ursprünglichen 400 UDP-Datagramme fehlen. Für die gegebene Hörprobe (8s lang für mein Beispiel):

[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] 

mit einer bestimmten Menge von aufeinanderfolgenden Paketverlust ich ein Audiosignal wie dies erwarten würde ausgegeben werden (‚-‘ bezeichnet Schweigen):

[XXXXXXXXXXXXXXXXXXXXXXXX-----XXXXXXXXXXX] 

aber, was tatsächlich in der Audiodatei gespeichert ist dies (1 s für mein Beispiel kürzer):

[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] 

Es scheint, dass der Jitter-Buffer, ein entscheidender Teil für diese Anwendung ist funktioniert nicht richtig. Könnte das eine Inkompatibilität mit dem Element pcapparse sein? Fehle ich einen wichtigen Teil in der Pipeline, um die Zeitsynchronisation sicherzustellen? Was könnte das sonst noch verursachen?

Antwort

1

Das Problem könnte durch leichtes Verändern der Pipeline gelöst werden. Dies funktioniert jedoch nur, wenn audiorate die Paketverlust-Ereignisse empfängt. Dazu muss die do-lost Eigenschaft von gstjitterbuffer auf True gesetzt werden.

Hier ist die korrigierte Pipeline:

filesrc location=foobar.pcap ! pcapparse 
    ! "application/x-rtp, payload=0, clock-rate=8000" 
    ! gstrtpjitterbuffer do-lost=true ! rtppcmudepay ! mulawdec 
    ! audioconvert ! audioresample ! audiorate ! wavenc 
    ! filesink location=foobar.wav 
2

GStreamer kann einfach den Dejitter-Puffer verwenden, um die Pakete auf dem Weg zum (Audio-) Ausgang zu glätten. Dies wäre nicht ungewöhnlich, es ist die absolute Definition von Dejittering.

Es kann so weit gehen, um Out-of-Order-Pakete neu zu ordnen oder Duplikate zu löschen, aber die Verdeckung von Paketverlusten (Ihr Szenario) kann sehr komplex sein.

Grundlegende Implementierungen duplizieren nur das zuletzt empfangene Paket, während erweiterte Implementierungen den Ton der zuletzt empfangenen Pakete analysieren und rekonstruieren, um den Ton zu glätten.

Es klingt, als ob Ihre Anwendungsleistung von der genauen Implementierung der Verlustverschleierung abhängt. Selbst wenn GStreamer "etwas" tut, kann es schwer sein, die Auswirkungen auf Ihre Ergebnisse zu quantifizieren, es sei denn, Sie verstehen es sehr genau.

Vielleicht könnten Sie eine pcap mit ein paar Out-of-Order- und Duplikat-Paketen versuchen und prüfen, ob GStreamer sie zumindest neu anordnet/löscht, was zur Klärung der Vorgänge beitragen könnte. Ein audiorate Element muss, bevor wavenc hinzugefügt werden, dass „produces a perfect stream by inserting or dropping samples as needed“:

+0

ich mit einem nackten Knochen Lösung leben können, das heißt einfach oder ohne Verlust Verschleierung. Was hier falsch ist, ist die Playout-Zeit. Nach einer weiteren Untersuchung scheint es sich tatsächlich um ein Problem mit 'pcapparse' bzw. der Zeitsynchronisation zwischen' pcapparse' und 'rtppcmudepay' zu handeln. Wenn ich 'udpsrc' als Quellelement verwende, funktioniert alles wie erwartet. – paprika