ultravideo / kvazaar

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

Question about set different QP for different CUs #222

Closed Dillon14281118 closed 5 years ago

Dillon14281118 commented 5 years ago

I want to divid the CUs into two classes and set different QP for them, how can I do that? Which function in the source code I need to change? And if kvazaar supports adaptive quantization and how to turn on?

fador commented 5 years ago

For what I know, you would have to set encoder->max_qp_delta_depth to something bigger (0 == 64x64) https://github.com/ultravideo/kvazaar/blob/master/src/encoder.c#L380

You need to modify the call to set_cu_qps() to start from higher depth in each lcu, and use your class data for last_qp: https://github.com/ultravideo/kvazaar/blob/master/src/encoderstate.c#L632

I have no idea if it works this easily, but those changes should do it.

We don't have adaptive quantization implemented at the moment.

Dillon14281118 commented 5 years ago

And how can I chang QP at CTU level? For example,I have the (x,y) coordinate of a CTU and I want to set its QP, what should I do?Which function in the source code I need to change?

fador commented 5 years ago

We have that also as a commanline parameter, --roi The file is just width and height followed by an array of delta qp's, like:

 3  3
-1   2  -2
 2  -3  -2
 1   2   3

..but if you want to set that for each frame separately then I think you can set roi.width, roi.height and roi.dqps manually at the start of the frame.. https://github.com/ultravideo/kvazaar/blob/master/src/encoder.c#L347 example initialization done here, but width and height are already defined in this case.

Maybe you could define that in encoder_state_init_new_frame() https://github.com/ultravideo/kvazaar/blob/master/src/encoderstate.c#L1171

It's just x times y array of int8_t for QP offset for that region, and you can define x and y to be width/64 to have a delta QP for each LCU.

If you want to set only one LCU QP, you can set rest of the values to 0 and one value to the difference from the base QP so -20 .. 20 or so

..and as I said previously, I'm not completely sure it will work since I have not done things like that =)

Dillon14281118 commented 5 years ago

How do the delta qp's influence the QP specifically? And how does kvazaar detect ROIs? ...Can I realize my idea by change "kvz_set_lcu_lambda_and_qp(encoder_state_t * const state, vector2d_t pos)" function? state->qp = state->frame->QP; state->lambda = state->frame->lambda; state->lambda_sqrt = sqrt(state->frame->lambda); set Qp and lambda directly in this part. https://github.com/ultravideo/kvazaar/blob/2ce1ef25c55e3a552e63f5cff7ea2e4f7c3921ae/src/rate_control.c#L278

fador commented 5 years ago

Delta QPs are just offsets from the base QP of the frame, offset 2 to a CU in frame with QP 22 will result in QP 24 for that CU.

Kvazaar does not detect the ROI, it is provided by the user at the moment..

Dillon14281118 commented 5 years ago

But the roi text resolution is not equal to the frame's resolution ,so how can I control each LCU 'qp exactly?

fador commented 5 years ago

You can just use larger width and height as the first two values in the file, for 1080p to control each LCU/CTU:

30 17
<array of 30*17>
Dillon14281118 commented 5 years ago

Thank you very much! It really works,I have ever realize similar function in HM. But HM is very very slow,so I replace it with kvazaar,it helps.

fador commented 5 years ago

No problem, nice to be able to help. Yes, Kvazaar is a bit faster ;) I'll close this issue since it seems to be solved.

praneet195 commented 3 years ago

Hi @Dillon14281118 , Can you please help me realize this functionality in HM. I'm a little confused with HM because i'm able to change the quantization for each CU but HM has a per slice quantization as well. How do I change this ? It would be great if someone could guide me through this. Thank you