Как извлечь векторы движения и информацию о разделе кадра в HEVC HM 16.15

Я использую эталонное программное обеспечение HEVC, версию HM Encoder [16.15] (включая RExt) на [Mac OS X][GCC 4.2.1][64 бит] и хотел бы извлечь на стороне кодировщика: 1) векторы движения для каждый блок 2) информацию о разделе кадра, т. е. размер и местоположение каждого блока в кадре, к которому относится вектор движения.

Есть ли у кого-нибудь подсказки о том, в каких переменных хранится эта информация для каждой единицы кодирования? Спасибо!


person SimonFD    schedule 20.04.2017    source источник
comment
Ответ на этот вопрос должно быть полезно.   -  person damjeux    schedule 20.04.2017


Ответы (1)


Все, что вам нужно, доступно в классе TComDataCU.

1) Для информации о движении есть функция getCUMvField(), которая возвращает вектор движения. Хотя работать с ним непросто.

По сути, чтобы получить доступ практически к любому элементу синтаксиса уровня PU/CU, вам нужно иметь возможность работать с абсолютным индексом этого PU/CU. Этот уникальный индекс сообщает вам, где именно находится ваш PU/CU в CTU, указывая на верхний левый блок 4x4 этой части. Я помню, что в большинстве случаев этот индекс хранится в переменной uiAbsPartIdx.

Если вы научитесь работать с этим индексом, то сможете получить информацию о разбиении блоков на уровне CTU. поэтому для 2) мое предложение состоит в том, что вы переходите на уровень среза, когда у вас есть цикл над CUT (я думаю, что это делается в функции compressSlice()). И после того, как функция compressCtu() вызывается для каждой CTU (что означает, что все решения RDO приняты и принято решение о разбиении CTU), вы зацикливаете все uiAbsPartIdxs CTU и получаете их ширину и высоту. Например, если размер вашего CTU равен 128, то в вашем CTU будет 32*32=1024 уникальных блока 4x4. Функция для получения ширины/высоты CU, соответствующей определенному uiAbsPartIdx, называется pCtu->getWidth(uiAbsPartIdx).

Я надеюсь, что это было ясно.

person Mosen    schedule 21.04.2017
comment
Спасибо за Ваш ответ. Я не понимаю, как зациклить все uiAbsPartIdxs каждой ГТЕ. В compressSlice я нахожусь в цикле for for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr ): как мне получить индексы CU (т.е. uiAbsPartIdx), включенные в текущую CTU, чтобы затем использовать getWidth(uiAbsPartIdx)? Я просто начинаю с 0 и увеличиваю индекс на единицу? и как мне получить общее количество CU внутри CTU? - person SimonFD; 25.04.2017
comment
Допустим, ширина вашего CTU равна 64, что составляет 256 единиц 4x4. Затем, если вы установите boundingCtuAddr=256, вы будете повторять все CU внутри CTU. И для каждого CU вы можете передать этот индекс CU (ctuTsAddr) функциям getHeight и getWidth, чтобы получить размер текущего CU. - person Mosen; 28.04.2017
comment
Но очень важным моментом является то, что когда ваш CU больше, чем 4x4, это означает, что CU покрывается более чем одним юнитом 4x4, и вам нужно быть осторожным, чтобы не рассматривать такой CU более одного раза. Например, если ваш первый CU имеет размер 8x8, то ctuTsAddr=0,1,2,3 будет указывать на этот CU, и если вы используете функции getWidth или getHeight с этими значениями, вы получите размер 8x8 четыре раза. Надеюсь было понятно! - person Mosen; 28.04.2017