struct intel_encoder_context* encoder_context)
{
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- double bitrate = encoder_context->brc.bits_per_second[0];
- double framerate = (double)encoder_context->brc.framerate_per_100s[0] / 100.0;
+ double bitrate, framerate;
+ double qp1_size = 0.1 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
+ double qp51_size = 0.001 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
+ double bpf, factor;
int inum = encoder_context->brc.num_iframes_in_gop,
pnum = encoder_context->brc.num_pframes_in_gop,
bnum = encoder_context->brc.num_bframes_in_gop; /* Gop structure: number of I, P, B frames in the Gop. */
int intra_period = encoder_context->brc.gop_size;
- double qp1_size = 0.1 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
- double qp51_size = 0.001 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
- double bpf;
int i;
mfc_context->brc.mode = encoder_context->rate_control_mode;
- for (i = 0; i < 3; i++) {
- mfc_context->brc.qp_prime_y[i] = 26;
- }
-
- mfc_context->brc.target_frame_size[SLICE_TYPE_I] = (int)((double)((bitrate * intra_period)/framerate) /
- (double)(inum + BRC_PWEIGHT * pnum + BRC_BWEIGHT * bnum));
- mfc_context->brc.target_frame_size[SLICE_TYPE_P] = BRC_PWEIGHT * mfc_context->brc.target_frame_size[SLICE_TYPE_I];
- mfc_context->brc.target_frame_size[SLICE_TYPE_B] = BRC_BWEIGHT * mfc_context->brc.target_frame_size[SLICE_TYPE_I];
-
mfc_context->brc.gop_nums[SLICE_TYPE_I] = inum;
mfc_context->brc.gop_nums[SLICE_TYPE_P] = pnum;
mfc_context->brc.gop_nums[SLICE_TYPE_B] = bnum;
- bpf = mfc_context->brc.bits_per_frame = bitrate/framerate;
-
mfc_context->hrd.buffer_size = encoder_context->brc.hrd_buffer_size;
mfc_context->hrd.current_buffer_fullness =
(double)(encoder_context->brc.hrd_initial_buffer_fullness < mfc_context->hrd.buffer_size) ?
mfc_context->hrd.buffer_capacity = (double)mfc_context->hrd.buffer_size/qp1_size;
mfc_context->hrd.violation_noted = 0;
- if ((bpf > qp51_size) && (bpf < qp1_size)) {
- mfc_context->brc.qp_prime_y[SLICE_TYPE_P] = 51 - 50*(bpf - qp51_size)/(qp1_size - qp51_size);
- }
- else if (bpf >= qp1_size)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_P] = 1;
- else if (bpf <= qp51_size)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_P] = 51;
+ for (i = 0; i < encoder_context->layer.num_layers; i++) {
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I] = 26;
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 26;
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_B] = 26;
+
+ if (i == 0) {
+ bitrate = encoder_context->brc.bits_per_second[0];
+ framerate = (double)encoder_context->brc.framerate_per_100s[0] / 100.0;
+ } else {
+ bitrate = (encoder_context->brc.bits_per_second[i] - encoder_context->brc.bits_per_second[i - 1]);
+ framerate = (double)(encoder_context->brc.framerate_per_100s[i] - encoder_context->brc.framerate_per_100s[i - 1]) / 100.0;
+ }
+
+ if (i == encoder_context->layer.num_layers - 1)
+ factor = 1.0;
+ else
+ factor = (double)encoder_context->brc.framerate_per_100s[i] / encoder_context->brc.framerate_per_100s[i + 1];
+
+ mfc_context->brc.target_frame_size[i][SLICE_TYPE_I] = (int)((double)((bitrate * intra_period * factor)/framerate) /
+ (double)(inum + BRC_PWEIGHT * pnum * factor + BRC_BWEIGHT * bnum * factor));
+ mfc_context->brc.target_frame_size[i][SLICE_TYPE_P] = BRC_PWEIGHT * mfc_context->brc.target_frame_size[i][SLICE_TYPE_I];
+ mfc_context->brc.target_frame_size[i][SLICE_TYPE_B] = BRC_BWEIGHT * mfc_context->brc.target_frame_size[i][SLICE_TYPE_I];
+
+ bpf = mfc_context->brc.bits_per_frame[i] = bitrate/framerate;
+
+ if ((bpf > qp51_size) && (bpf < qp1_size)) {
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 51 - 50*(bpf - qp51_size)/(qp1_size - qp51_size);
+ }
+ else if (bpf >= qp1_size)
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 1;
+ else if (bpf <= qp51_size)
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 51;
- mfc_context->brc.qp_prime_y[SLICE_TYPE_I] = mfc_context->brc.qp_prime_y[SLICE_TYPE_P];
- mfc_context->brc.qp_prime_y[SLICE_TYPE_B] = mfc_context->brc.qp_prime_y[SLICE_TYPE_I];
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I] = mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P];
+ mfc_context->brc.qp_prime_y[i][SLICE_TYPE_B] = mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I];
- BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_I], 1, 51);
- BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_P], 1, 51);
- BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_B], 1, 51);
+ BRC_CLIP(mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I], 1, 51);
+ BRC_CLIP(mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P], 1, 51);
+ BRC_CLIP(mfc_context->brc.qp_prime_y[i][SLICE_TYPE_B], 1, 51);
+ }
}
int intel_mfc_update_hrd(struct encode_state *encode_state,
- struct gen6_mfc_context *mfc_context,
+ struct intel_encoder_context *encoder_context,
int frame_bits)
{
+ struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
double prev_bf = mfc_context->hrd.current_buffer_fullness;
mfc_context->hrd.current_buffer_fullness -= frame_bits;
return BRC_UNDERFLOW;
}
- mfc_context->hrd.current_buffer_fullness += mfc_context->brc.bits_per_frame;
+ mfc_context->hrd.current_buffer_fullness += mfc_context->brc.bits_per_frame[encoder_context->layer.curr_frame_layer_id];
if (mfc_context->hrd.buffer_size > 0 && mfc_context->hrd.current_buffer_fullness > mfc_context->hrd.buffer_size) {
if (mfc_context->brc.mode == VA_RC_VBR)
mfc_context->hrd.current_buffer_fullness = mfc_context->hrd.buffer_size;
}
int intel_mfc_brc_postpack(struct encode_state *encode_state,
- struct gen6_mfc_context *mfc_context,
+ struct intel_encoder_context *encoder_context,
int frame_bits)
{
+ struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
gen6_brc_status sts = BRC_NO_HRD_VIOLATION;
VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
int slicetype = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
- int qpi = mfc_context->brc.qp_prime_y[SLICE_TYPE_I];
- int qpp = mfc_context->brc.qp_prime_y[SLICE_TYPE_P];
- int qpb = mfc_context->brc.qp_prime_y[SLICE_TYPE_B];
+ int curr_frame_layer_id, next_frame_layer_id;
+ int qpi, qpp, qpb;
int qp; // quantizer of previously encoded slice of current type
int qpn; // predicted quantizer for next frame of current type in integer format
double qpf; // predicted quantizer for next frame of current type in float format
* y - how far we are from target HRD buffer fullness
*/
double x, y;
- double frame_size_alpha;
+ double frame_size_alpha, factor;
+
+ if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0) {
+ curr_frame_layer_id = 0;
+ next_frame_layer_id = 0;
+ } else {
+ curr_frame_layer_id = encoder_context->layer.curr_frame_layer_id;
+ next_frame_layer_id = encoder_context->layer.frame_layer_ids[encoder_context->num_frames_in_sequence % encoder_context->layer.size_frame_layer_ids];
+ }
+
+ /* checking wthether HRD compliance first */
+ sts = intel_mfc_update_hrd(encode_state, encoder_context, frame_bits);
- qp = mfc_context->brc.qp_prime_y[slicetype];
+ if (sts == BRC_NO_HRD_VIOLATION) { // no HRD violation
+ /* nothing */
+ } else {
+ next_frame_layer_id = curr_frame_layer_id;
+ }
+
+ if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0)
+ factor = 1.0;
+ else
+ factor = (double)encoder_context->brc.framerate_per_100s[next_frame_layer_id] / encoder_context->brc.framerate_per_100s[encoder_context->layer.num_layers - 1];
+
+ qpi = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I];
+ qpp = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P];
+ qpb = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B];
- target_frame_size = mfc_context->brc.target_frame_size[slicetype];
+ qp = mfc_context->brc.qp_prime_y[next_frame_layer_id][slicetype];
+
+ target_frame_size = mfc_context->brc.target_frame_size[next_frame_layer_id][slicetype];
if (mfc_context->hrd.buffer_capacity < 5)
frame_size_alpha = 0;
else
- frame_size_alpha = (double)mfc_context->brc.gop_nums[slicetype];
+ frame_size_alpha = (double)mfc_context->brc.gop_nums[slicetype] * factor;
if (frame_size_alpha > 30) frame_size_alpha = 30;
frame_size_next = target_frame_size + (double)(target_frame_size - frame_bits) /
(double)(frame_size_alpha + 1.);
/* making sure that with QP predictions we did do not leave QPs range */
BRC_CLIP(qpn, 1, 51);
- /* checking wthether HRD compliance is still met */
- sts = intel_mfc_update_hrd(encode_state, mfc_context, frame_bits);
-
/* calculating QP delta as some function*/
x = mfc_context->hrd.target_buffer_fullness - mfc_context->hrd.current_buffer_fullness;
if (x > 0) {
/* correcting QPs of slices of other types */
if (slicetype == SLICE_TYPE_P) {
if (abs(qpn + BRC_P_B_QP_DIFF - qpb) > 2)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_B] += (qpn + BRC_P_B_QP_DIFF - qpb) >> 1;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B] += (qpn + BRC_P_B_QP_DIFF - qpb) >> 1;
if (abs(qpn - BRC_I_P_QP_DIFF - qpi) > 2)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_I] += (qpn - BRC_I_P_QP_DIFF - qpi) >> 1;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I] += (qpn - BRC_I_P_QP_DIFF - qpi) >> 1;
} else if (slicetype == SLICE_TYPE_I) {
if (abs(qpn + BRC_I_B_QP_DIFF - qpb) > 4)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_B] += (qpn + BRC_I_B_QP_DIFF - qpb) >> 2;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B] += (qpn + BRC_I_B_QP_DIFF - qpb) >> 2;
if (abs(qpn + BRC_I_P_QP_DIFF - qpp) > 2)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_P] += (qpn + BRC_I_P_QP_DIFF - qpp) >> 2;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P] += (qpn + BRC_I_P_QP_DIFF - qpp) >> 2;
} else { // SLICE_TYPE_B
if (abs(qpn - BRC_P_B_QP_DIFF - qpp) > 2)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_P] += (qpn - BRC_P_B_QP_DIFF - qpp) >> 1;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P] += (qpn - BRC_P_B_QP_DIFF - qpp) >> 1;
if (abs(qpn - BRC_I_B_QP_DIFF - qpi) > 4)
- mfc_context->brc.qp_prime_y[SLICE_TYPE_I] += (qpn - BRC_I_B_QP_DIFF - qpi) >> 2;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I] += (qpn - BRC_I_B_QP_DIFF - qpi) >> 2;
}
- BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_I], 1, 51);
- BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_P], 1, 51);
- BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_B], 1, 51);
+ BRC_CLIP(mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I], 1, 51);
+ BRC_CLIP(mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P], 1, 51);
+ BRC_CLIP(mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B], 1, 51);
} else if (sts == BRC_UNDERFLOW) { // underflow
if (qpn <= qp) qpn = qp + 1;
if (qpn > 51) {
}
}
- mfc_context->brc.qp_prime_y[slicetype] = qpn;
+ mfc_context->brc.qp_prime_y[next_frame_layer_id][slicetype] = qpn;
return sts;
}
{
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
unsigned int rate_control_mode = encoder_context->rate_control_mode;
- int target_bit_rate = encoder_context->brc.bits_per_second[0];
+ int target_bit_rate = encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1];
// current we only support CBR mode.
if (rate_control_mode == VA_RC_CBR) {
if (encoder_context->rate_control_mode == VA_RC_CQP)
qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
else
- qp = mfc_context->brc.qp_prime_y[slice_type];
+ qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
if (vme_state_message == NULL)
return;
if (encoder_context->rate_control_mode == VA_RC_CQP)
qp = q_matrix->quantization_index[0];
else
- qp = mfc_context->brc.qp_prime_y[slice_type];
+ qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
lambda = intel_lambda_qp(qp * QP_MAX / VP8_QP_MAX);
if (encoder_context->rate_control_mode == VA_RC_CQP)
qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
else
- qp = mfc_context->brc.qp_prime_y[slice_type];
+ qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
#define USE_SCOREBOARD (1 << 21)
int qp;
int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
- qp = mfc_context->brc.qp_prime_y[slice_type];
+ qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
intel_h264_enc_roi_cbr(ctx, qp, pParamROI,encode_state, encoder_context);
} else if (encoder_context->rate_control_mode == VA_RC_CQP){