2012-02-16 15 views
5

Soy nuevo en FFmpeg que lucha para decodificar paquetes H264 que se pueden obtener como una matriz de uint8_t.usando FFmpeg, cómo decodificar paquetes H264

Después de muchas de las investigaciones, creo que debe ser capaz de simplemente poner la matriz en un AVPacket como lo de abajo

AVPacket *avpkt = (AVPacket *)malloc(sizeof(AVPacket) * 1); 
av_init_packet(avpkt); 
avpkt->data = ct; // ct is the array 
avpkt->length =.... 

y decodificar por avcodec_decode_video2(). Una parte del código es como

... 
codec = avcodec_find_decoder(CODEC_ID_H264); 
gVideoCodecCtx = avcodec_alloc_context(); 
gFrame = avcodec_alloc_frame(); 
avcodec_decode_video2(gVideoCodecCtx, gFrame, &frameFinished, packet); 
... 

supongo que puse todas las propiedades requeridas correctamente, pero esta función está volviendo solamente -1 :(

solo he encontrado el -1 viene de

ret = avctx-> codec-> decodificación (avctx, imagen, got_picture_ptr, avpkt);

en el avcodec_decode_video2();

en realidad, lo que me pregunto es si puedo descifrar H 264 paquetes (sin encabezado RTP) por avcodec_decode_video2().

Gracias por la ayuda con antelación.


/////////// añade

bien, todavía estoy tratando de encontrar una solución. Lo que estoy haciendo ahora es el siguiente

** la corriente H264 en este flujo RTP está codificada por FU-A

  1. reciben un paquete RTP

  2. vistazo si el segundo byte de el encabezado RTP es> 0, lo que significa que es el primer paquete (y posiblemente se seguirá)

  3. ver si el siguiente paquete RTP tiene> 0 en su segundo byte también, entonces significa que el cuadro anterior fue un NAL completo o si esto es < 0, el el paquete debe adjuntarse al paquete anterior.

  4. elimina todo el encabezado RTP de los paquetes por lo que solo tiene el indicador de FU | Encabezado FU | NAL

  5. intentar jugar con avcodec_decode_video2()

pero sólo está devolviendo -1 ..... voy a quitar el indicador de cabecera FU y también ??

cualquier sugerencia será muy apreciada

gracias de antemano.

Respuesta

1

No creo que pueda decodificar paquetes H264 sin encabezado RTP, ya que gran cantidad de información de transmisión de video está incrustada en los encabezados RTP. Al mismo tiempo, supongo que es posible que toda la información de transmisión de video se pueda duplicar en los paquetes de video RTP. Por lo tanto, también depende de cómo se genera la secuencia.

Vibgyor

+0

Gracias Vibgyor, en realidad el remitente es el código abierto Spydroid y su cabecera RTP no se ve contiene muchas cosas .. que está hecha de tipo de carga útil, número de secuencia, marca de tiempo, Identificador de fuente de sincronización ... ¿alguno de ellos significa información de transmisión de video? No lo creo. Todavía estoy trabajando en eso y actualizaré mi progreso. – Jun

5

En realidad, lo que me pregunto es si puedo descifrar paquetes H264 (sin cabecera RTP) por avcodec_decode_video2().

Es posible que necesite pre-proceso de la carga útil (s) RTP (volver a montar NALU fragmentada, dividida agregada NALU) antes de pasar a las unidades NAL al decodificador si utiliza modos distintos de paquetización modo de unidad NAL sola. Los tipos de unidades NAL (STAP, MTAP, FU) permitidas en la transmisión dependen del modo de paquetización. Lea RFC 6184 para obtener más información sobre los modos de paquetización.

En segundo lugar, aunque no estoy familiarizado con FFMPEG, podría tratarse más bien de un problema general de decodificación H.264: siempre debe inicializar el decodificador con la secuencia H.264 (SPS) y los conjuntos de parámetros de imagen (PPS) antes de que puedas decodificar otros marcos. ¿Ha hecho usted eso?

+0

Gracias Ralf, spydroid envía paquetes rtp en modo single nal y en modo fu-1 ambos así que supongo que necesito manejar paquetes como RTP con encabezado para el caso fu-1 pero no tengo idea de cómo decodificar RTP utilizando la biblioteca ffmpeg . Creo que no hay ninguna función que funcione con el nivel RTP y es por eso que estoy comenzando este trabajo con H264 :(... ¿podría obtener algún consejo al respecto? – Jun

+0

Si ffmpeg no funciona en la capa RTP, tendrá que escribe ese código antes de pasarlo a FFMPEG (no es tan malo) o usa otra biblioteca de terceros. Live555 (www.live555.com) sería una biblioteca LGPL de código abierto que maneja RTP, incluida la paquetización específica de carga H.264, entre otras cosas – Ralf

+0

@Ralf Creo que el modo de paquete de unidad Single NAL también forma parte del RFC6184, consulte la sección 5.6 para el RFC. No estoy seguro de por qué está diciendo que no requiere el encabezado RTP. Corrija amablemente si estoy equivocado –

0

Este es mi código de trabajo

bool VideoDecoder::decode(const QByteArray &encoded) 
{ 
    AVPacket packet; 
    av_new_packet(&packet, encoded.size()); 
    memcpy(packet.data, encoded.data(), encoded.size()); 
    //TODO: use AVPacket directly instead of Packet? 
    //TODO: some decoders might in addition need other fields like flags&AV_PKT_FLAG_KEY 

    int ret = avcodec_decode_video2(d->codec_ctx, d->frame, &d->got_frame_ptr, &packet); 
    av_free_packet(&packet); 

    if ((ret < 0) || (!d->got_frame_ptr)) 
     return false; 

    d->sws_ctx = sws_getCachedContext(d->sws_ctx 
     , d->codec_ctx->width, d->codec_ctx->height, d->codec_ctx->pix_fmt 
     , d->width, d->height, d->pix_fmt 
     , (d->width == d->codec_ctx->width && d->height == d->codec_ctx->height) ? SWS_POINT : SWS_BICUBIC 
     , NULL, NULL, NULL 
     ); 

    int v_scale_result = sws_scale(
     d->sws_ctx, 
     d->frame->data, 
     d->frame->linesize, 
     0, 
     d->codec_ctx->height, 
     d->picture.data, 
     d->picture.linesize 
     ); 
    Q_UNUSED(v_scale_result); 

    if (d->frame->interlaced_frame) 
     avpicture_deinterlace(&d->picture, &d->picture, d->pix_fmt, d->width, d->height); 
    return true; 
} 
Cuestiones relacionadas