tutorial tag poner para pagina oficial musica mp3tag imagen descargar como cambiar archivo album opencv udp webrtc janus-gateway

opencv - poner - tag editor para pc



Reconstruir imagen de paquetes RTP (3)

Estoy tratando de transmitir la cámara web de un usuario a través de la red a un servidor basado en C. He usado el portal Janus .

Creé un pequeño complemento basado en gran medida en el ejemplo de prueba de echotest: tengo mi navegador conectado a mi servidor janus a través de la tecnología WebRTC y lo hago transmitir la cámara web del usuario.

En el lado del servidor, tengo la función janus_incomming_rtp que me da un búfer char * y longitud int . Tras la inspección, el búfer de datos que recibe es aproximadamente la longitud de la MTU: cada fotograma de mi video se envía a través de varios paquetes RTP.

He inspeccionado un poco el encabezado al seguir esta página de wikipedia, pero no sé cómo reconstruir la imagen de esa secuencia de paquetes UDP RTP. Idealmente, me gustaría pasar la secuencia para abrirCV para hacer el procesamiento de imágenes en tiempo real.

He oído hablar de Gstreamer, pero no entiendo qué es ni cómo podría ayudarme; Además, no sé si openCV tiene funciones integradas para "reconstruir" las imágenes. Y no sé en qué formato se están codificando los cuadros de video: el PT (tipo de carga) parece ser 116, que se define como "dinámico", pero no tengo idea de lo que significa.

Alguna ayuda ?


Tenemos la misma preocupación con respecto a la transmisión de WebRTC. Lo que hice fue enviar el cuadro de video a un servidor WebSocket, desde allí decodifiqué el buffer de imagen usando imdecode ().

Tengo una demostración en vivo aquí twistedcv y también albergo la fuente en github aquí twistedcv . Pero la transmisión no está en tiempo real.


Terminé trabajando con Janus y GStreamer (1.9) siguiendo las sugerencias de otros en este hilo, incluyendo @nschoe (OP) y @Benjamin Trent. Pensé que incluiría mi código para hacer la vida más fácil para la siguiente persona que venga, ya que tanto ensayo y error estuvo involucrado para mí:

Primero compila / instala GStreamer con todos sus complementos necesarios (para mi configuración, necesitaba asegurarme de que dos directorios de complementos estaban en la variable de entorno GST_PLUGIN_SYSTEM_PATH). Ahora inicialice GStreamer cuando su plugin Janus se inicialice (llamada de retorno init() ).

gst_init(NULL, NULL);

Para cada sesión de WebRTC, deberá conservar algunos identificadores de GStreamer, así que agregue lo siguiente a su estructura de sesión de plugin Janus:

GstElement *pipeline, *appsrc, *multifilesink;

Cuando se crea una sesión de plugin de Janus ( create_session() callback), configure la create_session() GStreamer para esa sesión (en mi caso, necesitaba reducir la velocidad de fotogramas, por lo tanto, la tasa de video / capsrate; puede que no los necesite):

