qué protocolo hikvision rtp rtsp

protocolo - Detectar MPEG4/H264 I-Frame(IDR) en un flujo RTP



rtsp vs http (6)

Necesito detectar MPEG4 I-Frame en un paquete RTP. Sé cómo eliminar el encabezado RTP y obtener el marco MPEG4 en él, pero no puedo averiguar cómo identificar el I-Frame.

¿Tiene una firma / encabezado específico?


0x000001b6: vop_start_code (fotograma clave, si los dos bits siguientes son cero) esta es la forma correcta para MPEG-4


En realidad, era correcto para el flujo h264, si el valor NAL (primer byte) es 0x7C significa que el I-Frame está fragmentado. No se pueden fragmentar otros marcos (P y B), por lo que si hay packetization-mode=1 en SDP , significa que los marcos I están fragmentados y, por lo tanto, si lee 0x7C como primer byte, entonces es I- Cuadro. Lea más aquí: here .


Esto funcionó para mí:
- Determine el "tipo de carga útil", por ejemplo: Tipo de carga útil: DynamicRTP-Type-96 (96)
- Indique a wireshark qué flujo es H264: Archivo-> preferencias-> protocolos-> H264. Introduzca 96 como tipo de carga útil.
- Filtro en slice_type: "h264.slice_type eq 7"


Ok, así que lo deduje a la corriente h264.

Cómo detectar I-Frame:

  • eliminar el encabezado RTP
  • verifique el valor del primer byte en la carga útil h264
  • si el valor es 124 (0x7C) es un I-Frame

No puedo entenderlo para la transmisión de MPEG4-ES ... ¿alguna sugerencia?

EDITAR: IDR H264

Esto funciona para mi flujo h264 ( fmtp:96 packetization-mode=1; profile-level-id=420029; ). Simplemente pase la matriz de bytes que representa el fragmento h264 recibido a través de RTP. Si desea pasar todo el RTP, simplemente corrija el valor RTPHeaderBytes para omitir el encabezado RTP. Siempre obtengo el I-Frame, porque es el único frame que se puede fragmentar, consulte here . ¡Utilizo este pedazo de código (simplificado) en mi servidor, y funciona como un encanto! Si el I-Frame (IDR) no está fragmentado, fragment_type sería 5, por lo que este código devolvería true para los IDR fragmentados y no fragmentados.

public static bool isH264iFrame(byte[] paket) { int RTPHeaderBytes = 0; int fragment_type = paket[RTPHeaderBytes + 0] & 0x1F; int nal_type = paket[RTPHeaderBytes + 1] & 0x1F; int start_bit = paket[RTPHeaderBytes + 1] & 0x80; if (((fragment_type == 28 || fragment_type == 29) && nal_type == 5 && start_bit == 128) || fragment_type == 5) { return true; } return false; }

Aquí está la tabla de tipos de unidades NAL:

Type Name 0 [unspecified] 1 Coded slice 2 Data Partition A 3 Data Partition B 4 Data Partition C 5 IDR (Instantaneous Decoding Refresh) Picture 6 SEI (Supplemental Enhancement Information) 7 SPS (Sequence Parameter Set) 8 PPS (Picture Parameter Set) 9 Access Unit Delimiter 10 EoS (End of Sequence) 11 EoS (End of Stream) 12 Filter Data 13-23 [extended] 24-31 [unspecified]

EDIT 2: MPEG4 I-VOP

Olvidé actualizar este ... Gracias al documento de Che e ISO IEC 14496-2 , ¡logré resolver esto! Che fue un rito, pero no tan preciso en su respuesta ... así que aquí es cómo encontrar los cuadros I, P y B (I-VOP, P-VOP, B-VOP) en resumen:

  1. VOP (Video Object Plane - frame) comienza con un código 000001B6 (hex). Es igual para todos los cuadros MPEG4 (I, P, B)
  2. A continuación, se incluye mucha más información, que no voy a describir aquí (consulte el documento IEC), pero solo (como dice cheque) necesitamos los 2 bits más altos del siguiente byte (los siguientes dos bits después del byte con el valor B6 ) . Esos 2 bits le indican el VOP_CODING_TYPE, vea la tabla:

    VOP_CODING_TYPE (binary) Coding method 00 intra-coded (I) 01 predictive-coded (P) 10 bidirectionally-predictive-coded (B) 11 sprite (S)

Entonces, para encontrar I-Frame, encuentre el paquete que comienza con cuatro bytes 000001B6 y que tiene los dos bits más altos del siguiente byte 00 . Esto encontrará el marco I en la secuencia MPEG4 con un tipo de objeto de video simple (no estoy seguro de que sea simple avanzado).

Para cualquier otro problema, puede consultar el documento proporcionado ( ISO IEC 14496-2 ), hay todo lo que desea saber sobre MPEG4. :)


Para H264:

  1. Eliminar el encabezado RTP.
  2. Si el tipo de NAL del fragmento (en el primer byte) es SPS (7) o PPS (8), marque el marco como IFrame (muchas cámaras no usan SPS y PPS (eje incluido)).
  3. Si el tipo de NAL del fragmento es # 28 FU A (unidad de fragmentación A), verifique el encabezado de FU (el siguiente byte) si es de tipo NAL IDR (5) (Imagen de IDR (actualización de descodificación instantánea)) es un IFrame.

Ejemplos:

nal_ref_idc: 3, nal type: 7 (0x07) descripcion: 7 (SPS)<br> 00000000 24 00 00 2B 80 60 22 ED 96 57 3E 68 57 F3 22 B5 $..+.`"í.W>hWó"µ<br> 00000010 67 64 00 1E AD 84 01 0C 20 08 61 00 43 08 02 18 gd..­... .a.C... 00000020 40 10 C2 00 84 2B 50 5A 09 34 DC 04 04 04 08 @.Â..+PZ.4Ü....<br> nal_ref_idc: 3, nal type: 8 (0x08) descripcion: 8 (PPS)<br> 00000000 24 00 00 10 80 60 22 EE 96 57 3E 68 57 F3 22 B5 $....`"î.W>hWó"µ 00000010 68 EE 3C B0 hî<° FU_A (fragmentation unit A) nal_ref_idc: 3, nal type: 5 (0x05) descripcion: 5 (IDR (Instantaneous Decoding Refresh) Picture) 00000000 24 00 05 96 80 60 22 F1 96 57 3E 68 57 F3 22 B5 $....`"ñ.W>hWó"µ 00000010 7C 05 A0 AA 2F 81 92 AB CA FE 9E 34 D8 06 AD 74 |. ª/..«Êþ.4Ø.­t ...


Por lo que sé, los fragmentos de flujo MPEG4-ES en la carga útil de RTP generalmente comienzan con el código de inicio MPEG4, que puede ser uno de los siguientes:

  • 0x000001b0 : visual_object_sequence_start_code (probablemente fotograma clave)
  • 0x000001b6 : vop_start_code (fotograma clave, si los dos bits siguientes son cero)
  • 0x000001b3 : group_of_vop_start_code, que contiene tres bytes y luego, con suerte, un vop_start_code que puede o no pertenecer a un fotograma clave (ver arriba)
  • 0x00000120 : video_object_layer_start_code (probablemente fotograma clave)
  • 0x00000100 - 0x0000011f : video_object_start_code (también parecen fotogramas clave)
  • otra cosa (probablemente no sea un fotograma clave)

Me temo que tendrás que analizar el flujo para estar seguro: - /