Приветствую.
Есть камера, устанавливаю соединение по 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 разбираюсь крайне слабо.