harish
harish

Reputation: 2483

Get some information from HEVC reference software

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

Answers (1)

Mosen
Mosen

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:

  1. The RDO phase: first there is the Rate-Distortion Optimization loop to "make the decisions". In this phase, literally all possible combinations of the parameters are tested (e.g. differetn partitionings, intra modes, filters etc.). At the end of this phase the RDO determines the best combination and passes them to the second phase.
  2. The encoding phase: Here the encoder does the actual final encoding step. This includes writing all the bins into the bitstream, based on the parameters determined during the RDO phase.

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:

  1. Get the number of partitions (NumPartition) within your pCtu by calling pCtu->getTotalNumPart().

  2. 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]

  3. 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

Related Questions