Извлечение NALU из файлов MP4 со звуком

Я разрабатываю приложение WinForms в VB.NET, где мне нужно проанализировать файл MP4 (в частности, версию 1 MP4 на основе ISO_IEC_14496-12 и кодек H.264/AVC), извлечь кадры в виде изображений и сохранить их. Я не использую для этого проекта какие-либо пакеты NuGet или внешние библиотеки.

При работе с тестовыми видео, не содержащими звука, я заметил, что количество NALU, полученных от функции синтаксического анализа, совпадает с количеством кадров, иногда с дополнительным NALU, когда его тип равен 6.

  1. Мой первоначальный вопрос касается этого наблюдения: должно ли количество NALU быть равным количеству кадров (или почти равным)?

Однако я столкнулся с проблемой с видео, содержащими звук. NALUnitLength иногда превышает размер файла или (tempPos + NALUnitLength) > mdatEndPos. При попытке перебора следующего NALU в таких случаях я иногда получаю бессмысленные результаты:

  • NALU длиной 0
  • НАЛУ типа 6 необычно большого размера (более 100 000), но ничего примечательного («читабельного текста») в файле в этой позиции.

Разрешенные типы NALU — от 0 до 13, 19 и от 24 до 31.

К сожалению, в документации не содержится никакой информации по этому поводу.

Может ли кто-нибудь предоставить помощь или информацию по этому вопросу?

Спасибо!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кадры преобразуются в блоки NAL, но существуют дополнительные метаданные, которые могут быть необходимы для декодирования видеоданных. Например, PPS, SPS или SEI — это единицы NAL.

Иногда кадр разбивается на несколько фрагментов, и тогда вы можете иметь несколько видеоединиц NAL на кадр.

Кроме того, чересстрочное видео можно кодировать как отдельные поля, в результате чего получается как минимум две видеоединицы NAL на кадр.

Короче говоря, между количеством кадров и количеством единиц NAL не существует соотношения 1:1.

Несколько блоков NAL составляют один блок доступа, а блок доступа обычно представляет собой кадр.

В этой спецификации подробно описывается, как преобразовать H.264 в MP4:

https://www.iso.org/standard/83336.html

В этой спецификации показаны все подробности о H.264:

https://www.itu.int/rec/T-REC-H.264-202108-I/en

Большое спасибо за ваш ответ. Я уже купил упомянутую спецификацию (ISO 14496-15) и внедрил ее содержимое – должно быть, я что-то перечитал. Обратите внимание на мой второй вопрос, см. выше: я столкнулся с проблемой, что иногда NALUnitLength иногда превышает размер файла. Как это может произойти?

Daniel 28.09.2023 19:41

Теперь я решил это по-другому. Раньше я просто просматривал поле mdat и всегда суммировал NALUnitLength — это была новая позиция. Теперь я использую список ChunkOffset, который ранее заполнялся в поле «stco». Теперь я получаю столько же или больше NAUniтов, сколько имеется кадров. Но перед этим вам придется «расширить» список; это значит, что в начале в нем нет промежуточных кадров. Тема завершена.

Daniel 29.09.2023 11:58

Другие вопросы по теме