Как я могу воспроизвести потоковые данные H264 RTSP с VLC - выгружается в файл с Wireshark - PullRequest
0 голосов
/ 17 октября 2018

Backstory

У меня есть IP-камера на локальной сети, я подключился к ней с помощью VLC (CTRL + N, добавление rtsp://192.168.1.10 <- IP-адрес, настроенный IP-камерой)и после подключения VLC я начал анализировать трафик с помощью Wireshark.Примерно через 30 секунд на Wireshark я нажал «Следить за потоком TCP» и сбросил трафик, поступающий с камеры, на мой компьютер raw. </p>

Моя цель

Iхотите иметь возможность получать выгруженный поток RTSP из Wireshark (или других альтернативных сетевых прослушиваний), извлекать данные H264 и иметь возможность впоследствии воспроизводить их на VLC.

Что я не хочу делать

  1. Я не хочу выгружать поток с помощью VLC
  2. Я не хочу выгружать поток с помощью FFMPEG

Things Iпопробовал

Так что мне уже удалось проанализировать заголовки RTSP и RTP и понять, откуда начинается полезная нагрузка H264, например:

00000000     24 00 05 A0 80 60 35 85 14 0C 1F DE 43 13 B7 58
00000010     7C 81 9A 26 26 64 33 FF 7C 11 99 87 4B 15 FA 06 
00000020     06 47 12 C5 6E 39 56 56 82 0D E0 1F 8D 1B 8A A7

Запускпо смещению 0x00000000 имеется заголовок RTSP 24 00 05 A0.Распаковывая его, используя python:

magic, channel, length = struct.unpack(">BBH", data)

после этого, между смещениями 0x00000004 to 0x00000010, у меня есть RTP header , синтаксический анализ как

bits_header_a, bits_header_b, sequence_number, timestamp, ssrc_identifier = struct.unpack(">BBHII", data)

и изсмещение 0x00000010 У меня есть фактическая полезная нагрузка.

Я посмотрел на RFC и отличный ответ, данный здесь на этот вопрос , но мне не совсем удалосьПонять, что я делаю неправильно, чтобы восстановить данные H264 из фактической полезной нагрузки RTSP.Вот часть большего кода, который я выполняю для каждой полезной нагрузки (фрейма) данных, которые я ранее анализировал (python), для создания фреймов данных:

first_byte = "{0:>08s}".format(bin(ord(frame[0]))[2:])
second_byte = "{0:>08s}".format(bin(ord(frame[1]))[2:])
rest_of_data = frame[2:]


# First byte
nal_unit_a = int(first_byte[:3], 2)
fragment_type = int(first_byte[3:], 2)

# Second byte
start_bit = int(second_byte[0], 2)
end_bit = int(second_byte[1], 2)
nal_unit_b = int(second_byte[3:], 2)


# Video data
if 0x1C == fragment_type:

    # Middle frame, just add
    if 0 == start_bit and 0 == end_bit:
        total_data += rest_of_data
        continue

    # First frame in sequence
    elif 1 == start_bit:
        print " [*] Found start frame"
        nal_unit = chr((nal_unit_a << 5) | nal_unit_b)
        if ord(nal_unit) != ( (ord(frame[0]) & 0xe0)  |  (ord(frame[1]) & 0x1F)):
            print "Unexpected"
        total_data += "\x00\x00\x00\x01"
        total_data += nal_unit
        total_data += rest_of_data
        continue

    # End
    elif 0 == start_bit and 1 == end_bit:
        print " [*] Found end frame"
        total_data += rest_of_data

Я восстанавливаю NALU какЯ думаю, я должен.Я выполняю этот код для каждой полезной нагрузки.Но вывод не воспроизводится на VLC (даже после настройки модуля VLC Demux на принудительный анализ H264).Я почти уверен, что что-то упустил, так как я ничего не исправил, связанный с временными метками и H264, так что может быть проблема с этим.Единственные значения, которые я получаю для nal_unit_b и nal_unit_a, это 5 3, 1 3, которые восстанавливаются на весь блок NAL 0x61 и 0x65.

Мои вопросы

  1. Я знаю, что в начале сеанса RTSP некоторые данные отправляются, чтобы лучше понять, как анализировать сеанс RTSP (также называемый SDP), но я уверен, что вседанные также должны существовать в полезной нагрузке H264, и они должны воспроизводиться даже без указания того, как анализировать данные, в качестве альтернативы, я всегда могу предположить, как данные кодируются, если я точно знаю, с каким поставщиком IP-камеры я общаюсьс.Это правильно?
  2. Правильно ли мой фрагмент кода выше?(Разбор рассматривается)
  3. Почему в моем потоке данных я получаю только пакеты видеоданных (fragment_type = 0x1C), и больше ничего не вижу.
  4. При простом подключении к IP-камере с помощью VLCи нажав Tools-->Codec Information, представленный кодек будет: Codec: H264 - MPEG-4 AVC (part 10) (h264), я предположил, что он должен быть проанализирован как H264, я также попытался проанализировать его как MPEG, но не смог, правильно ли я проанализировал его как H264?
...