Negociación de Codec en FreeSWITCH 1.10

Como anunciado ayer, va el documento del curso de FreeSWITCH, modalidad MOOC, dedicado a la negociación de Codec en FreeSWITCH 1.10

----

Tercera Parte Negociación de Codec Audio en las llamadas

Cada llamada de voz que utilice el Codec G711, que es el formato nativo, no comprimido, utilizado por todas las compañías telefónicas, consuma entre 80 y 100 Kbps por cada dirección de la llamada mientras G729, que es uno de los Codec con el más alto nivel de compresión, 30 Kbps por dirección; de hecho es el más utilizado por su relación calidad audio/nivel de compresión.

Normalmente cada paquete del flujo media contiene 20ms de audio y es el empaquetado más utilizado porque garantiza una buena calidad audio en relación a perdida de paquetes y latencia aunque no siempre es la mejor solución ya que consuma más ancho de banda. En comunicaciones donde el ancho de banda representa un costo considerable, es mejor utilizar paquetes de audio entre 30 y 60ms y optar por Codec audio con un nivel de compresión más alto aunque haya que sacrificar algo en la calidad del audio de la llamada.

FreeSWITCH implementa muchos tipos de Codec audio, desde la calidad CD de Opus hasta la calidad más baja de los Codec audio con un alto nivel de compresión.

Para ver la lista de los Codec audio y video activados y disponibles de manera predefinida en FS:

freeswitch@sip10.voztovoice.net> show codec

Como acabamos de decir, G729 es el Codec más utilizado por su relación consumo de banda/calidad del audio; es bueno saber que G729 no puede transportar FAX y DTMF dentro del flujo audio y necesita una buena CPU para realizar la compresión descompresión en tiempo real. Hasta hace poco tiempo su código era propietario y para utilizarlo había que pagar un valor por cada canal adquirido. Desde el primero de enero del 2017 este Codec se ha vuelto royalty-free esto significa que para utilizarlo no hace falta pagar más regalías; de hecho existe ya la posibilidad de instalar una versión gratuita basada en la versión Open Source bcg729 de Belledonne Communications que son los mismos desarrolladores del SoftPhone Linphone. IMPORTANTE: Según los desarrolladores de FreeSWITCH la licencia de codec G729 de Belledonne (GPL) no es compatible con la licencia de uso de FS que es la MPL 1.1 pues aconsejan utilizar el codec solamente en entornos de laboratorio/aprendizaje.

cd /usr/src/

Se descarga el programa para la instalación de bcg729:

git clone https://github.com/xadhoom/mod_bcg729.git

se entra en la carpeta creada:

cd mod_bcg729/

nano Makefile

las dos lineas que siguen se modifican si no corresponden a las carpetas donde se encuentran los datos que necesita el programa para compilar y luego instalar el modulo en la ubicación correcta:

FS_INCLUDES=/usr/include/freeswitch

FS_MODULES=/usr/lib/freeswitch/mod

En nuestro caso las carpetas indicadas son las correctas pues no hace falta realizar cambios. Se cierra el archivo y se continua con:

make

por ultimo se instala el modulo:

make install

Ahora se modifica el archivo de configuración que contiene la lista de módulos que FS carga cuando se inicia:

nano /etc/freeswitch/autoload_configs/modules.conf.xml

se modifica esta linea (Linea 95):

<load module="mod_g729"/>

para que quede:

<load module="mod_bcg729"/>

Como estos cambios aplicarán solamente cuando se reinicie FS para aplicarlos en seguida, desde la consola de FreeSWITCH, primero se deshabilita el Codec G729 que viene con la instalación de FS:

freeswitch@sip10.voztovoice.net> unload mod_g729

y luego se carga el que se acaba de compilar:

freeswitch@sip10.voztovoice.net> load mod_bcg729

a partir de este momento el Codec audio G729 soportará transcoding. Para ver si aparece en la lista de Codec soportados:

freeswitch@sip10.voztovoice.net> show codec

