2012-02-16 18 views
5

Jestem nowy dla FFmpeg, który stara się dekodować pakiety H264, które można uzyskać w postaci tablicy uint8_t.używając FFmpeg, jak dekodować pakiety H264

Po wielu badaniach, myślę, że powinien on być w stanie po prostu umieścić tablicy do AVPacket jak poniżej

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

i dekodowania przez avcodec_decode_video2(). Część kodu jest jak

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

Chyba ustawić wszystkie wymagane właściwości prawidłowo, ale ta funkcja zwraca tylko -1 :(

Właśnie znalazłem -1 pochodzi

ret = avctx-> codec-> dekodowania (avctx, obraz, got_picture_ptr, avpkt);

w avcodec_decode_video2();

Właściwie co zastanawiam się, czy mogę rozszyfrować H 264 pakiety (bez nagłówka RTP) przez avcodec_decode_video2().

Dzięki za pomoc z góry.


/////////// dodany

OK, ja wciąż próbuje znaleźć rozwiązanie. Co robię teraz jest poniżej

** strumień H264 w tym strumieniu RTP jest kodowana przez FU-A

  1. odebrania pakietu RTP

  2. wygląd jeśli drugi bajt nagłówek RTP ma wartość> 0, co oznacza, że ​​jest to pierwszy pakiet (i być może będzie śledzony)

  3. Sprawdź, czy następny pakiet RTP ma także> 0 w swoim drugim bajcie, oznacza to, że poprzednia klatka była kompletną NAL lub jeśli jest to < 0, pakiet powinien zostać dołączony do poprzedniego pakietu.

  4. usuwa wszystkie nagłówki RTP pakietów, więc ma tylko taki wskaźnik FU | Nagłówek FU | NAL

  5. spróbować odtworzyć go z avcodec_decode_video2()

ale to powrót tylko -1 ..... mam usunąć wskaźnik FU i header zbyt ??

każda sugestia będzie bardzo mile widziane

z góry dzięki.

Odpowiedz

1

Nie sądzę, że będziesz w stanie dekodować pakiety H264 bez nagłówka RTP, ponieważ sporo informacji o strumieniu wideo jest osadzonych w nagłówkach RTP. W tym samym czasie, przypuszczam, że jest możliwe, że wszystkie informacje o strumieniu wideo mogą być duplikowane w pakietach wideo RTP. Zależy to również od sposobu generowania strumienia.

Vibgyor

+0

Dzięki Vibgyor, rzeczywiście nadawca jest spydroid open source i jego nagłówek RTP nie wygląda zawierają wiele rzeczy .. to jest zrobione z rodzaju ładunku, numer sekwencji, datownik, Identyfikator źródła synchronizacji. Któryś z nich oznacza strumień wideo? Nie sądzę ... Nadal nad tym pracuję i będę aktualizował moje postępy. – Jun

5

Właściwie co zastanawiam się, czy mogę dekodowania H264 pakiety (bez nagłówka RTP), których autorem jest avcodec_decode_video2().

może trzeba pre-process ładowność (s) RTP (ponownie zamontować fragmentaryczne Nalus split agregowane Nalus) przed przekazaniem jednostki NAL do dekodera, jeśli używasz trybu pakietyzację inne niż jednego rodzaju jednostki NAL. Typy jednostek NAL (STAP, MTAP, FU) dozwolone w strumieniu zależą od trybu pakietowania. Przeczytaj RFC 6184, aby uzyskać więcej informacji o trybach pakietowania.

Po drugie, chociaż nie jestem zaznajomiony z FFMPEG, może to być bardziej ogólny problem z dekodowaniem H.264: zawsze należy zainicjować dekoder za pomocą sekwencji parametrów H.264 (SPS) i obrazów (PPS) zanim będziesz mógł dekodować inne ramki. Zrobiłeś to?

+0

Dzięki Ralf, okazuje się, że spydroid wysyła pakiety rtp w trybie pojedynczym i fu-1, więc domyślam się, że potrzebuję obsługiwać pakiety jako RTP z nagłówkiem dla sprawy fu-1, ale nie mam pojęcia jak rozszyfrować RTP przy użyciu biblioteki ffmpeg . Myślę, że nie ma żadnej funkcji działającej na poziomie RTP i dlatego zaczynam tę pracę z H264 :(.. czy mogę uzyskać jakąkolwiek poradę na ten temat? – Jun

+0

Jeśli ffmpeg nie działa na warstwie RTP, musisz albo napisz ten kod samodzielnie przed przekazaniem go do FFMPEG (nie jest tak źle) lub użyj innej biblioteki 3rd party. Live555 (www.live555.com) będzie biblioteką Open Source LGPL, która obsługuje RTP, w tym pakietowanie H.264 specyficzne dla ładunku, między innymi – Ralf

+0

@Ralf Wierzę, że tryb pojedynczego pakietu NAL jest również częścią RFC6184, odsyłaj do sekcji 5.6 dla RFC.Nie jestem pewien, dlaczego mówisz, że nie wymaga nagłówka RTP. Uprzejmie mnie popraw, jeśli mylę się, –

0

To jest mój kod roboczych

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; 
}