2012-02-16 40 views
5

Ben yeni bir uint8_t dizisi olarak elde edilebilir H264 paketleri çözmek için mücadele FFmpeg için yeniyim. , H264 paketleri nasıl çözüleceği

araştırmaların birçoğu sonra, bunun sadece avcodec_decode_video2 tarafından

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

ve dekoder altında gibi bir AVPacket içine diziyi koymak gerekir düşünüyorum(). kodun bir kısmı ben düzgün gerekli tüm özellikleri ayarlamak tahmin

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

gibidir ama bu işlev

ret geliyor sadece -1 :(Ben sadece bulundu

-1 dönüyor = avctx-> codec-> şifresini çözmek (avctx, resim, got_picture_ptr, avpkt); avcodec_decode_video2 içinde

(); ı H deşifre eğer

Aslında ne merak ediyorum olduğunu Avcodec_decode_video2() tarafından 264 paket (RTP başlığı olmadan).

Yardımlarınız için şimdiden teşekkür ederiz.


/////////// hala bir çözüm bulmaya çalışıyorum,

Tamam ekledi. Aşağıda

** Bu RTP akışında H264 akışı tarafından kodlanan

Şimdi ne yapıyorum olduğunu FU-A

  1. bir RTP pakete

  2. göz ikinci bayt arasında ise alacak RTP üstbilgisi> 0 olan ilk pakettir (ve muhtemelen takip edilecek)

  3. bir sonraki RTP paketinin ikinci baytında> 0'a sahip olup olmadığına bakın, o zaman önceki çerçevenin tam bir NAL olduğu anlamına gelir veya Bu < 0 ise, paket önceki pakete eklenmelidir.

  4. Paketlerin tüm RTP üstbilgisini kaldırın, böylece yalnızca FU göstergesi gibi olur | FU başlığı | Ben FU göstergesini kaldırıp çok başlık gerekiyor .....

  5. NAL

    avcodec_decode_video2()

ile oynamak deneyin ancak yalnızca -1 dönüyor ??

herhangi bir öneri çok önceden

sayesinde takdir edilecektir.

cevap

1

RTP başlıkları olmadan H264 paketlerini RTP üstbilgisi olmadan çözebildiğinizi sanmıyorum. Aynı zamanda, tüm video akışı bilgilerinin RTP video paketlerinde çoğaltılabileceğini tahmin ediyorum. Dolayısıyla, akışın nasıl oluşturulduğuna da bağlı.Ben avcodec_decode_video2 tarafından (RTP olmadan) H264 paketleri deşifre eğer

Vibgyor

+0

Teşekkür Vibgyor aslında gönderen SpyDroid açık kaynak ve onun rtp başlığı birçok şeyi içeriyor görünmüyor, Kaynak Tanımlayıcıyı Senkronize Et ... bunlardan herhangi biri video akışı bilgisi anlamına mı geliyor? Ben öyle düşünmüyorum .. Hala üzerinde çalışıyorum ve ilerlememi güncelleyeceğim. – Jun

5

Aslında ne merak ediyorum olduğunu().

için gerekebilir ön-işlem RTP veri yükü (ler) tek NAL birimi modu dışında paketleme modları kullanmak durumunda dekodere SI birimleri geçirmeden önce (parçalanmış Nalus yeniden monte bölünmüş Nalus toplanır). Akışta izin verilen NAL birim tipleri (STAP, MTAP, FU) paketleme moduna bağlıdır. Paketleme modları hakkında daha fazla bilgi için RFC 6184'u okuyun. İkinci olarak, FFMPEG'e aşina olmamakla birlikte, genel bir H.264 kod çözme sorunu daha fazla olabilir: dekoderi her zaman H.264 dizisi (SPS) ve resim parametre setleri (PPS) ile başlatmanız gerekir. diğer çerçeveleri de çözebileceksiniz. Bunu yaptın mı? .. o yük tipi, sıra numarası, zaman damgası yapılmış

+0

Teşekkürler Ralf, spydroid'in rtp pakcet'lerini tek nal modda ve fu-1 modunda gönderdiğinden, sanırım fu paketinde RTP olarak paketlerin RTP olarak ele alınması gerektiğine inanıyorum, fakat ffmpeg kütüphanesini kullanarak RTP'nin nasıl çözüleceğine dair hiçbir fikrim yok. . Ben RTP seviyesi ile çalışan bir işlev olduğunu düşünüyorum ve bu yüzden bu işe H264 ile başlıyorum :(.. herhangi bir tavsiyede bulunabilir miyim? – Jun

+0

Eğer ffmpeg RTP katmanında çalışmıyorsa ya FFMPEG'e geçmeden önce bu kodu kendiniz yazın (o kadar da kötü değil) ya da başka bir 3. parti kütüphanesi kullanın .. Live555 (www.live555.com), diğer şeyler arasında H.264 yüküne özel paketleme de dahil olmak üzere RTP'yi işleyen bir Açık Kaynak LGPL kütüphanesi olurdu – Ralf

+0

@Ralf Tek NAL birim paket modunun RFC6184'ün bir parçası olduğunu, RFC için 5.6 bölümüne bakın. Neden RTP üstbilgisine gerek olmadığını söylediğinizden emin değilim. Yanlış, –

0

Bu, benim çalışma kodu

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