2012-02-16 40 views
5

Tôi mới sử dụng FFmpeg để giải mã các gói H264 có thể lấy được dưới dạng mảng uint8_t.sử dụng FFmpeg, cách giải mã gói H264

Sau nhiều cuộc điều tra, tôi nghĩ rằng nó sẽ có thể chỉ cần đặt mảng thành một AVPacket như dưới đây

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

và giải mã bởi avcodec_decode_video2(). Một phần của mã này là như

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

Tôi đoán tôi đặt tất cả các thuộc tính cần thiết đúng nhưng chức năng này chỉ có -1 :(

Tôi chỉ tìm thấy -1 đang trở lại đến từ

ret = avctx-> codec-> decode (avctx, hình ảnh, got_picture_ptr, avpkt);

trong avcodec_decode_video2();

trên thực tế, những gì tôi đang tự hỏi là nếu tôi có thể giải mã H 264 gói (không có tiêu đề RTP) bởi avcodec_decode_video2().

Cảm ơn bạn đã trợ giúp trước.


/////////// thêm

OK, tôi vẫn đang cố gắng để tìm một giải pháp. Những gì tôi đang làm bây giờ là dưới

** dòng H264 trong dòng RTP này được mã hóa bởi FU-A

  1. nhận được một gói tin RTP

  2. nhìn nếu byte thứ hai của tiêu đề RTP là> 0 có nghĩa là đó là gói đầu tiên (và có thể sẽ được theo sau)

  3. xem gói RTP tiếp theo có> 0 tại byte thứ hai của nó hay không, sau đó có nghĩa là khung trước đó là NAL hoàn chỉnh hoặc nếu đây là < 0, gói nên được nối vào gói trước đó.

  4. xóa tất cả tiêu đề RTP của các gói để nó chỉ giống như chỉ báo FU | Tiêu đề FU | NAL

  5. thử chơi nó với avcodec_decode_video2()

nhưng nó chỉ trở về -1 ..... Tôi phải loại bỏ chỉ số FU và tiêu đề quá ??

mọi đề xuất sẽ được đánh giá rất cao

cảm ơn trước.

Trả lời

1

Tôi không nghĩ rằng bạn sẽ có thể giải mã các gói H264 mà không có tiêu đề RTP vì một chút thông tin luồng video được nhúng vào các tiêu đề RTP. Đồng thời, tôi đoán có thể là tất cả các thông tin dòng video có thể được nhân đôi trong các gói video RTP. Vì vậy, nó cũng phụ thuộc vào cách tạo luồng.

Vibgyor

+0

Cảm ơn Vibgyor, trên thực tế người gửi là mã nguồn mở spydroid và tiêu đề RTP của nó không giống chứa nhiều điều .. nó được làm từ loại tải trọng, số thứ tự, dấu thời gian, Mã định danh nguồn đồng bộ .. bất kỳ định nghĩa nào trong số đó có nghĩa là thông tin luồng video? Tôi không nghĩ vậy .. Tôi vẫn đang nghiên cứu và sẽ cập nhật tiến trình của mình. – Jun

5

Trên thực tế, những gì tôi đang tự hỏi là nếu tôi có thể giải mã H264 gói (không có tiêu đề RTP) bởi avcodec_decode_video2().

Bạn có thể cần phải xử lý trước (các) trọng tải RTP (tái lắp ráp NALU phân đoạn, NALU được chia tách) trước khi chuyển các đơn vị NAL đến bộ giải mã nếu bạn sử dụng chế độ đóng gói khác với chế độ đơn vị NAL đơn. Các loại đơn vị NAL (STAP, MTAP, FU) được phép trong luồng phụ thuộc vào chế độ gói. Đọc RFC 6184 để biết thêm thông tin về các chế độ gói. Thứ hai, trong khi tôi không quen thuộc với FFMPEG, nó có thể là một vấn đề giải mã H.264 nói chung: bạn phải luôn khởi tạo bộ giải mã với chuỗi H.264 (SPS) và các bộ tham số hình ảnh (PPS). trước khi bạn có thể giải mã các khung hình khác. Bạn đã hoàn thành chưa?

+0

Cảm ơn Ralf, hóa ra spydroid gửi rtp pakcets ở chế độ đơn nal và fu-1 cả vì vậy tôi đoán tôi cần xử lý các gói như RTP với tiêu đề cho trường hợp fu-1 nhưng không biết cách giải mã RTP bằng thư viện ffmpeg . Tôi nghĩ rằng không có chức năng làm việc với mức RTP và đó là lý do tại sao tôi bắt đầu công việc này với H264: (.. Tôi có thể nhận được bất kỳ lời khuyên nào về nó? – Jun

+0

Nếu ffmpeg không hoạt động ở lớp RTP, bạn sẽ phải tự viết mã đó trước khi chuyển sang FFMPEG (không phải là xấu) hoặc sử dụng thư viện của bên thứ 3. Live555 (www.live555.com) sẽ là một thư viện LGPL mã nguồn mở xử lý RTP bao gồm gói tin đặc biệt tải trọng H.264 trong số những thứ khác – Ralf

+0

@Ralf Tôi tin rằng chế độ gói đơn vị NAL đơn cũng là một phần của RFC6184, tham khảo phần 5.6 cho RFC. Tôi không chắc chắn lý do tại sao bạn nói rằng nó không yêu cầu tiêu đề RTP.Xin vui lòng sửa tôi nếu tôi –

0

Đây là mã làm việc của tôi

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; 
} 
Các vấn đề liên quan