2012-07-04 41 views
19

Gần đây tôi đã có cơ hội làm việc với hai thiết bị đang phát trực tuyến H264 qua RTSP. Và tôi đã gặp phải một số sự cố khi cố giải nén luồng này bằng thư viện FFmpeg.FFmpeg không thể giải mã luồng/dữ liệu khung H264

Mỗi lần "avcodec_decode_video2" được gọi là - FFmpeg chỉ nói một cái gì đó như:

[h264 @ 00.339.220] không có khung!

dòng H264 liệu của tôi tôi khung dữ liệu bắt đầu như thế này: " 88 84 21 3F F8 F8 0D ..." (như xa như tôi hiểu 0x65 điều này chỉ ra rằng đó là một khung IDR?)

khung khác cho một thiết bị khởi động như: " 9A 22 07 F3 4E 48 CC ...."

và cho các thiết bị khác - như thế này: " 9A 25 C1 1C 45 62 39 .... "

  • Tôi có thiếu một số dữ liệu khung ở đây không?
  • FFmpeg có cần thiết lập thêm một số tham số không?

Tôi đã chờ đợi ít nhất "" byte lúc bắt đầu cho dữ liệu khung ... nhưng đây là những gì tôi đã có ..

Trả lời

21

Ok, cố gắng làm cho mọi việc đang làm việc.

  • Tôi cần bao gồm chuỗi (SPS) và tham số hình ảnh (PPS) cho dữ liệu khung trước khi gửi khung đến FFmpeg.
  • Tôi cần thêm 4 byte phụ "00 00 00 01" sau dữ liệu SPS và PPS.

Dưới đây là một hình ảnh nhỏ hiển thị những gì tôi muốn nói: enter image description here

Bytes "65 88 ..." là nơi dữ liệu khung ban đầu của tôi bắt đầu.

Thông tin SPS và PPS này không được bao gồm trong gói RTP. Tôi đang sử dụng thư viện Live555 để phát trực tuyến RTSP, vì vậy tôi đã sử dụng các chức năng "fmtp_spropparametersets" để có được những gì tôi cần. Thông tin này được mã hóa Base64. (Ví dụ: Một cái gì đó như thế này "Z0KAKNoC0EkQ, aM48gA ==") Lưu ý rằng có hai "tham số" SPS và PPS được phân tách bằng "," và các thông số đó không có "00 00 00 01" được bao gồm, vì vậy bạn cần thêm chúng.

Một số mẫu mã (Tôi đang sử dụng Qt thư viện ở đây):

QByteArray  ba   = pSubSession->fmtp_spropparametersets(); 
QList<QByteArray> recordsList = ba.split(','); 

for (int i = 0; i < recordsList.size(); i++) 
{ 
    mExtraData.append(char(0x00)); 
    mExtraData.append(char(0x00)); 
    mExtraData.append(char(0x00)); 
    mExtraData.append(char(0x01)); 

    mExtraData += QByteArray::fromBase64(recordsList.at(i)); 
} 

Bây giờ cho mỗi khung Tôi làm điều gì đó như thế này:

QByteArray ba = QByteArray(4, 0); // Prepare the "00 00 00 01" 
      ba[3] = 0x01; 

mpTrackVideo->buffer.insert(0, mExtraData); 
mpTrackVideo->buffer.insert(mExtraData.size(), ba); 

Năm trước, tôi nghĩ tôi đã có hỗ trợ dòng H264 Vì vậy, bạn cần phải ghi nhớ rằng một số thiết bị có thể gửi dữ liệu SPS và PPS cho mỗi khung hình của tôi ... và một số có thể không!

Các vấn đề liên quan