GstElement *conv, *vp8depay, *vp8dec, *videorate, *capsrate, *pngenc; session->pipeline = gst_pipeline_new("pipeline"); session->appsrc = gst_element_factory_make("appsrc", "source"); vp8depay = gst_element_factory_make("rtpvp8depay", NULL); vp8dec = gst_element_factory_make("vp8dec", NULL); videorate = gst_element_factory_make("videorate", NULL); capsrate = gst_element_factory_make("capsfilter", NULL); conv = gst_element_factory_make("videoconvert", "conv"); pngenc = gst_element_factory_make("pngenc", NULL); session->multifilesink = gst_element_factory_make("multifilesink", NULL); GstCaps* capsRate = gst_caps_new_simple("video/x-raw", "framerate", GST_TYPE_FRACTION, 15, 1, NULL); g_object_set(capsrate, "caps", capsRate, NULL); gst_caps_unref(capsRate); GstCaps* caps = gst_caps_new_simple ("application/x-rtp", "media", G_TYPE_STRING, "video", "encoding-name", G_TYPE_STRING, "VP8-DRAFT-IETF-01", "payload", G_TYPE_INT, 96, "clock-rate", G_TYPE_INT, 90000, NULL); g_object_set(G_OBJECT (session->appsrc), "caps", caps, NULL); gst_caps_unref(caps); gst_bin_add_many(GST_BIN(session->pipeline), session->appsrc, vp8depay, vp8dec, conv, videorate, capsrate, pngenc, session->multifilesink, NULL); gst_element_link_many(session->appsrc, vp8depay, vp8dec, conv, videorate, capsrate, pngenc, session->multifilesink, NULL); // Setup appsrc g_object_set(G_OBJECT (session->appsrc), "stream-type", 0, NULL); g_object_set(G_OBJECT (session->appsrc), "format", GST_FORMAT_TIME, NULL); g_object_set(G_OBJECT (session->appsrc), "is-live", TRUE, NULL); g_object_set(G_OBJECT (session->appsrc), "do-timestamp", TRUE, NULL); g_object_set(session->multifilesink, "location", "/blah/some/dir/output-%d.png", NULL); gst_element_set_state(session->pipeline, GST_STATE_PLAYING);

Cuando un paquete RTP entrante es demultiplexado por Janus y está listo para leer, (devolución de llamada incoming_rtp() ), alimentarlo en la tubería GStreamer:

if(video && session->video_active) { // Send to GStreamer guchar* temp = NULL; temp = (guchar*)malloc(len); memcpy(temp, buf, len); GstBuffer* buffer = gst_buffer_new_wrapped_full(0, temp, len, 0, len, temp, g_free); gst_app_src_push_buffer(GST_APP_SRC(session->appsrc), buffer); }

Finalmente, cuando la sesión del plugin Janus haya terminado ( destroy_session() callback), asegúrese de liberar los recursos de GStreamer:

if(session->pipeline) { gst_element_set_state(session->pipeline, GST_STATE_NULL); gst_object_unref(session->pipeline); session->pipeline = NULL; }


Aquí hay algunos pasos guía para manejar los paquetes SRTP para decodificarlos.

  1. Asegúrese de que rtp y RTCP no estén multiplexados, puede eliminar esa opción del SDP
  2. Descifre el paquete SRTP en RTP sin procesar, necesitará acceder al intercambio de claves (no estoy seguro de si ya está haciendo esto, pero todos los medios están encriptados y se intercambian claves mediante DTLS y deben descifrarse antes de manipularlos)
  3. Tome su tipo de carga útil de medios y compárela con los medios de SDP (puede ver desde el RTPMAP en el SDP qué medios son qué carga útil)
  4. Elimine la carga útil RTP del paquete (Gstreamer tiene complementos RtpDepay para la mayoría de las cargas útiles comunes, incluido VP8) y decodifica la transmisión. Ejemplo rápido de tuberías de línea de comando usando vp8
  5. Ahora tiene un paquete de video / audio sin formato que se puede mostrar.

PARTIDO SOCIALDEMÓCRATA:

  • Si se multiplexan RTCP y RTP, verá la línea a=rtcp-mux y verá que el puerto en a=rtcp:50111 IN IP4 <address> y los puertos de medios candidatos serán los mismos.
  • Si el medio se está multiplexando, verá a=group:BUNDLE audio video

SRTP:

  • Janus ya maneja el intercambio DTLS y parece que ya puede descifrar el rtp antes de enviarlo, pero no parece que represente multiplexado rtp / rtcp y medios.
  • Aquí hay un descifrador de SRTP rápido y sucio que funciona cuando le pasa la MasterKey que se intercambia en DTLS.

GStreamer:

  • Es posible que desee buscar en el GstAppSrc que le permite copiar matrices en una tubería gstreamer para decodificar y puede empujarlo a otro puerto udp para agarrarlo con OpenCV.
  • Aquí hay un código de ejemplo de un servidor de websocket que escribí que tomará los medios sin procesar y los empujará a una tubería. Este ejemplo no es exactamente lo que quiere hacer (no capta el RTP, sino marcos de medios en bruto de la página web), pero le mostrará cómo usar AppSrc.