Store intra coding bit costs to CU structure

This commit is contained in:
Marko Viitanen 2014-03-11 12:15:50 +02:00
parent bdf8166e5c
commit aa0fb6ccad
3 changed files with 27 additions and 14 deletions

View file

@ -252,14 +252,16 @@ static uint32_t intra_pred_ratecost(int16_t mode, int8_t *intra_preds)
This function derives the prediction samples for planar mode (intra coding). This function derives the prediction samples for planar mode (intra coding).
*/ */
int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t recstride, int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t recstride,
uint8_t width, pixel *dst, int32_t dststride, uint32_t *sad_out, int8_t *intra_preds) uint8_t width, pixel *dst, int32_t dststride, uint32_t *sad_out,
int8_t *intra_preds, uint32_t *bitcost_out)
{ {
uint32_t best_sad = 0xffffffff; uint32_t best_sad = 0xffffffff;
uint32_t sad = 0; uint32_t sad = 0;
int16_t best_mode = 1; int16_t best_mode = 1;
uint32_t best_bitcost = 0;
int32_t x,y; int32_t x,y;
int16_t i; int16_t i;
uint32_t ratecost = 0; uint32_t bitcost = 0;
cost_16bit_nxn_func cost_func = get_sad_16bit_nxn_func(width); cost_16bit_nxn_func cost_func = get_sad_16bit_nxn_func(width);
@ -279,6 +281,7 @@ int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t re
sad += additional_sad;\ sad += additional_sad;\
if(sad < best_sad)\ if(sad < best_sad)\
{\ {\
best_bitcost = bitcost;\
best_sad = sad;\ best_sad = sad;\
best_mode = mode;\ best_mode = mode;\
COPY_PRED_TO_DST();\ COPY_PRED_TO_DST();\
@ -308,8 +311,8 @@ int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t re
for (i = 0; i < (int32_t)(width*width); i++) { for (i = 0; i < (int32_t)(width*width); i++) {
pred[i] = val; pred[i] = val;
} }
ratecost = intra_pred_ratecost(1,intra_preds)*(int)(g_cur_lambda_cost+0.5); bitcost = intra_pred_ratecost(1,intra_preds);
CHECK_FOR_BEST(1,ratecost); CHECK_FOR_BEST(1,bitcost*(int)(g_cur_lambda_cost+0.5));
} }
// Check angular not requiring filtering // Check angular not requiring filtering
@ -317,8 +320,8 @@ int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t re
int distance = MIN(abs(i - 26),abs(i - 10)); //!< Distance from top and left predictions int distance = MIN(abs(i - 26),abs(i - 10)); //!< Distance from top and left predictions
if(distance <= threshold) { if(distance <= threshold) {
intra_get_angular_pred(rec, recstride, pred, width, width, i, filter); intra_get_angular_pred(rec, recstride, pred, width, width, i, filter);
ratecost = intra_pred_ratecost(i,intra_preds)*(int)(g_cur_lambda_cost+0.5); bitcost = intra_pred_ratecost(i,intra_preds);
CHECK_FOR_BEST(i,ratecost); CHECK_FOR_BEST(i,bitcost*(int)(g_cur_lambda_cost+0.5));
} }
} }
@ -326,8 +329,8 @@ int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t re
// Test planar mode (always filtered) // Test planar mode (always filtered)
intra_get_planar_pred(rec_filtered, recstride, width, pred, width); intra_get_planar_pred(rec_filtered, recstride, width, pred, width);
ratecost = intra_pred_ratecost(0,intra_preds)*(int)(g_cur_lambda_cost+0.5); bitcost = intra_pred_ratecost(0,intra_preds);
CHECK_FOR_BEST(0,ratecost); CHECK_FOR_BEST(0,bitcost*(int)(g_cur_lambda_cost+0.5));
// Check angular predictions which require filtered samples // Check angular predictions which require filtered samples
// TODO: add conditions to skip some modes on borders // TODO: add conditions to skip some modes on borders
@ -336,13 +339,14 @@ int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t re
int distance = MIN(abs(i-26),abs(i-10)); //!< Distance from top and left predictions int distance = MIN(abs(i-26),abs(i-10)); //!< Distance from top and left predictions
if(distance > threshold) { if(distance > threshold) {
intra_get_angular_pred(rec_filtered, recstride, pred, width, width, i, filter); intra_get_angular_pred(rec_filtered, recstride, pred, width, width, i, filter);
ratecost = intra_pred_ratecost(i,intra_preds)*(int)(g_cur_lambda_cost+0.5); bitcost = intra_pred_ratecost(i,intra_preds);
CHECK_FOR_BEST(i,ratecost); CHECK_FOR_BEST(i,bitcost*(int)(g_cur_lambda_cost+0.5));
} }
} }
// assign final sad to output // assign final sad to output
*sad_out = best_sad; *sad_out = best_sad;
*bitcost_out = best_bitcost;
#undef COPY_PRED_TO_DST #undef COPY_PRED_TO_DST
#undef CHECK_FOR_BEST #undef CHECK_FOR_BEST

