diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index b286e2e1a43086a5c1c2093f45a9ffcc5bea318b..1cc5a1f2ce5b932e4ac4405baf25168297d4c888 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -168,14 +168,15 @@ typedef struct int as_int; MV as_mv; } mv; - int partitioning; - int partition_count; - int mb_skip_coeff; //does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens - int dc_diff; - unsigned char segment_id; // Which set of segmentation parameters should be used for this MB - int force_no_skip; - int need_to_clamp_mvs; - B_MODE_INFO partition_bmi[16]; + + char partitioning; + unsigned char mb_skip_coeff; //does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens + unsigned char dc_diff; + unsigned char need_to_clamp_mvs; + + unsigned char segment_id; // Which set of segmentation parameters should be used for this MB + + unsigned char force_no_skip; //encoder only } MB_MODE_INFO; @@ -227,8 +228,6 @@ typedef struct YV12_BUFFER_CONFIG dst; MODE_INFO *mode_info_context; - MODE_INFO *mode_info; - int mode_info_stride; FRAME_TYPE frame_type; diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 4f24b445fca1f3eb8abb1a68242a67123269b9a6..d1412673937049f4476267440a4234b8c004c809 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -219,8 +219,8 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi) do /* for each subset j */ { - B_MODE_INFO *const bmi = mbmi->partition_bmi + j; - MV *const mv = & bmi->mv.as_mv; + B_MODE_INFO bmi; + MV *const mv = & bmi.mv.as_mv; int k = -1; /* first block in subset j */ int mv_contz; @@ -237,7 +237,7 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi) mv_contz = vp8_mv_cont(&(vp8_left_bmi(mi, k)->mv.as_mv), &(vp8_above_bmi(mi, k, mis)->mv.as_mv)); - switch (bmi->mode = (B_PREDICTION_MODE) sub_mv_ref(bc, vp8_sub_mv_ref_prob2 [mv_contz])) //pc->fc.sub_mv_ref_prob)) + switch (bmi.mode = (B_PREDICTION_MODE) sub_mv_ref(bc, vp8_sub_mv_ref_prob2 [mv_contz])) //pc->fc.sub_mv_ref_prob)) { case NEW4X4: read_mv(bc, mv, (const MV_CONTEXT *) mvc); @@ -285,7 +285,7 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi) refer back to us via "left" or "above". */ do if (j == L[k]) - mi->bmi[k] = *bmi; + mi->bmi[k] = bmi; while (++k < 16); } diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c index 02edba2beca739324249a050a934b0273efaf543..93acd368b191e959d7f9d6bef931677c2e1a18ff 100644 --- a/vp8/decoder/threading.c +++ b/vp8/decoder/threading.c @@ -52,7 +52,6 @@ void vp8_setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC mbd->subpixel_predict8x8 = xd->subpixel_predict8x8; mbd->subpixel_predict16x16 = xd->subpixel_predict16x16; - mbd->mode_info = pc->mi - 1; mbd->mode_info_context = pc->mi + pc->mode_info_stride * (i + 1); mbd->mode_info_stride = pc->mode_info_stride; @@ -105,7 +104,6 @@ void vp8_setup_loop_filter_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_D //mbd->subpixel_predict8x8 = xd->subpixel_predict8x8; //mbd->subpixel_predict16x16 = xd->subpixel_predict16x16; - mbd->mode_info = pc->mi - 1; mbd->mode_info_context = pc->mi + pc->mode_info_stride * (i + 1); mbd->mode_info_stride = pc->mode_info_stride; diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 21629841b03fc880348bf4bcce453201058dde7b..c706395a8a2a7c79bf1cc19b5bbde0401a71cb1d 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -872,6 +872,8 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) int prob_skip_false = 0; ms = pc->mi - 1; + cpi->mb.partition_info = cpi->mb.pi; + // Calculate the probabilities to be used to code the reference frame based on actual useage this frame if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter))) cpi->prob_intra_coded = 1; @@ -1020,7 +1022,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) do { - const B_MODE_INFO *const b = mi->partition_bmi + j; + const B_MODE_INFO *const b = cpi->mb.partition_info->bmi + j; const int *const L = vp8_mbsplits [mi->partitioning]; int k = -1; /* first block in subset j */ int mv_contz; @@ -1042,7 +1044,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) write_mv(w, &b->mv.as_mv, &best_mv, (const MV_CONTEXT *) mvc); } } - while (++j < mi->partition_count); + while (++j < cpi->mb.partition_info->count); } break; default: @@ -1051,9 +1053,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) } ++m; + cpi->mb.partition_info++; } ++m; /* skip L prediction border */ + cpi->mb.partition_info++; } } diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h index c914a32b60723b54007d805ab3a091d657d010ee..be2b8167882bd62e8bbb60b4040b226611dac9ab 100644 --- a/vp8/encoder/block.h +++ b/vp8/encoder/block.h @@ -50,6 +50,12 @@ typedef struct } BLOCK; +typedef struct +{ + int count; + B_MODE_INFO bmi[16]; +} PARTITION_INFO; + typedef struct { DECLARE_ALIGNED(16, short, src_diff[400]); // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y @@ -61,6 +67,9 @@ typedef struct YV12_BUFFER_CONFIG src; MACROBLOCKD e_mbd; + PARTITION_INFO *partition_info; /* work pointer */ + PARTITION_INFO *pi; /* Corresponds to upper left visible macroblock */ + PARTITION_INFO *pip; /* Base of allocated array */ search_site *ss; int ss_count; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 1e0e1abc3d81c333d01bc31dc9915489d61904b8..96f36ee63b6bb09d2b0e9c4a1c1f75044fc578ff 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -458,7 +458,7 @@ void encode_mb_row(VP8_COMP *cpi, for (b = 0; b < xd->mbmi.partition_count; b++) { - inter_b_modes[xd->mbmi.partition_bmi[b].mode] ++; + inter_b_modes[x->partition->bmi[b].mode] ++; } } @@ -511,6 +511,7 @@ void encode_mb_row(VP8_COMP *cpi, // skip to next mb xd->mode_info_context++; + x->partition_info++; xd->above_context++; cpi->current_mb_col_main = mb_col; @@ -525,6 +526,7 @@ void encode_mb_row(VP8_COMP *cpi, // this is to account for the border xd->mode_info_context++; + x->partition_info++; } @@ -594,7 +596,7 @@ void vp8_encode_frame(VP8_COMP *cpi) totalrate = 0; - xd->mode_info = cm->mi - 1; + x->partition_info = x->pi; xd->mode_info_context = cm->mi; xd->mode_info_stride = cm->mode_info_stride; @@ -730,6 +732,7 @@ void vp8_encode_frame(VP8_COMP *cpi) x->src.v_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols; xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count; + x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count; if (mb_row < cm->mb_rows - 1) //WaitForSingleObject(cpi->h_event_main, INFINITE); diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c index b677fde662a0f73820d91f7fe31e17ebfb94c3cc..04093ff434f6c269377319903c02a30d3fbff9af 100644 --- a/vp8/encoder/ethreading.c +++ b/vp8/encoder/ethreading.c @@ -147,7 +147,7 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data) for (b = 0; b < xd->mbmi.partition_count; b++) { - inter_b_modes[xd->mbmi.partition_bmi[b].mode] ++; + inter_b_modes[x->partition->bmi[b].mode] ++; } } @@ -179,6 +179,7 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data) // skip to next mb xd->mode_info_context++; + x->partition_info++; xd->above_context++; @@ -195,12 +196,14 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data) // this is to account for the border xd->mode_info_context++; + x->partition_info++; x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols; x->src.u_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols; x->src.v_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols; xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count; + x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count; if (ithread == (cpi->encoding_thread_count - 1) || mb_row == cm->mb_rows - 1) { @@ -364,7 +367,8 @@ void vp8cx_init_mbrthread_data(VP8_COMP *cpi, vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts)); mbr_ei[i].totalrate = 0; - mbd->mode_info = cm->mi - 1; + mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1); + mbd->mode_info_context = cm->mi + x->e_mbd.mode_info_stride * (i + 1); mbd->mode_info_stride = cm->mode_info_stride; diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index a58b9b75db07c3c9ca419ed3080b05b906775e78..fea4e3d6a728a6abe9ce63066315aeb6fe87e3dc 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -565,6 +565,8 @@ void vp8_first_pass(VP8_COMP *cpi) xd->pre = *lst_yv12; xd->dst = *new_yv12; + x->partition_info = x->pi; + xd->mode_info_context = cm->mi; vp8_build_block_offsets(x); diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index fe83ae976da693a4ef61bdc34926369b9431e004..201de33774ae191bb2d174eb38ed1a954630728b 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -29,6 +29,8 @@ #include "swapyv12buffer.h" #include "threading.h" #include "vpx_ports/vpx_timer.h" +#include "vpxerrors.h" + #include <math.h> #include <stdio.h> #include <limits.h> @@ -230,6 +232,11 @@ void vp8_dealloc_compressor_data(VP8_COMP *cpi) cpi->gf_active_flags = 0; + if(cpi->mb.pip) + vpx_free(cpi->mb.pip); + + cpi->mb.pip = 0; + } static void enable_segmentation(VP8_PTR ptr) @@ -1221,6 +1228,20 @@ static void alloc_raw_frame_buffers(VP8_COMP *cpi) cpi->source_buffer_count = 0; } + +static int vp8_alloc_partition_data(VP8_COMP *cpi) +{ + cpi->mb.pip = vpx_calloc((cpi->common.mb_cols + 1) * + (cpi->common.mb_rows + 1), + sizeof(PARTITION_INFO)); + if(!cpi->mb.pip) + return ALLOC_FAILURE; + + cpi->mb.pi = cpi->mb.pip + cpi->common.mode_info_stride + 1; + + return 0; +} + void vp8_alloc_compressor_data(VP8_COMP *cpi) { VP8_COMMON *cm = & cpi->common; @@ -1232,6 +1253,11 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate frame buffers"); + if (vp8_alloc_partition_data(cpi)) + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, + "Failed to allocate partition data"); + + if ((width & 0xf) != 0) width += 16 - (width & 0xf); diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index 9da715e99d35267dcbae48db04c452fdbe131d54..2be412c9974042d2974e7e25d70e0aa8024a2d4f 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -430,6 +430,7 @@ int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int rec MACROBLOCKD *xd = &x->e_mbd; B_MODE_INFO best_bmodes[16]; MB_MODE_INFO best_mbmode; + PARTITION_INFO best_partition; MV best_ref_mv1; MV mode_mv[MB_MODE_COUNT]; MB_PREDICTION_MODE this_mode; @@ -832,6 +833,7 @@ int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int rec *returndistortion = distortion2; best_rd = this_rd; vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, sizeof(MB_MODE_INFO)); + vpx_memcpy(&best_partition, x->partition_info, sizeof(PARTITION_INFO)); if (this_mode == B_PRED || this_mode == SPLITMV) for (i = 0; i < 16; i++) @@ -906,6 +908,7 @@ int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int rec best_mbmode.dc_diff = 0; vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO)); + vpx_memcpy(x->partition_info, &best_partition, sizeof(PARTITION_INFO)); for (i = 0; i < 16; i++) { @@ -920,6 +923,7 @@ int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int rec // macroblock modes vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO)); + vpx_memcpy(x->partition_info, &best_partition, sizeof(PARTITION_INFO)); if (x->e_mbd.mode_info_context->mbmi.mode == B_PRED || x->e_mbd.mode_info_context->mbmi.mode == SPLITMV) for (i = 0; i < 16; i++) diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index c5dd59a61e40b99f0f8692e15659cdc8de6f38c2..75a71d7df1c2ca728ef8744f74169ac0f51bf59b 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1439,9 +1439,9 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes // save partitions labels = vp8_mbsplits[best_seg]; x->e_mbd.mode_info_context->mbmi.partitioning = best_seg; - x->e_mbd.mode_info_context->mbmi.partition_count = vp8_count_labels(labels); + x->partition_info->count = vp8_count_labels(labels); - for (i = 0; i < x->e_mbd.mode_info_context->mbmi.partition_count; i++) + for (i = 0; i < x->partition_info->count; i++) { int j; @@ -1451,8 +1451,8 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes break; } - x->e_mbd.mode_info_context->mbmi.partition_bmi[i].mode = x->e_mbd.block[j].bmi.mode; - x->e_mbd.mode_info_context->mbmi.partition_bmi[i].mv.as_mv = x->e_mbd.block[j].bmi.mv.as_mv; + x->partition_info->bmi[i].mode = x->e_mbd.block[j].bmi.mode; + x->partition_info->bmi[i].mv.as_mv = x->e_mbd.block[j].bmi.mv.as_mv; } return best_segment_rd; @@ -1466,6 +1466,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int MACROBLOCKD *xd = &x->e_mbd; B_MODE_INFO best_bmodes[16]; MB_MODE_INFO best_mbmode; + PARTITION_INFO best_partition; MV best_ref_mv; MV mode_mv[MB_MODE_COUNT]; MB_PREDICTION_MODE this_mode; @@ -1787,19 +1788,19 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int } // trap cases where the 8x8s can be promoted to 8x16s or 16x8s - if (0)//x->e_mbd.mbmi.partition_count == 4) + if (0)//x->partition_info->count == 4) { - if (x->e_mbd.mode_info_context->mbmi.partition_bmi[0].mv.as_int == x->e_mbd.mode_info_context->mbmi.partition_bmi[1].mv.as_int - && x->e_mbd.mode_info_context->mbmi.partition_bmi[2].mv.as_int == x->e_mbd.mode_info_context->mbmi.partition_bmi[3].mv.as_int) + if (x->partition_info->bmi[0].mv.as_int == x->partition_info->bmi[1].mv.as_int + && x->partition_info->bmi[2].mv.as_int == x->partition_info->bmi[3].mv.as_int) { const int *labels = vp8_mbsplits[2]; x->e_mbd.mode_info_context->mbmi.partitioning = 0; rate -= vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + 2); rate += vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings); - //rate -= x->inter_bmode_costs[ x->e_mbd.mbmi.partition_bmi[1]]; - //rate -= x->inter_bmode_costs[ x->e_mbd.mbmi.partition_bmi[3]]; - x->e_mbd.mode_info_context->mbmi.partition_bmi[1] = x->e_mbd.mode_info_context->mbmi.partition_bmi[2]; + //rate -= x->inter_bmode_costs[ x->partition_info->bmi[1]]; + //rate -= x->inter_bmode_costs[ x->partition_info->bmi[3]]; + x->partition_info->bmi[1] = x->partition_info->bmi[2]; } } @@ -2143,6 +2144,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int *returndistortion = distortion2; best_rd = this_rd; vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, sizeof(MB_MODE_INFO)); + vpx_memcpy(&best_partition, x->partition_info, sizeof(PARTITION_INFO)); for (i = 0; i < 16; i++) { @@ -2224,6 +2226,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int best_mbmode.dc_diff = 0; vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO)); + vpx_memcpy(x->partition_info, &best_partition, sizeof(PARTITION_INFO)); for (i = 0; i < 16; i++) { @@ -2238,6 +2241,7 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int // macroblock modes vpx_memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO)); + vpx_memcpy(x->partition_info, &best_partition, sizeof(PARTITION_INFO)); for (i = 0; i < 16; i++) {