ultravideo / kvazaar

An open-source HEVC encoder
BSD 3-Clause "New" or "Revised" License
831 stars 178 forks source link

About ROI-Based coding and QP setting #226

Open pengxiaopx opened 5 years ago

pengxiaopx commented 5 years ago

Hi, as my understanding, the following setting will get same results, but the results are different.

  1. kvazaar --input input.yuv --input-res=352x288 --qp 28 --roi roi.txt --output out.hevc roi.txt is: 1 2 0 0
  2. kvazaar --input input.yuv --input-res=352x288 --roi roi.txt --output out.hevc roi.txt is: 1 2 6 6 Could you tell me why the results are different?
Arizer commented 5 years ago

Hi,

Generally larger absolute values are more expensive to code than smaller ones. Different coding methods for coding delta QPs are involved and part of the reason for this behaviour in this case.

The final QPs for blocks should still be identical with both of your options.

In case you are interested, this is how QP deltas are coded in Kvazaar: https://github.com/ultravideo/kvazaar/blob/master/src/encode_coding_tree.c#L269-L289

pengxiaopx commented 5 years ago

Thank you for your reply. Actually, I ran a sequence with the two options, results of bits and PSNR is listed as follows,

  1. kvazaar --input input.yuv --input-res=352x288 --qp 28 --roi roi.txt --output out.hevc roi.txt is: 1 2 0 0 Bits: 1994344, PSNR: 36.9817
  2. kvazaar --input input.yuv --input-res=352x288 --roi roi.txt --output out.hevc roi.txt is: 1 2 6 6 Bits: 2445736, PSNR: 37.2556 As my understanding, the roi.txt defines the CU delta QP. final CU QP=initial QP + slice delta QP + CU delta QP.
    In Case 1, the command --qp 28 is setting the initial QP to 28, CU delta QP =0, In Case 2, the initial QP is the default value 22, CU delta QP =6, Since CU delta QP should signaled many times, Case 2 with the larger CU delta QP needs more bits. This is why the bits of Case 2 is more than case 1. Is the above understanding right? However, since the final CU QP for the two cases are identical, I think the PSNR for the two cases should be the same. Could you tell me why they are different?
Arizer commented 5 years ago

You seem have the right idea.

I think you ran into a bug. I had a look at some code and I see at least one issue in our rate-distortion optimization where the (sqrt) lambda parameter is not set correctly with our ROI enabled which leads to different encoding decisions. Need to investigate this later.

pengxiaopx commented 5 years ago

Thank you for your reply. For the QP setting for different parts, there is another strange result in my test. In my test, for a sequence, each frame are departed into 64 (8x8) blocks. 6x6 blocks in the middle of the frame are defined as ROI, the other blocks are defined as Nor_ROI. I ran the sequence with two different delta QP maps. The maps and results for both cases are listed as follows,

Case 1: the roi.txt is 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 PSNR: 40.10; Bits: 7931784

Case 2: the roi.txt is 8 8 20 20 20 20 20 20 20 20 20 0 0 0 0 0 0 20 20 0 0 0 0 0 0 20 20 0 0 0 0 0 0 20 20 0 0 0 0 0 0 20 20 0 0 0 0 0 0 20 20 0 0 0 0 0 0 20 20 20 20 20 20 20 20 20 PSNR: 34.00; Bits: 6124408

In Case 1, both the ROI and Nor_ROI are coded with the same QP 22.
In Case 2, ROI is coded with the QP 22, and the other QP are coed with QP 42.

Then I calculate the PSNR for ROI and Nor_ROI separately for both cases. For Case 1, PSNR_ROI: 39.60 PSNR_Nor_ROI: 40.9 For Case 2, PSNR_ROI: 35.40 PSNR_Nor_ROI: 32.60

In my understanding, the roi.txt is used to depart the frame into different tiles. Tiles are independent with each other. Since the QP value of ROI for both cases are the same, the quality of ROI part for both cases should be the same or very close. Is the above understanding right?

In my calculation, the result of PSNR for ROI is 39.6 and 35.4, the difference is very large even the same QP value is used for ROI area.

Could you tell me why they are so different? Is it reasonable?

Arizer commented 5 years ago

Is this any better after the latest commit? Other bugs are probably still present.

One additional issue might be the resolution of your input video since not height or width is a multiple of 64. AFAIK, Kvazaar only sets different QP values for each 64x64 block in a frame. It is possible that some pixels you used for ROI PSNR calculation were actually not coded with the lower QP and vice versa.

Also, PSNR is very much affected by the content of the input video.