LINUX.ORG.RU

Узнать порядок кадров в сыром потоке H.264

 ,


0

1

Обычно h264 упакован в контейнер, например mp4, и в этом контейнере (в блоке moov или moof) указывается pts (presentation time) каждого кадра, то есть порядок их показа. Допустим, moov куда-то потерялся, но остался блок mdat, в нём сырой h264. В нём есть информация о порядке кадров или никак нет?

Когда я сконвертировал mp4 в annexb (тоже можно считать без контейнера) - mpv получившийся файл успешно показывал, и вроде даже нормально выглядело. Хотя, допускаю, что кадры там показывались в порядке кодирования, а я просто не заметил разницы от мелких перестановок.

★★★★★

Последнее исправление: hobbit (всего исправлений: 1)

Полагаю, в 99% видео кадры просто идут по порядку. Эта фича для каких-то особых ситуаций. Посмотри что с порядком у других файлов, у которых ничего не потеряно.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от KivApple

Полагаю, в 99% видео кадры просто идут по порядку.

Так и есть. PTS исключительно для синхронизации нужен, типа, чтобы скорость не плавала, и чтобы аудио/видео не разъезжались.

Переставить их вообще было бы максимально трудно. Ведь там идёт сначала базовый кадр, а потом - несколько кадров, где закодированы только дельты смещений. Попробуй тут попереставляй - отсчитаешь смещения не от того кадра.

anonmyous ★★
()
Ответ на: комментарий от KivApple

Нет, наоборот, в подавляющем большинстве (если не во всех) видео есть b-фреймы, которые расположены после всех своих зависимостей, притом что pts у них меньше части из них. Собственно, поскольку про b-фреймы обычно говорят в контексте кодека, а не контейнера, я и подозреваю что из h264 можно как-то и эту информацию узнать.

Эти перестановки обычно в пределах нескольких фреймов, например в файле I P B B B, а показывается I B B B P (P сдвинут вперёд на 3 кадра, B кадры сдвинуты назад). При 30 фпс это перестановки в пределах 0.1 сек, возможно их сложно глазом заметить.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от slew

Полезная статья, надо будет почитать (как и сам стандарт h.264), но это надолго, а про вопрос из темы есть надежда что кто-нить ответит быстрее.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

притом что pts у них меньше части из них.

PTS тут вообще не при чём, он только для синхронизации. Ладно бы ты ещё про DTS говорил - эти таймстемпы, хотя бы, к декодированию относятся. Но, разумеется, никакие таймстемпы не дадут нормально привязываться к нескольким фреймам, так что тебе придётся осилить вот этот документ: https://ocw.unican.es/pluginfile.php/2825/course/section/2777/FinalDraftH.264.pdf

А конкретно, главу 8.3.6.3 Default index orders:

 When decoding a B slice, there may be two reference indices used
per block each pointing into a separate lists of reference indices
which are called the first reference index list and second
reference index list.
The first reference index list and the second reference index list
have default mappings to the pictures numbers in the
reference picture buffer as defined below.

И далее по тексту.

anonmyous ★★
()
Ответ на: комментарий от anonmyous

Ты вот эти ссылки на документы итд - из своих знаний сюда привёл или решил пересказать в тему ответ поисковой системы или какого-то ии? Если второе, то зря, не надо этим заниматься. Если первое, то ты не прав.

pts при чём. Это именно то время, когда кадр выводится на экран. dts же это внутренний счётчик (сумма) длительностей распарсенных кадров в том порядке как они в потоке байт были присланы. Нужен он с единственной целью: в mp4 pts-ы записаны не абсолютными числами, а смещениями от dts, поэтому вторые приходится тоже помнить, хотя бы временно. Посчитать dts по сырому h264 проблем не представляет - это просто номер кадра, поделённый на fps который мы уж как-нить сможем узнать/угадать. Хотя если fps плавающий (но я таких видео не встречал) то такой способ не годится.

Зачем ты мне прислал цитату про межкадровые ссылки тоже непонятно, я про них не спрашивал, всё-таки подозреваю что ты не своим умом этот ответ сочинил.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

pts при чём. Это именно то время, когда кадр выводится на экран.

И? Это и нужно для синхронизации. А в выходной очереди декодера кадры разложены по DTS, и PTS их уже не будет переупорядочивать. При этом, для того, чтобы декодировать кадры, нужно именно ссылки парсить. По DTSам их можно разложить в буфере уже потом, когда они декодированы. И да, DTS их может переупорядочить относительно битстрима, но PTS уже потом порядок не изменяет, насколько мне известно.

