PavelK
@PavelK

Как вынуть h264 из rtp потока c IP камеры или в чём мои ошибки?

Приветствую.
Есть камера, устанавливаю соединение по RTSP, открываю UDP порт, камера шлёт пакеты.
С этим проблем почти не возникло,
возникли проблемы как из UDP потока выцепить h264 и просто записать в файл.

Алгоритм такой:
1. Из RTSP получаю для h264 параметры SPS и PPS из DSP, что пришёл в DSP ответе на DESCRIBE,
2. Записываю в файл: 000001 SPS 000001 PPS
3. Начинаю читать RTP пакеты с камеры
4. Получаю N`нный пакет целиком
5.1 Беру из него буфер заголовка фрейма (первые 12 байт, с проверкой что нету контрольных сумм и отступов, иначе пришлось бы увеличивать )
5.2. Беру из него буфер данных фрейма (с отступом от начала соразмерно заголовку и до конца)
5.3 Из заголовков выясняю Sequence что бы быть уверенным, что пакеты идут по порядку
6. Беру первый байт из буфера данных - NAL юнит
7. Смотрю его тип: (NAL & 0x1f)
7.1.1 Если тип 28, значит фрейм не влезает в один пакет
7.1.2 Беру второй байт из буфера данных - fuHeader заголовок фрагмента
7.1.3. Выясняю, какой это фрагмент:
начала ( f = fuHeader & 0x80 f!=0 )
середины ( m = fuHeader & 0xE0 m==0)
или конечный ( e = fuHeader & 0x40 e!=0)
7.1.4. Если фрагмент начала, то пишу в итоговый буфер
000001 - разделитель
восстанавливаю NAL (NAL & 0xE0) ^ (fuHeader & & 0x1f) и записываю в файл
записываю буфер данных фрейма со сдвигом от начала на 2 байта (без NAL и fuHeader)
7.1.5 Если фрагмент середины, то пишу в итоговый буфер
пишу буфер данных фрейма со сдвигом от начала на 2 байта (без NAL и fuHeader)
7.1.6 Если фрагмент конца, то пишу в итоговый буфер
пишу буфер данных фрейма со сдвигом от начала на 2 байта (без NAL и fuHeader)
записываю итоговый буфер в файл и очищаю итоговый буфер
8. И снова на шаг №4

В итоге файл воспроизводиться но в файле сплошные артефакты, если камеру подвигать,
что-то можно разобрать но опять же сплошные артефакты и прыжки.
По логу смотрел
- пакеты принимаются по порядку (показания Sequence)
- потерь ( разница Sequence от прошлого пакета) практически нет (один на 20-30)
- тип NAL всегда 28 (изредка проскакивает 6, но его игнорирую)

Если через ffmpeg записывать, то всё идеально.
Ставил у ffmpeg loglevel trace - моё RTSP подключение совпадает по параметрам.

Что я делаю не так? Правилен ли алгоритм?

P.S. Статья прочитана: https://habrahabr.ru/post/233237/ сверялся с ней - вроде всё правильно...
Посмотрел исходники примера - в примере делается так же (часть получегия и обработки),
разве что где-то ещё какая-то обработка стоит, но в Java разбираюсь крайне слабо.
  • Вопрос задан
  • 3330 просмотров
Решения вопроса 1
PavelK
@PavelK Автор вопроса
В общем, всё было правильно в алгоритме.
Я не до конца считывал udp пакет.
Осталось разобраться, храниться ли где-нибудь его длина, что бы проверять... т.к. контрольных сумм нету.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы