ffmpeg создает странные суффиксы NAL для MPEG-TS с h264

Я делаю анализатор потока h264 и обнаружил странное поведение ffmpeg при записи и чтении одного и того же кадра, упакованного с помощью MPEG-TS.

Я сбросил данные кадра кодирования и декодирования в HEX и обнаружил следующие различия:

В начале кадра добавлен разделитель NAL:

+ 00
+ 00
+ 00
+ 01
+ 09
+ f0

это выглядит абсолютно законным для меня.

Но вот странные вещи:

Если текущий пакет не является последним, то добавляется некоторый суффикс (т.е. в последнем записанном кадре этого суффикса нет). И этот суффикс добавляется к текущему кадру чтения (т.е. это не префикс к следующему кадру).

+ e0
+ 00
+ 00
+ 00
+ 01
+ ce
+ 8c
+ 4d
+ 9d
+ 10
+ 8e
+ 25
+ e9
+ fe

(точно начиная с добавленного e0 байта)

Я пытаюсь понять, что это может означать. Если 00000001 является заголовком NAL, то за ним следует ce байт с запрещенным нулевым битом, равным 1, что абсолютно не работает.

Я использую форк из репозитория ffmpeg github, последний раз объединенный с коммитом 89092fafdde894c6ba4d4f8e3cd1cce0d68bfc22.

ffmpeg построен с --disable-everything --enable-encoder=libopenh264 --enable-muxer=mpegts --enable-demuxer=mpegts --enable-protocol=file --enable-parser=h264 --enable-decoder=libopenh264 --enable-shared --disable-static --disable-programs --disable-doc --enable-libopenh264 параметрами


person ElDorado    schedule 06.12.2016    source источник
comment
Да, этот файл может быть поврежден. Можете ли вы опубликовать его где-нибудь, и я могу подтвердить?   -  person szatmary    schedule 06.12.2016
comment
@szatmary да, конечно. Вот все. Я проверил, что у меня все еще есть проблемы с этим видео, хотя vlc с ffmpeg читает его нормально   -  person ElDorado    schedule 09.12.2016
comment
Последовательность 00 00 00 01 ce отсутствует в файле, который вы разместили.   -  person szatmary    schedule 10.12.2016
comment
@ElDorado Я подтверждаю выводы Сатмари. Можете ли вы дать нам смещение?   -  person aergistal    schedule 10.12.2016
comment
@aergistal Я пытался создать проект на другом ПК, чтобы дать вам компенсацию и предоставить дополнительную информацию, но больше не нашел этот шаблон. Похоже, это ошибка, зависящая от среды. Возможно, сбой выравнивания памяти на том ПК, на котором я работал раньше. Как только смогу воспроизвести баг - дам больше информации. В любом случае шаблона в файле не было, и я это знал (извините, если не ясно выразился). Он присутствовал только в AVPacket при чтении файла с помощью ffmpeg.   -  person ElDorado    schedule 11.12.2016
comment
@aergistal Я нашел проблему. В любом случае я очень благодарна вам и szatmary за то, что не оставили меня в покое и пытались помочь.   -  person ElDorado    schedule 13.12.2016


Ответы (1)


Итак, я нашел проблему.

TL;DR:

pInputFormatContext->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;

сразу после avformat_open_input

Объяснение:

Я обнаружил во время отладки, что AVPacket был испорчен на utils.c:1661 во время выполнения

av_packet_merge_side_data(pkt);

Более того, я нашел последовательность тех дополнительных данных, которые видели ранее:

#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL

используется в av_packet_merge_side_data

Тип данных Side в AVPacket — AV_PKT_DATA_MPEGTS_STREAM_ID (78), который используется только в демультиплексорах и мультиплексорах, но не в кодеках.

Я был сбит с толку, когда прочитал аннотацию к av_read_frame, которую я использовал для чтения данных кадра из файла:

Return the next frame of a stream.
This function returns what is stored in the file, and does not validate
that what is there are valid frames for the decoder. It will split what is
stored in the file into frames and return one for each call. It will not
omit invalid data between valid frames so as to give the decoder the maximum
information possible for decoding.

Я совершенно не понимаю, почему флаги потоков различаются на двух компьютерах, которые я использовал, но отключение слияния сторонних данных с данными пакета помогло.

Поэтому я думаю, что проблема с документацией ffmpeg заключается в том, что он заверил меня, что «мне будет возвращено то, что хранится в файле», не упоминая, что могут быть добавлены некоторые дополнительные данные.

person ElDorado    schedule 13.12.2016