По этому. Порядок декодирования определяется битстримом. Зависимости между кадрами определяются индексными ссылками. Порядок отправки в выходную очередь определяется DTS. А PTS отвечает за синхронизацию (и вряд ли меняет порядок относительно DTS).

anonmyous ★★
()
Ответ на: комментарий от anonmyous

Хватит глупости писать. dts не может ничего «переупорядочивать», это и есть «порядок битстрима», он же «порядок выходной очереди декодера». И вопрос был, в который раз повторю, не про неё, а про порядок показа. Это - другой порядок, он определяется PTS.

А PTS отвечает за синхронизацию (и вряд ли меняет порядок относительно DTS).

Запусти ffprobe на любое mp4 видео и увидь.

ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 filename.mp4
firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Это - другой порядок, он определяется PTS.

Да не особо там нужен PTS, можно порядок понять и без него. У B-фрейма будут 2 ссылки - вперёд и назад. При этом, в битстриме оба этих кадра будут располагаться перед ним, но, однако, вполне понятно, что тот, который через «переднюю» ссылку доступен, должен быть показан после этого B-фрейма, то есть передвинут.

К тому же, там есть счётчик PicOrderCnt, который, судя по всему, как раз и даёт корректный порядок, даже если у нас 2 B-фрейма подряд идут, и одними ссылками их упорядочить нельзя. В общем, PTS таки не при чём.

anonmyous ★★
()
Последнее исправление: anonmyous (всего исправлений: 1)
Ответ на: комментарий от firkax

Это - другой порядок, он определяется PTS.

Поищи переменные AbsFrameNum & PicOrderCnt по ссылке, что я давал. Ничего, кроме синхронизации, PTSами определяться не должно, не для этого они. А вот те переменные - судя по всему, как раз для этого.

anonmyous ★★
()
Ответ на: комментарий от firkax

Хватит глупости писать. dts не может ничего «переупорядочивать», это и есть «порядок битстрима»

Кто здесь пишет глупости - надо ещё разобраться. Да, гугловая нейронка на вашей стороне. Но есть прикладные статьи, типа вот этой: https://www.elecard.com/ru/page/timestamp_validation_in_transport_stream

PTS и DTS имеют разрешение 90 кГц. Максимальное значение 233 - 1,
система является цикличной. Значения должны монотонно возрастать
с каждым последующим PES пакетом. Данное утверждение справедливо
для видео кадров в display последовательности.  
! В процессе сжатия энкодер может переупорядочить кадры, создав
две последовательности:

    stream, в которой кадры были сжаты и уложены в поток;
    display, в которой кадры будут воспроизведены.

И далее:

График показывает разницу между PTS и DTS. В нормальных условиях
график имеет вид константы, но возможны небольшие коллебания в
верхнюю область.

Понимаете? PTS/DTS монотонно возрастают лишь в display потоке, а разница между ними - константа.

В вашем же мире - DTS монотонно возрастает в стриме, а PTS - в дисплей потоке. Но ведь такая схема бы порождала долгоживущие дырки в дисплей потоке! Вы декодировали P-frame и положили его в дисплей-очередь с отступом. Теперь там дырка. Вы берёте следующий кадр (B) чтобы её закрыть, а DTS вам говорит: «рановато». Вы ставите декодер на паузу и идёте пить чай, а дырка, между тем, никуда не делась.

В моём же мире, равно как и в статье по ссылке выше, дырки невозможны, так как у B-фрейма DTS будет гарантированно меньше предыдущего. То есть, вы его гарантированно декодируете сразу, и дырка будет закрыта.

Опять же, согласие с вами гугловой нейронки, конечно, посеяло во мне сомнения, но я считаю, что всё это - малозначительные детали. Куда важнее то, что и PTS, и DTS нужны исключительно для синхронизации. Поймите вы это наконец: не могут временные метки отвечать за корректность декодирования, за корректность порядка следования кадров и пр - не для этого они!

Порядок кадров на входе определяется битстримом, а на выходе - межкадровыми ссылками и счётчиками типа AbsFrameNum & PicOrderCnt. Но никак не метками времени.

anonmyous ★★
()
Ответ на: комментарий от anonmyous

Но есть прикладные статьи, типа вот этой: https://www.elecard.com/ru/page/timestamp_validation_in_transport_stream

