Я хотел бы знать, как получить доступ к содержимому заголовков GOV видео-файла mp4.
Я использую камеру Axis для потоковой передачи видео через RTSP, которое хранится на жестком диске в формате mp4. Согласно документации, камера вставляет определенные данные триггера в заголовок MPEG4 GOV, но я не знаю, как эту информацию можно получить или получить.
Я занимаюсь разработкой приложения на C ++, но сейчас мне не нужно обрабатывать данные программно, поэтому мне было бы достаточно решения, позволяющего визуализировать содержимое заголовка GOV.
Дополнительные данные, как правило, встраиваются прямо в поток и предположительно записываются в данные полезной видеоинформации файла MP4. Намерение состоит в том, чтобы сохранить весь поток, совместимый с MPEG-4, по-прежнему иметь дополнительные данные внутри. Декодеры обычно просто игнорируют это.
Обычно вам необходимо передать эти данные обратно из файла и проанализировать поток, чтобы извлечь части данных с информацией о триггере. Вам понадобятся специальные API для потоковой передачи видео (формат файла / демультиплексор и т. Д. — какова ваша ОС и среда?), И вам понадобится техническая информация Axis, чтобы увидеть, что именно они встраивают и как именно вам нужно разобрать это.
Если вы осуществляете потоковую передачу по RTSP, заголовок MPEG4 не будет передаваться — вместо этого информация «SDP» (протокол описания сеанса) будет передаваться через запрос DESCRIBE от клиента. Этот файл sdp содержит закодированную версию частоты кадров и т. Д., Которая фактически берется из атома MDAT в заголовке mpeg4.
Если вам определенно необходим доступ к gov atom для определения разности i-кадров p-кадра, вы можете попробовать проанализировать заголовок MPEG4 на сервере и передать его по отдельному каналу.
Внешний вид заголовка MPEG4 — это, в основном, текстовое имя атома, а затем длина, которая обычно составляет 4 байта (вам нужно поменять байты в зависимости от вашей платформы), а затем данные.
Вот некоторый отладочный код, который у меня есть в моем анализаторе заголовка mpeg4:
public boolean valid_atom(byte[] word, int offset) {
for (int i = 0; i < 4; i++)
if (!(word[i + offset] >= 'a' && word[i + offset] <= 'z') && !(word[i + offset] >= 'A' && word[i + offset] <= 'Z'))
return false;
return true;
}
…
public int parse_atom(byte[] b, int offset, int depth) {
int len;
len = ifba(b, offset);
Log.d(TAG, String.format("atom: %c%c%c%c depth %d @ %d len %d", b[offset + 4], b[offset + 5], b[offset + 6], b[offset + 7], depth, offset, len));
return len;
}
…
private int ifba(byte[] buffer, int offset) {
int retval = (buffer[offset] & 0xFF) << 24;
retval += (buffer[offset + 1] & 0xFF) << 16;
retval += (buffer[offset + 2] & 0XFF) << 8;
retval += (buffer[offset + 3] & 0XFF);
return retval;
}