Reputation: 2483
I am new to HEVC and I am understanding the reference software now (looking at intra prediction right now).
I need to get information as below after encoding.
I know CTU decision are made when m_pcCuEncoder->compressCtu( pCtu )
is called in TEncSlice.cpp
. But where exactly I can get these specific information? Can someone help me with this?
p.s. I am learning C++ too (I have a Java background).
Upvotes: 2
Views: 1113
Reputation: 468
EDIT: This post is a solution for the encoder side. However, the decoder side solution is far less complex.
Getting CTU information (partitioning etc.) is a bit tricky at encoder if you are new to the code. But I try to help you with it. Everything that I am going to tell you is based on the JEM code and not HM, but I am pretty sure that you can apply them to HM too.
As you might have noticed, there are two completely separate phases for compression/encoding of each CTU:
In the CTU level, these two phases are performed by the m_pcCuEncoder->compressCtu( pCtu )
and the m_pcCuEncoder->encodeCtu( pCtu )
functions, respectively, both in the compressSlice()
function of the TEncSlice.cpp
file.
Given the above information, you must look for what you are looking for, in the second phase and not the first phase (you may already know these things, but I suspected that you might be looking at the first phase).
So, now this is my suggestion for getting your information. It's not the best way to do it, but is easier to explain here. You first go to this point in your HM code:
compressGOP() -> encodeSlice() -> encodeCtu() -> xEncodeCU()
Then you find the line where the prediction mode (intra/inter) is encoded:
m_pcEntropyCoder->encodePredMode()
At this point, you have access to the pcCU
object which contains all the final decisions, including the information you look for, that are made during the first phase. At this point of the code, you are dealing with a single CU and not the entire CTU. But if you want your information for the entire CTU, you may go back to
compressGOP() -> encodeSlice() -> encodeCtu()
and find the line where the xEncodeCU()
function is called for the first time. There, you will have access to the pCtu
object.
Reminder: each TComDataCU
object (pcCU
if you are in the CU level, or pCtu
if you are in the CTU level) of size WxH
is split to NumPartition=(W/4)x(H/4)
partitions of size 4x4
. Each partition is accessible by an index (uiAbsPartIdx
) which indicates its Z-scan order. For example, the uiAbsPartIdx
for the partition at <x=8,y=0>
is 4.
Now, you do the following steps:
Get the number of partitions (NumPartition
) within your pCtu
by calling pCtu->getTotalNumPart()
.
Loop over all NumPartition
partitions and call the functions pCtu->getWidth(idx)
, pCtu->getHeight(idx)
, pCtu->getCUPelX(idx)
and pCtu->getCUPelY()
, where idx
is your loop iterator. These functions return the following information for each CU
coincided with the 4x4
partition at idx
: width, height, positionX, positionY. [both positions are relative to the pixel <0,0>
of the frame]
The above information is enough for deriving the CTU partitioning of the current pCtu
! So the last step is to write a piece of code to do that.
This was an example of how to extract CTU partitioning information during the second phase (i.e. encoding phase). However, you may call some proper functions to get the other information in your second question. For example, to get selected luma intra mode, you may call pCtu->getIntraDir(CHANNEL_TYPE_LUMA, idx)
, instead of getWidth()/getHeight()
functions. Or pCtu->getQP(CHANNEL_TYPE_LUMA, idx)
to get the QP value.
You can always find a list of functions that provide useful information at the pCtu
level, in the TComDataCU
class (TComDataCU.cpp
).
I hope this helps you. If not, let me know!
Good luck,
Upvotes: 7