Во-первых, не путай mp4 и mp2ts, это совершенно разные форматы, несмотря на схожее название и вероятно местами общих авторов (твоя статья про второе). Во-вторых в mp2ts dts тоже идёт в порядке декодирования, а порядок показа определяется pts.

Понимаете? PTS/DTS монотонно возрастают лишь в display потоке, а разница между ними - константа.

А это просто враньё.

Вы берёте следующий кадр (B) чтобы её закрыть, а DTS вам говорит: «рановато».

Ты бредишь.

гугловой нейронки,

Вобщем ясно откуда ты свои ответы берёшь, продолжать диалог не будем.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

А это просто враньё.

Нет, цитата из статьи. Я дал не только ссылку, но и выделил цитаты. Ты что, реально слепой, и не заметил цитаты?

Вобщем ясно откуда ты свои ответы берёшь, продолжать диалог не будем.

Конечно ясно, если я и ссылки привожу, и цитаты. Открыл Америку, мля. :) А лучше бы открыл ссылку на описание AbsFrameNum & PicOrderCnt, которую я тоже приводил.

anonmyous ★★
()
Ответ на: комментарий от anonmyous

Нет, цитата из статьи. Я дал не только ссылку, но и выделил цитаты. Ты что, реально слепой, и не заметил цитаты?

То, что это цитата из статьи, не отменяет того факта, что это враньё. Но ты его, вероятно, не сам наврал, а скопипастил чужое. В интернете по рандомным ссылкам из поиска вообще часто враньё находится, а чтобы отличить его от не-вранья, надо вручную проверять (в данном случае - писать парсер этого всего и смотреть что получается из mp4 файлов). Я это делал, а ты - нет.

А лучше бы открыл ссылку на описание AbsFrameNum & PicOrderCnt, которую я тоже приводил.

Ссылку (а точнее главу 8.2 стандарта) я разумеется посмотрю.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

Во-первых, не путай mp4 и mp2ts, это совершенно разные форматы,

Если бы ты хоть немного был в теме, то понимал бы, TS у них один и тот же, а различается лишь ES (elementary stream). А PTS/DTS относятся к PES, а не к ES.

anonmyous ★★
()
Ответ на: комментарий от firkax

То, что это цитата из статьи, не отменяет того факта, что это враньё.

Ты мои сообщения читаешь вообще? Я ведь уже сказал, что инфа из статьи, и правда, не соответствует, например, тому, что гугловая нейронка говорит. Но ещё раз: это всё - детали. Основной поинт - что маркеры времени из PES нужны исключительно для синхронизации.

anonmyous ★★
()
Ответ на: комментарий от firkax

Во-первых, не путай mp4 и mp2ts, это совершенно разные форматы,

Да что тебе не ясно-то, ё-моё? TS создаётся муксером, а не кодеком. Кодеком создаётся ES. Потом он нарезается на PES и муксится в TS. Какой там был кодек - mp2 или mp4 - никого уже не волнует на этом этапе.

Так хоть понятно?

anonmyous ★★
()
Ответ на: комментарий от firkax

Да я уж не знаю, ну хотя бы то, что PTS/DTS входят в PES, а не в ES - хоть это-то понятно? Как они могут хоть на что-то влиять, если они даже в ES не входят?

Не, ну ещё проще я уже не смогу объяснить. :) Это, пожалуй, максимум.

anonmyous ★★
()

зачем тебе это? да в сыром h264 есть порядок и ты легко можешь проверить точно. берешь mp4 декодируешь в png, забираешь из mp4 перепаковываешь в сырой h264 annexb и декодируешь в png. исходник сгенерируй такой, в котором написан номер кадра. сравнивай png по порядку из двух источников

anonymous
()
Ответ на: комментарий от anonmyous

нет, это зачем то сюда mpegts с его терминологией притянули, mp4 существенно отличается от mpegts и на уровне упаковки и как там h264 раскладывается; ничем mpegts тсу не поможет в понимании

anonymous
()
Ответ на: комментарий от anonymous

mp4 существенно отличается от mpegts и на уровне упаковки и как там h264 раскладывается;

А какая разница? Ведь нам важно только, на каком уровне приделываются тайм-стемпы. Что они не кодеком проставляются, а муксером. Я думаю, это фундаментально для любых вариантов mpeg.

Да и h264 же вполне можно и в mpegts завернуть. По-моему, в DVB именно так и делают, или я не прав?

anonmyous ★★
()
Последнее исправление: anonmyous (всего исправлений: 1)