View file

@ -40,7 +40,8 @@ void intra_filter(pixel* ref, int32_t stride, int32_t width, int8_t mode);
/* Predictions */ /* Predictions */
int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t recstride, int16_t intra_prediction(pixel *orig, int32_t origstride, pixel *rec, int16_t recstride,
uint8_t width, pixel *dst, int32_t dststride, uint32_t *sad_out, int8_t *intra_preds); uint8_t width, pixel *dst, int32_t dststride, uint32_t *sad_out,
int8_t *intra_preds, uint32_t *bitcost_out);
pixel intra_get_dc_pred(pixel* pic, uint16_t pic_width, uint8_t width); pixel intra_get_dc_pred(pixel* pic, uint16_t pic_width, uint8_t width);
void intra_get_planar_pred(pixel* src,int32_t srcstride, uint32_t width, pixel* dst, int32_t dststride); void intra_get_planar_pred(pixel* src,int32_t srcstride, uint32_t width, pixel* dst, int32_t dststride);

View file

@ -679,6 +679,7 @@ static int search_cu_intra(encoder_control *encoder,
cu_info *left_cu = 0; cu_info *left_cu = 0;
cu_info *above_cu = 0; cu_info *above_cu = 0;
uint32_t bitcost = 0, bitcost_nxn;
if ((x_px >> 3) > 0) { if ((x_px >> 3) > 0) {
left_cu = &lcu->cu[cu_index - 1]; left_cu = &lcu->cu[cu_index - 1];
@ -706,7 +707,7 @@ static int search_cu_intra(encoder_control *encoder,
mode = intra_prediction(ref_pixels, LCU_WIDTH, mode = intra_prediction(ref_pixels, LCU_WIDTH,
cu_in_rec_buffer, cu_width * 2 + 8, cu_width, cu_in_rec_buffer, cu_width * 2 + 8, cu_width,
pred_buffer, cu_width, pred_buffer, cu_width,
&cost, candidate_modes); &cost, candidate_modes, &bitcost);
cur_cu->intra[0].mode = (int8_t)mode; cur_cu->intra[0].mode = (int8_t)mode;
cur_cu->intra[0].cost = cost; cur_cu->intra[0].cost = cost;
cur_cu->part_size = SIZE_2Nx2N; cur_cu->part_size = SIZE_2Nx2N;
@ -726,6 +727,8 @@ static int search_cu_intra(encoder_control *encoder,
cu_in_rec_buffer = &rec_buffer[nxn_width * 2 + 8 + 1]; cu_in_rec_buffer = &rec_buffer[nxn_width * 2 + 8 + 1];
bitcost_nxn = 0;
for (nxn_i = 0; nxn_i < 4; ++nxn_i) { for (nxn_i = 0; nxn_i < 4; ++nxn_i) {
const vector2d nxn_px = { x_px + offsets[nxn_i].x, const vector2d nxn_px = { x_px + offsets[nxn_i].x,
y_px + offsets[nxn_i].y }; y_px + offsets[nxn_i].y };
@ -738,13 +741,15 @@ static int search_cu_intra(encoder_control *encoder,
{ {
uint32_t nxn_cost = -1; uint32_t nxn_cost = -1;
int16_t nxn_mode = -1; int16_t nxn_mode = -1;
uint32_t bitcost_temp = 0;
pixel *ref_pixels = &lcu->ref.y[nxn_px.x + nxn_px.y * LCU_WIDTH]; pixel *ref_pixels = &lcu->ref.y[nxn_px.x + nxn_px.y * LCU_WIDTH];
nxn_mode = intra_prediction(ref_pixels, encoder->in.width, nxn_mode = intra_prediction(ref_pixels, encoder->in.width,
cu_in_rec_buffer, nxn_width * 2 + 8, nxn_width, cu_in_rec_buffer, nxn_width * 2 + 8, nxn_width,
pred_buffer, nxn_width, pred_buffer, nxn_width,
&nxn_cost, candidate_modes); &nxn_cost, candidate_modes, &bitcost_temp);
cur_cu->intra[nxn_i].mode = (int8_t)nxn_mode; cur_cu->intra[nxn_i].mode = (int8_t)nxn_mode;
cost += nxn_cost; cost += nxn_cost;
bitcost_nxn += bitcost_temp;
} }
} }
@ -755,9 +760,12 @@ static int search_cu_intra(encoder_control *encoder,
} else { } else {
cur_cu->intra[0].cost = cost; cur_cu->intra[0].cost = cost;
cur_cu->part_size = SIZE_NxN; cur_cu->part_size = SIZE_NxN;
bitcost = bitcost_nxn;
} }
} }
cur_cu->intra[0].bitcost = bitcost;
return cur_cu->intra[0].cost; return cur_cu->intra[0].cost;
} }