Подтвердить что ты не робот

FFmpeg не может декодировать данные потока/кадра H264

Недавно у меня появилась возможность работать с двумя устройствами, которые передают H264 через RTSP. И у меня возникла проблема с попыткой распаковать этот поток, используя библиотеку FFmpeg.

Каждый раз, когда вызывается " avcodec_decode_video2", FFmpeg просто говорит что-то вроде:

[h264 @00339220] no frame!

Мой необработанный поток H264 I начинается следующим образом: " 65 88 84 21 3F F8 F8 0D..." (насколько я понимаю, это 0x65 указывает, что это рамочный IDR?)

Другие кадры для одного устройства начинаются следующим образом: " 41 9A 22 07 F3 4E 48 CC...."

и для другого устройства - например: 61 9A 25 C1 1C 45 62 39.... "

  • Мне не хватает данных о кадре?
  • Требуется ли FFmpeg для установки некоторых дополнительных параметров?

Я ожидал по крайней мере " 00 00 00 01" байт в начале для данных фрейма... но это то, что у меня есть.

4b9b3361

Ответ 1

Хорошо, удалось заставить все работать.

  • Мне нужно было включить последовательности (SPS) и набор параметров изображения (PPS) для моих данных кадра перед отправкой фрейма в FFmpeg.
  • Мне нужно было добавить 4 дополнительных байта "00 00 00 01" после данных SPS и PPS.

Вот небольшая картина, показывающая, что я имею в виду: enter image description here

Байты "65 88..." - это где мои исходные данные кадра начинаются.

Эта информация SPS и PPS не была включена в пакет RTP. Я использую библиотеку Live555 для потоковой передачи RTSP, поэтому я использовал подсекции " fmtp_spropparametersets", чтобы получить то, что мне нужно. Эта информация была кодирована Base64. (Пример: что-то вроде этого "Z0KAKNoC0EkQ, aM48gA ==" ). Обратите внимание, что есть два "параметра" SPS и PPS, разделенные ",", и эти параметры не содержат "00 00 00 01", поэтому вам нужно добавьте их.

Пример кода (я использую здесь библиотеку Qt):

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

Теперь для каждого кадра я делаю что-то вроде этого:

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

Год назад я думал, что у меня есть поддержка потоков H264, интегрированная в мой проект, пока у меня не было возможности проверить ее с помощью некоторых других устройств... Поэтому вам нужно иметь в виду, что некоторые устройства могут отправлять данные SPS и PPS для каждого кадра I... а некоторые могут и не быть!