Si queremos realizar una prueba, configuramos en un Softphone que soporta G729 solamente ese Codec (yo he usado Bria) y, por ejemplo, en X-Lite solamente el Codec OPUS. Luego tenemos que añadir el Codec a la lista de los ofrecidos para llamadas entrantes y salientes:

nano /etc/freeswitch/vars.xml

modificar estas dos lineas (Desde la linea 259):

<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,G722,PCMU,PCMA,VP8"/>

<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,G722,PCMU,PCMA,VP8"/>

para que queden:

<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G729,OPUS,G722,PCMU,PCMA,VP8"/>

<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=G729,OPUS,G722,PCMU,PCMA,VP8"/>

y a seguir añadir esta linea:

<X-PRE-PROCESS cmd="set" data="media_mix_inbound_outbound_codecs=true"/>

esto linea permitirá a FreeSWITCH negociar codec distintos por cada Pata de la llamada. Guardar los cambios y reiniciar los dos perfiles SIP:

fscli

freeswitch@sip10.voztovoice.net> sofia profile internal rescan

Reload XML [Success]

+OK scan complete

freeswitch@sip10.voztovoice.net> sofia profile external rescan

Reload XML [Success]

+OK scan complete

No hace falta recargar la configuración XML porque es implícita en el comando de rescan de los perfiles SIP.

Ya podemos realizar una llamada entre los dos Softphone; en SNGREP:

Ese es el flujo entre Bria y FS;

y ese el flujo entre FS y X-Lite.

Ahora pasamos a hablar de la negociación de Codec utilizada por FreeSWITCH. El objetivo de toda configuración de FreeSWITCH es evitar que FS tenga que realizar trancoding y resampling. El primero acontece cuando FS tiene que pasar el flujo audio de un Codec a otro antes de reenviarlo; esto porque los dos dispositivos están utilizando Codec audio distintos. El segundo acontece cuando en cada lado de la llamada se están utilizando el mismo Codec audio pero con una frecuencia de muestreo distinta. Estas dos operaciones son las más costosas en términos de CPU y es por eso, que en lo posible, se intentan evitar.

En general la negociación de Codec en FS funciona de la siguiente manera; primero FreeSWITCH compara los Codec audio ofrecidos por el dispositivo de la pata A de la llamada con la lista presente en la variable inbound-codec-prefs del perfil SIP que está utilizando. Una vez negociado el Codec con la pata A, FS negocia el Codec con la pata B utilizando la lista presente en la variable outbound-codec-prefs, del perfil SIP que se está utilizando, organizándola para que el Codec negociado con la pata-A sea el primero de la lista de los negociados con la pata B. Si entre FS y una de las dos patas de la llamada no hay por lo menos un Codec en común, la llamada será terminada:

X-Lite FS FS Bria

OPUS ----> <------ G729 OPUS G722 PCMU PCMA OPUS G729 G722 PCMU PCMA ---> <-- G729

OPUS G729

OPUS es el Codec utilizado en la primera pata de la llamada e indicado como primero de la lista de los ofrecidos en la segunda pata de la llamada.

Dicho esto, los dos parámetros más importantes para la negociación de Codec son:

  • early-negotation

  • late-negotation

Con el primer parámetro FS negocia los Codec con la segunda pata de la llamada basándose en los Codec negociados con la primera pata de la llamada. Con el segundo FS espera hasta conocer los Codec disponibles en la segunda pata de la llamada para decidir cuales utilizar en la primera.

De manera predefinida FreeSWITCH está configurado para utilizar el segundo parámetro; de hecho los perfiles SIP internal y external contienen esta misma linea:

<param name="inbound-late-negotiation" value="true"/>

Con este parámetro configurado en true, en el dialplan es posible utilizar una variable de canal, absolute_codec_string, donde es posible indicar que Codec se quiere utilizar en la llamada saliente. Un ejemplo:

nano /etc/freeswitch/dialplan/default/00_absolutecodecstring.xml

copiamos las siguientes linea:

<include>

<extension name="absolute_codec">

<condition field="destination_number" expression="^105$">

<action application="set" data="absolute_codec_string=PCMU@30i,OPUS@16000h"/>

<action application="conference" data="$1@default"/>

</condition>

</extension>

