Análisis del código fuente Rtcp
Palabras clave cliente/servidor; transmisión de vídeo en tiempo real; Divx
Introducción
La transmisión de vídeo en tiempo real dentro de LAN se ha utilizado ampliamente. Actualmente, la mayoría de las LAN utilizadas para transmitir video son LAN cableadas porque la tecnología de LAN cableada está madura, tiene una velocidad de transmisión rápida y tiene buena estabilidad. Sin embargo, debido a la gran cantidad de datos de vídeo, la red cableada también será inestable, lo que provocará congestión de datos y graves retrasos a largo plazo. Si el entorno de trabajo no es fijo y se requiere movilidad, se debe utilizar una red inalámbrica. Hoy en día, el funcionamiento de las tarjetas de red inalámbrica se vuelve inestable a medida que cambia el entorno, lo que provocará una disminución significativa en la calidad de la transmisión de vídeo y provocará fácilmente imágenes fantasma, fluctuaciones, pintura de pantalla y otros fenómenos. Este artículo propone una solución universal de transmisión de video en tiempo real para diferentes redes de área local y utiliza el paquete de desarrollo de software Windows VFW SDK encapsulado en VC ++ para el desarrollo secundario. De acuerdo con la estrategia de transmisión establecida, las imágenes fantasma de vídeo, la fluctuación y los problemas de visualización de la pantalla causados por la inestabilidad de la red local se pueden resolver de manera efectiva.
Problemas con la transmisión de video en tiempo real en LAN
Para transmitir secuencias de video de manera eficiente y con alta calidad en LAN, se requiere el soporte de múltiples tecnologías, incluida la compresión de video, codificación Tecnología y aplicaciones. Tecnología de control de calidad de capas, etc.
El ancho de banda de la red es limitado, por lo que las imágenes de vídeo deben comprimirse y transmitirse. MPEG-4 se usa ampliamente para la transmisión de video en tiempo real en entornos de red porque MPEG-4 tiene las siguientes ventajas: puede lograr una alta relación de compresión; la codificación flexible basada en objetos permite la interacción de objetos de video y audio; ;Tiene la ventaja de una fuerte tolerancia a fallos. Este artículo utiliza el códec Divx para codificar y comprimir vídeo. De hecho, Divx=(vídeo)MPEG-4+(audio)MP3.
La tecnología de control de calidad de la capa de aplicación ahora utiliza el protocolo RTP/RTCP para garantizar una transmisión de transmisiones de video de alta calidad y baja latencia en la red. El protocolo de transmisión de datos RTP es responsable de la transmisión y carga de datos de audio y video, y RTCP es responsable del control de transmisión de mensajes de datos RTP. Este protocolo retroalimenta el estado de la red a través del cliente (receptor) y el servidor (remitente) ajusta la velocidad y la tasa de compresión de la recopilación y transmisión de información. Sin embargo, la velocidad de adquisición de imágenes es fija y se requiere software para la compresión y descompresión. Ajustar la velocidad de adquisición hará que los datos recopilados se descarten antes de comprimirse. Ajustar la relación de compresión del codificador requiere restablecer los parámetros del codificador, reiniciar el codificador y ajustar el decodificador correspondiente. Este proceso lleva mucho tiempo y no puede cumplir con los requisitos en tiempo real. Por lo tanto, este artículo no utiliza el protocolo RTP/RTCP, sino que comienza desde el remitente, juzga el estado de la red en tiempo real y utiliza la estrategia "dejar de esperar" para la transmisión en tiempo real.
Existen dos protocolos para la comunicación de red: TCP y UDP. UDP es más adecuado para la transmisión de video en un entorno de red, pero no proporciona funciones de detección y corrección de errores. Una vez que se bloquea la red, se perderá una gran cantidad de información de datos. Para la tecnología de codificación y decodificación Divx, la codificación y decodificación se realizan en unidades de fotogramas, que se dividen en fotogramas clave y no clave. Durante el proceso de transmisión, debido a la alta relación de compresión, siempre que un bit en un cuadro sea incorrecto, afectará a cientos o incluso miles de otros bits, provocando directamente imágenes borrosas y caídas de pantalla. Sólo con la llegada del siguiente fotograma clave es posible restaurar la claridad de la imagen. Para garantizar la exactitud de la transmisión, necesito crear un protocolo en la capa de aplicación. De esta forma, las ventajas de UDP desaparecen. Por lo tanto, este artículo opta por utilizar TCP para la comunicación de red. El uso integral de la tecnología VFW y la tecnología de transmisión de medios, complementada con la estrategia de control de "detener y esperar", puede resolver mejor problemas como imágenes fantasma, fluctuaciones y visualización de pantalla que son propensos a la transmisión de video en tiempo real dentro de la LAN.
Implementación de transmisión de video en tiempo real
Para realizar la transmisión de video en tiempo real, la idea general es enviar la información menos redundante y enviar el video más reciente a los mejores. medida.
La transmisión de vídeo LAN en tiempo real adopta el modo servidor/cliente y se implementa con VC++. Su flujo de trabajo se muestra en la Figura 1.
Figura 1 Flujo de trabajo de transmisión de video en tiempo real
La captura de video utiliza AVICap para capturar imágenes de video desde la tarjeta de captura de video y luego obtiene cuadros de video de mapa de bits, que son comprimidos por el codificador Divx. . Los datos de video comprimidos se transmiten en tiempo real dentro de la LAN a través de Winsock, y los datos recibidos se envían al decodificador Divx para su descompresión y finalmente se logra la visualización del video.
VC++ utiliza tecnología VFW y el cliente registra la función de devolución de llamada a través de capSetCallbackOnFrame(). Cuando la tarjeta de captura captura una imagen, el sistema llamará automáticamente a la función de devolución de llamada y luego usará la función ICSeqCompressFrame () en la función de devolución de llamada para la compresión. Luego, los datos comprimidos se envían al servidor a través de Winsock. Después de que el servidor recibe un fotograma, se entrega a ICDecompress() para su descompresión y, finalmente, la imagen se muestra usando SetDIBitsToDevice().
1. Estructura del cuadro de video
Los datos recopilados por el video son un cuadro de video de mapa de bits, que el codificador Divx comprime para formar una secuencia Mpeg4-4 en formato de cuadro. El decodificador Divx también descomprime en formato de cuadro. Por lo tanto, se recomienda enviar el flujo de datos de vídeo en fotogramas. Para extraer fácilmente el marco en el extremo receptor, el marco se construye en el formato que se muestra en la Figura 2.
Indicador de inicio de fotograma
Marco de imagen
Número de fotograma
Tipo de fotograma
Datos del fotograma
Figura 2 Formato de fotograma de vídeo
Un fotograma completo consta de cinco campos. El significado de cada campo es el siguiente: bandera de inicio de fotograma, que marca el comienzo de un fotograma y ocupa 4 bytes de espacio. También podría configurarlo en 0xffffffff. El tamaño del marco indica el tamaño del marco completo, incluido el tamaño de 5 campos, que ocupa 4 bytes de espacio. El número de trama representa el número de secuencia de la trama y ocupa 4 bytes de espacio. El tipo de fotograma, que indica si el fotograma es un fotograma clave, ocupa 1 byte. Los datos del marco almacenan los datos completos del marco comprimido.
2. Envío de fotogramas de vídeo
Para lograr un rendimiento en tiempo real en la transmisión de vídeo en tiempo real, los datos comprimidos deben enviarse continuamente al extremo receptor. Así que cree un hilo en el extremo emisor específicamente para enviar datos. Al mismo tiempo, el proceso principal aún recopila datos y los comprime. El flujo de trabajo del hilo de envío se muestra en la Figura 3.
Figura 3 Flujo de trabajo del hilo de envío
Asumimos que el hilo creado se llama sendThread y el código central se implementa de la siguiente manera:
while(1)
{
isOK = true//listo
suspender hilo(enviar hilo);//suspender hilo
isOK = false/ /el hilo está en progreso Enviar datos
int length = frameLength//La longitud de los datos a enviar
if (length & lt50000) {//Determinar si los datos son normales .
int n = 0;
int enviar recuento = 0
mientras(longitud>0) {
n=enviar( calcetín, (char*)imageBuf+sendCount, length, 0); //Enviar datos,
//imageBuf es un puntero al marco de datos que se enviará.
If(n==SOCKET_ERROR) //Si ocurre una excepción en la red, salga del hilo.
Pausa;
Longitud-= n;
enviar recuento+= n;
}
}
}
El marco de datos enviado en el hilo es un marco de datos ensamblado de acuerdo con el método de la sección anterior. Este método garantiza que la trama actual que se envía llegue completamente al extremo receptor.
Tenga en cuenta que cuando se inicia este hilo o cada vez que se envía una trama, el hilo entrará en un estado suspendido, esperando a que el mundo exterior se despierte. Esta tarea se completa con la función de devolución de llamada. En la función de devolución de llamada, determine si el hilo de envío está listo (en estado suspendido), comprima la imagen y luego active el hilo para enviar los datos comprimidos; de lo contrario, salte y espere la siguiente llamada de la función de devolución de llamada.
Esta estrategia se denomina estrategia de "esperar y esperar" y se describirá en detalle más adelante.
3. Recibir fotogramas de vídeo
Para el receptor, lo más importante es extraer un fotograma completo del flujo de datos recibido. La idea del método es: primero encontrar el indicador de inicio del cuadro en el flujo de datos, luego extraer el tamaño del cuadro de los datos siguientes y luego leer los datos restantes del cuadro del búfer de recepción. Luego busque la marca de inicio del siguiente cuadro, y así sucesivamente. La Figura 4 es el flujo de trabajo del receptor.
De manera similar, el receptor crea un hilo dedicado a la recepción de datos. Suponemos que el nombre del hilo es recThread y que el código central se implementa de la siguiente manera:
while(temp!=socket_error)
{
if (! IsStart) {// Si los datos del marco comienzan, verdadero significa que comienzan.
if(endNum & gt; 3) //endNum registra los datos no procesados recibidos actualmente.
endNum = 0;
temp=recv(clisock, (char*)(recBuf+endNum), 1000, 0 //Leer datos del buffer
startPos = serchStr(temp+endNum); //Buscar el indicador de inicio del marco
If (startPos!=-1) {
isStart = true
endNum = temp+endNum-startPos-4;
memcpy(imageBuf, recBuf+startPos+4, endNum); //Guardar datos del cuadro
}
De lo contrario {
memcpy(recBuf, recBuf+temp+endNum-3, 3); //Guarda los últimos tres bytes de datos.
endNum = 3
}
}
si no {
if(endNum & lt; 4 ) {//Determine los datos inmediatamente después de la bandera de inicio. Si es menor que 4, significa que no se puede obtener el tamaño del marco.
temp=recv(clisock, (char*)(recBuf), 1000, 0); //Leer datos
memcpy(imageBuf+endNum, recBuf, temp);/ / Guardar datos
endNum+= temp;
if(endNum & lt;4)
Continuar;
frameSize = *(( int *)image buf); //Obtener el tamaño del marco
if(frameSize & lt; 500 | | frameSize & gt50000) {//Manejo de excepciones (tamaño de marco ilegal)
isStart = false//Descarta los datos y busca el indicador de inicio del marco nuevamente
endNum = 0
Continuar
}
frameSize; -= endNum+4;
}
De lo contrario {
while(frameSize & gt; 0 &&&temporary Workers!=SOCKET_ERROR) {//Obtener el marco completo los datos restantes.
temp=recv(clisock, (char*)(imageBuf+endNum), frameSize, 0
endNum+= temp
frameSize-= temp; ;
}
if(frameSize & lt;=0) {//Establecer al final del cuadro y descomprimir.
isStart = false
endNum = 0;
Decompress(); // Determina la validez de los datos y llama a ICDecompress para descomprimir.
}
}
}
}
El resultado de la ejecución del programa anterior es guarde un cuadro completo (excepto el indicador de inicio del cuadro).
4. Estrategia de control "Detener"
Si la velocidad de comunicación LAN es alta y el trabajo es estable, se puede lograr la transmisión de video en tiempo real siguiendo el método anterior sin ningún control. estrategia. Sin embargo, a menudo ocurren anomalías en la red, lo que hace que la velocidad de transmisión de datos disminuya significativamente, lo que genera una acumulación de datos en el extremo emisor y los datos en espera de ser enviados no se pueden enviar normalmente. En este momento, es necesario adoptar ciertas estrategias para controlar que el remitente cumpla con los requisitos en tiempo real.
En el programa de envío anterior, la variable isOK se utiliza para indicar si se ha enviado la trama actual del remitente. Si se ha enviado, se establece en verdadero, lo que también significa que el remitente está listo para continuar enviando datos; de lo contrario, es falso. Luego puede usar isOK para notificar los hilos de captura y compresión de video. Si isOK es verdadero, puede capturar el video y comprimirlo, luego activar el hilo de envío para continuar enviando nuevos datos de cuadros. De lo contrario, puede esperar hasta que la red pueda continuar enviando datos (isOK es verdadero). Por supuesto, la recopilación de video continúa, por lo que cuando la red está congestionada, siempre que no se permita que el codificador se comprima, la transmisión comprimida continuará cuando la red vuelva a la normalidad. En otras palabras, cuando la red está bloqueada, las tramas en espera de ser enviadas se eliminarán directamente, lo que garantiza que una vez que la red se recupere, se enviarán las últimas tramas comprimidas. Por supuesto, es necesario asegurarse de que una vez que se comienza a enviar una trama, se envía por completo.
Según esta estrategia de "detener y esperar" para la transmisión de vídeo en tiempo real sólo provocará un problema: cuando la calidad de la red es mala, el objetivo en movimiento en la imagen receptora se moverá instantáneamente. Sin embargo, esta estrategia garantizará que no se produzcan imágenes fantasma, fluctuaciones, visualización de pantalla, etc.
Conclusión
El esquema de transmisión de vídeo en tiempo real propuesto en este artículo se ha probado en LAN de 100 m, LAN de 100 m y LAN inalámbrica de 110 m. Durante la prueba, deje que un objetivo se mueva frente a la cámara (remitente) y observe la visualización de vídeo del receptor. Se realizaron múltiples pruebas en diferentes redes de área local, cada vez con una duración de entre 10 y 30 minutos, y el experimento se realizó cambiando la velocidad de movimiento del objetivo. Finalmente, se resumen los datos y se obtienen resultados estadísticos. Los resultados de la prueba se muestran en la Tabla 1.
Tabla 1 Resultados de la prueba en diferentes LAN
Ejercicio fuerte
Ejercicio normal
Movimiento lento
100- medidor LAN
La imagen es clara y suave.
La imagen es clara y fluida.
La imagen es clara y fluida.
LAN de 10 metros
Se producen pausas ocasionales y la tasa de pérdida de fotogramas es aproximadamente del 1 %.
La imagen es clara y fluida para el ojo humano.
La imagen es clara y fluida.
LAN inalámbrica de 11M
A menudo se producen pausas y la tasa de pérdida de fotogramas es del 5 % al 6 %.
A menudo se produce tartamudeo y la tasa de pérdida de fotogramas es del 2 % al 3 %.
Se producen pausas ocasionales y la tasa de pérdida de fotogramas es aproximadamente del 1%.
Entre ellos,
Nota: La tarjeta de red inalámbrica de 11M se conecta a la PC a través de la interfaz USB1.0. Sería mejor si se utilizara la interfaz USB2.0.
A juzgar por los resultados reales de la prueba, el efecto es bueno, excepto por el movimiento instantáneo, la imagen puede permanecer clara, eliminando las imágenes fantasma, las fluctuaciones y otros fenómenos causados por la mala calidad de la red, y cumpliendo con la transmisión en tiempo real. Requisitos de diferentes redes de área local.
//////////////////////////////////////////// // ///////////////////////////////////////////////// ////// ///////////////////////////////////////////// ////////// //////////////////////////////////////// ////////////// ///
Introducción al protocolo RTP/RTCP
RTP (Protocolo de transporte en tiempo real): Es una transmisión Protocolo para flujos de datos multimedia en Internet. Está publicado por el IETF (Internet Engineering Task Force) como RFC1889. RTP se define como trabajar en transmisión uno a uno o uno a muchos, con el propósito de proporcionar información de tiempo y lograr la sincronización de la transmisión. Las aplicaciones típicas de RTP se basan en UDP, pero también puede funcionar en otros protocolos, como TCP o ATM. El propio RTP solo garantiza la transmisión de datos en tiempo real, pero no puede proporcionar un mecanismo de transmisión confiable para la transmisión secuencial de paquetes de datos, ni proporciona control de flujo o control de congestión. Depende de RTCP para proporcionar estos servicios.
RTCP (Protocolo de control de transporte en tiempo real): Responsable de gestionar la calidad de la transmisión e intercambiar información de control entre los procesos de aplicación actuales. Durante una sesión RTP, cada participante transmite periódicamente paquetes RTCP, que contienen estadísticas como la cantidad de paquetes enviados y la cantidad de paquetes perdidos. Por lo tanto, el servidor puede utilizar esta información para cambiar dinámicamente la tasa de transferencia e incluso el tipo de carga útil. La combinación de RTP y RTCP puede optimizar la eficiencia de la transmisión con retroalimentación efectiva y una sobrecarga mínima, por lo que es particularmente adecuada para transmitir datos en tiempo real a través de Internet.
RTCP tiene cuatro funciones principales:
(1) La información de retroalimentación se utiliza para mejorar la calidad de transmisión de datos distribuidos y se puede utilizar para controlar la congestión del tráfico, monitorear la red y diagnosticar problemas. en la red
(2) Proporcionar una identificación de capa de transporte CNAME (nombre canónico) permanente para la fuente RTP, porque la SSRC (identificación de fuente de sincronización) cambiará cuando se descubra un conflicto o se actualice el programa. y reiniciado, requiriendo rastros de la operación. En un conjunto de sesiones relacionadas, el receptor también debe usar CNAME para obtener flujos de datos relacionados (como audio y video) de participantes específicos;
(3) Ajustar la velocidad de envío de paquetes RTCP de acuerdo con el número de participantes;
(4) Envío de información de control de sesión, como mostrar la identificación del participante en la interfaz de usuario; esta es una característica opcional.
Flujo de trabajo RTP/RTCP
Cuando está en funcionamiento, el protocolo RTP recibe el flujo de código de información de medios de transmisión (como H.263) de la capa superior, lo ensambla en un paquete RTP y lo envía a la capa inferior. El protocolo de capa inferior proporciona desvío de RTP y RTCP. Por ejemplo, en UDP, RTP usa puertos pares y el RTCP correspondiente usa los puertos impares que siguen. Los paquetes RTP no tienen límite de longitud y su longitud máxima de paquete solo está limitada por el protocolo de capa inferior.
Separación de dos niveles de sesiones y transmisiones RTP
Las sesiones RTP incluyen todo el tráfico a un par de destinos específico, y el remitente puede incluir varios. Una secuencia de paquetes RTP enviados desde la misma fuente de sincronización se denomina flujo y una sesión RTP puede contener múltiples flujos RTP. Cuando se envía un paquete RTP desde el servidor, siempre es necesario especificar a qué sesión y flujo pertenece. Al recibirlo, también debe dividirse en dos niveles, a saber, división de sesión y división de flujo. Solo combinando paquetes en la misma secuencia con el identificador de fuente de sincronización (SSRC) y el tipo de paquete (PTYPE) RTP puede usar números de secuencia y marcas de tiempo para ordenar y reproducir correctamente los paquetes.
Debido a la singularidad de los datos en tiempo real, diferentes clientes en tiempo real pueden usar un subproceso de servicio en tiempo real RTP y un subproceso de servicio en tiempo real RTCP, lo que puede reducir en gran medida la carga del servidor. y cada cliente de archivos puede diferentes archivos pueden tener diferentes requisitos de velocidad y tiempo de inicio, por lo que debe tener su propio subproceso de servicio de archivos RTP y su propio subproceso de servicio de archivos RTCP.
El hilo de servicio RTP es responsable de enviar flujos de datos en tiempo real al cliente. El hilo de servicio RTCP genera un informe del remitente al cliente basado en los datos estadísticos del hilo RTP.
A través de * * * estadísticas de interacción de memoria compartida entre un subproceso RTP y un subproceso RTCP, se debe configurar un mutex para proteger * * * la memoria compartida para evitar lecturas y escrituras erróneas. De esta forma, el servidor puede proporcionar fácilmente diferentes servicios según las diferentes solicitudes y situaciones específicas de cada usuario.
Procesamiento de marcas de tiempo RTP
El campo de marca de tiempo es la información de sincronización en el encabezado RTP que explica la hora del paquete de datos y es la clave para recuperar datos en el momento correcto. El valor de la marca de tiempo proporciona el momento de muestreo del primer byte de datos en el paquete, lo que requiere que el reloj de la marca de tiempo del remitente aumente continuamente de manera monótona, incluso si no se ingresan ni transmiten datos. En silencio, el remitente no necesita enviar datos para mantener incrementada la marca de tiempo. En el extremo receptor, debido a que el número de secuencia del paquete de datos recibido no se pierde, sabe que no hay pérdida de datos. Solo necesita comparar la diferencia en las marcas de tiempo de los paquetes de datos anteriores y posteriores para determinar el intervalo de tiempo de salida. .
RTP estipula que la marca de tiempo inicial de una sesión debe seleccionarse aleatoriamente, pero el protocolo no especifica la unidad de la marca de tiempo ni la interpretación exacta del valor. En cambio, el tipo de carga determina la granularidad del. Reloj para facilitar varios tipos de aplicaciones. La precisión de sincronización de salida adecuada se puede seleccionar según sus necesidades.
Cuando RTP transmite datos de audio, la velocidad de marca de tiempo lógica es generalmente la misma que la frecuencia de muestreo, pero cuando se transmiten datos de video, la velocidad de marca de tiempo debe ser mayor que un latido por cuadro. El estándar de protocolo también permite que varios paquetes tengan el mismo valor de marca de tiempo si los datos se muestrean simultáneamente.
El protocolo RTP no estipula la longitud de los paquetes RTP ni la velocidad de envío de datos. El servidor necesita ajustar la velocidad de envío de datos multimedia de acuerdo con condiciones específicas. Para datos en tiempo real del dispositivo, podemos acceder al búfer del dispositivo a intervalos iguales y enviar datos a medida que ingresan nuevos datos. Establecer marcas de tiempo es relativamente fácil. Para archivos multimedia grabados en el disco duro local, tome como ejemplo los archivos en formato H.263. Debido a que el archivo en sí no contiene información sobre la velocidad de fotogramas, necesita conocer la velocidad de fotogramas durante la grabación o establecer un valor inicial. Al enviar datos, averigüe el número de fotogramas en los datos de transmisión y calcule el retraso en función de la velocidad de fotogramas. el valor preestablecido para determinar la velocidad de fotogramas adecuada. Envíe datos rápidamente y establezca información de marca de tiempo.
Una de las características clave de RTCP es permitir que el receptor sincronice múltiples transmisiones RTP. Por ejemplo, cuando el audio y el video se transmiten juntos, debido a diferentes codificaciones, RTP usa dos transmisiones para transmitir por separado. De esta manera, las marcas de tiempo de las dos transmisiones se ejecutan a velocidades diferentes. El extremo receptor debe sincronizar las dos transmisiones para garantizar la transmisión. coherencia del sonido y las imágenes. Para sincronizar flujos de datos, RTCP requiere que el remitente proporcione un nombre canónico único para cada transmisión para identificar la fuente de datos. Aunque los diferentes flujos enviados por la fuente de datos tienen diferentes identificadores de fuente de sincronización (SSRC), tienen el mismo nombre canónico para que el receptor sepa qué flujos están relacionados. El receptor puede utilizar la información contenida en el mensaje de informe del remitente para conciliar los valores de marca de tiempo en las dos secuencias. El informe del remitente contiene un valor de tiempo absoluto en forma de NTP (Protocolo de tiempo de red) y luego se proporciona un valor de marca de tiempo RTP en el informe RTCP. El reloj que genera este valor es el reloj que genera el campo de marca de tiempo en el paquete RTP. . Debido a que todas las transmisiones enviadas por el remitente y reportadas por el remitente usan el mismo reloj absoluto, el receptor puede comparar los tiempos absolutos de dos transmisiones de la misma fuente de datos para determinar cómo asignar los valores de marca de tiempo en una transmisión a la otra. valor en .