</include>

Los Codec negociados podrán ser o PCMU (ulaw) o OPUS: la i indica el empaquetado (30ms por paquete) y h la frecuencia de muestreo (16000). Se guardan los cambios y se recarga la configuración:

fscli -x reloadxml

Ahora si se desde la extensión 1000 se marca la extensión 105 con los siguientes Codec activados:

En la consola de FreeSWITCH aparecerá:

FS comparando los Codec presente en la variable absolute_codec_string con los Codec soportados por el Softphone verá que el canal empareja con dos (la lineas que terminan con ++++ is saved as a match) y al final escogerá el Codec con mejor calidad:

Esto demuestra que se han utilizado los valores presentes en la variable absolute_codec_string. Si se cuelga, se configura en el Softphone solamente el codec G722 y se vuelve a marcar, el resultado será:

La llamada no puede ser procesada porque en el Softphone no hay por lo menos un Codec compatible con los configurados en la variable absolute_codec_string.

Ahora hipotizamos que vamos a realizar una llamada entre extensiones pero no conocemos a priori que tipo de Codec soporta cada una de ellas y al mismo tiempo queremos evitar, en lo posible, cualquier tipo de transcodificación. En este caso la variable absolute_codec_string no sirve porque no podemos configurar la variable en el momento en que logramos conocer el Codec utilizado por el destinatario. En estos casos se utiliza la variable inherit_codec que justamente cumple esa tarea; dice a FreeSWITCH de crear automáticamente la variable absolute_codec_string indicando como valor el Codec utilizado por el destinatario de la llamada:

nano /etc/freeswitch/dialplan/default/00_inheritcodec.xml

<include>

<extension name="inherit_codec">

<condition field="destination_number" expression="^106$">

<action application="set" data="inherit_codec=true"/>

<action application="bridge" data="user/1001@${domain_name}"/>

</condition>

</extension>

</include>

fscli -x reloadxml

+OK [Success]

Ahora basta que los dos softphone tengan por lo menos un Codec Audio en común para que ese Codec sea el que se utilizará. Registramos las extensiones 1000 y 1001 con por lo menos un codec audio en común y luego desde la extensión 1000 marcamos 106:

En un primer momento FS negocia con la extensión 1000 el Codec G722 pero como la pata B de la llamada utiliza el Codec aLaw (extensión 1001), FreeSWITCH cambia el Codec negociado con la pata A también a aLaw. Este es el funcionamiento de la variable inherit_codec. Esto claramente porque el destinatario de la llamada no soporta OPUS.

Otra cosa que se puede hacer para limitar al máximo la transcodificación es ofrecer a la pata-B de la llamada solamente la lista de Codec negociados con la pata-A. Esto gracias a la variable ep_codec_string donde se almacenan los Codec negociados con la pata-A de la llamada:

nano /etc/freeswitch/dialplan/default/00_epcodecstring.xml

<include>

<extension name="ep_codec">

<condition field="destination_number" expression="^107$">

<action application="set" data="inherit_codec=true"/>

<action application="export" data="nolocal:absolute_codec_string=${ep_codec_string}"/>

<action application="bridge" data="user/1001@${domain_name}"/>

</condition>

</extension>

</include>

Alguna explicaciones:

  • la aplicación export permite utilizar el valor de la variable absolute_codec_string en todas las posibles patas-B de la llamada

  • la opción nolocal indica que el valor de la variable absolute_codec_string no aplicará a la pata-A de la llamada.

Se guardan los cambios y se recarga la configuración:

fscli -x reloadxml

+OK [Success]

Desde la extensión 1000 se marca 107 y se mira que pasa en SNGREP. FreeSWITCH negociará en la segunda pata de la llamada solamente los Codec ofrecidos por la pata-A:

----

En el documetno sigue una parte dedicada a las locuciones audio y la musica en espera que no es parte de este tema.

Vota el Articulo: 

Sin votos (todavía)
Evalúa la calidad del articulo
Suscribirse a Comentarios de "Negociación de Codec en FreeSWITCH 1.10" Suscribirse a VozToVoice - Todos los comentarios