Added common prediction modules.
This function adds the common prediction modules, some data structures and a config option but does not use them. It also corrects a bug in clearing down the MODE_INFO border and introduces a new element that indicates if an entry corresponds to an "in image" macro block or is part of the border. Change-Id: Ib69eec0876173ebe9d1de9df9537d0b2447702e0
This commit is contained in:
parent
048e4fd524
commit
b2f64dff7d
1
configure
vendored
1
configure
vendored
@ -226,6 +226,7 @@ EXPERIMENT_LIST="
|
||||
qimode
|
||||
uvintra
|
||||
newnear
|
||||
compred
|
||||
newlpf
|
||||
enhanced_interp
|
||||
"
|
||||
|
@ -20,17 +20,37 @@
|
||||
|
||||
extern void vp8_init_scan_order_mask();
|
||||
|
||||
static void update_mode_info_border(MODE_INFO *mi, int rows, int cols)
|
||||
static void update_mode_info_border( VP8_COMMON *cpi, MODE_INFO *mi_base )
|
||||
{
|
||||
int stride = cpi->mode_info_stride;
|
||||
int i;
|
||||
vpx_memset(mi - cols - 2, 0, sizeof(MODE_INFO) * (cols + 1));
|
||||
|
||||
for (i = 0; i < rows; i++)
|
||||
// Clear down top border row
|
||||
vpx_memset(mi_base, 0, sizeof(MODE_INFO) * cpi->mode_info_stride);
|
||||
|
||||
// Clear left border column
|
||||
for (i = 1; i < cpi->mb_rows+1; i++)
|
||||
{
|
||||
/* TODO(holmer): Bug? This updates the last element of each row
|
||||
* rather than the border element!
|
||||
*/
|
||||
vpx_memset(&mi[i*cols-1], 0, sizeof(MODE_INFO));
|
||||
vpx_memset(&mi_base[i*stride], 0, sizeof(MODE_INFO));
|
||||
}
|
||||
}
|
||||
static void update_mode_info_in_image( VP8_COMMON *cpi, MODE_INFO *mi )
|
||||
{
|
||||
int stride = cpi->mode_info_stride;
|
||||
int rows = cpi->mb_rows;
|
||||
int cols = cpi->mb_cols;
|
||||
int i, j;
|
||||
|
||||
// For each in image mode_info element set the in image flag to 1
|
||||
for (i = 0; i < cpi->mb_rows; i++)
|
||||
{
|
||||
for (j = 0; j < cpi->mb_cols; j++)
|
||||
{
|
||||
mi->mbmi.mb_in_image = 1;
|
||||
mi++; // Next element in the row
|
||||
}
|
||||
|
||||
mi++; // Step over border element at start of next row
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,9 +159,11 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
|
||||
return 1;
|
||||
}
|
||||
|
||||
update_mode_info_border(oci->mi, oci->mb_rows, oci->mb_cols);
|
||||
update_mode_info_border(oci, oci->mip);
|
||||
update_mode_info_in_image(oci, oci->mi);
|
||||
#if CONFIG_ERROR_CONCEALMENT
|
||||
update_mode_info_border(oci->prev_mi, oci->mb_rows, oci->mb_cols);
|
||||
update_mode_info_border(oci, oci->prev_mip);
|
||||
update_mode_info_in_image(oci, oci->prev_mi);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -194,6 +194,15 @@ typedef struct
|
||||
// Flags used for prediction status of various bistream signals
|
||||
unsigned char seg_id_predicted;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
unsigned char ref_predicted;
|
||||
#endif
|
||||
|
||||
// Indicates if the mb is part of the image (1) vs border (0)
|
||||
// This can be useful in determining whether the MB provides
|
||||
// a valid predictor
|
||||
unsigned char mb_in_image;
|
||||
|
||||
} MB_MODE_INFO;
|
||||
|
||||
typedef struct
|
||||
|
@ -234,6 +234,11 @@ typedef struct VP8Common
|
||||
vp8_prob segment_pred_probs[PREDICTION_PROBS];
|
||||
unsigned char temporal_update;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Context probabilities for reference frame prediction
|
||||
vp8_prob ref_pred_probs[PREDICTION_PROBS];
|
||||
vp8_prob mod_refprobs[MAX_REF_FRAMES][PREDICTION_PROBS];
|
||||
#endif
|
||||
|
||||
FRAME_CONTEXT lfc_a; /* last alt ref entropy */
|
||||
FRAME_CONTEXT lfc; /* last frame entropy */
|
||||
|
297
vp8/common/pred_common.c
Normal file
297
vp8/common/pred_common.c
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "vp8/common/pred_common.h"
|
||||
|
||||
// TBD prediction functions for various bitstream signals
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
unsigned char get_pred_context( VP8_COMMON *const cm,
|
||||
MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id )
|
||||
{
|
||||
int pred_context;
|
||||
MODE_INFO *m = xd->mode_info_context;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialised to 0.
|
||||
switch (pred_id)
|
||||
{
|
||||
case PRED_SEG_ID:
|
||||
pred_context = (m - 1)->mbmi.seg_id_predicted +
|
||||
(m - cm->mode_info_stride)->mbmi.seg_id_predicted;
|
||||
break;
|
||||
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
|
||||
case PRED_REF:
|
||||
pred_context = (m - 1)->mbmi.ref_predicted +
|
||||
(m - cm->mode_info_stride)->mbmi.ref_predicted;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// TODO *** add error trap code.
|
||||
pred_context = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
// This function returns a context probability for coding a given
|
||||
// prediction signal
|
||||
vp8_prob get_pred_prob( VP8_COMMON *const cm,
|
||||
MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id )
|
||||
{
|
||||
vp8_prob pred_probability;
|
||||
int pred_context;
|
||||
|
||||
// Get the appropriate prediction context
|
||||
pred_context = get_pred_context( cm, xd, pred_id );
|
||||
|
||||
switch (pred_id)
|
||||
{
|
||||
case PRED_SEG_ID:
|
||||
pred_probability = cm->segment_pred_probs[pred_context];
|
||||
break;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
|
||||
case PRED_REF:
|
||||
pred_probability = cm->ref_pred_probs[pred_context];
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// TODO *** add error trap code.
|
||||
pred_probability = 128;
|
||||
break;
|
||||
}
|
||||
|
||||
return pred_probability;
|
||||
}
|
||||
|
||||
// This function returns the status of the given prediction signal.
|
||||
// I.e. is the predicted value for the given signal correct.
|
||||
unsigned char get_pred_flag( MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id )
|
||||
{
|
||||
unsigned char pred_flag = 0;
|
||||
|
||||
switch (pred_id)
|
||||
{
|
||||
case PRED_SEG_ID:
|
||||
pred_flag = xd->mode_info_context->mbmi.seg_id_predicted;
|
||||
break;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
|
||||
case PRED_REF:
|
||||
pred_flag = xd->mode_info_context->mbmi.ref_predicted;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// TODO *** add error trap code.
|
||||
pred_flag = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return pred_flag;
|
||||
}
|
||||
|
||||
// This function sets the status of the given prediction signal.
|
||||
// I.e. is the predicted value for the given signal correct.
|
||||
void set_pred_flag( MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id,
|
||||
unsigned char pred_flag)
|
||||
{
|
||||
switch (pred_id)
|
||||
{
|
||||
case PRED_SEG_ID:
|
||||
xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
|
||||
break;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
|
||||
case PRED_REF:
|
||||
xd->mode_info_context->mbmi.ref_predicted = pred_flag;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// TODO *** add error trap code.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The following contain the guts of the prediction code used to
|
||||
// peredict various bitstream signals.
|
||||
|
||||
// Macroblock segment id prediction function
|
||||
unsigned char get_pred_mb_segid( VP8_COMMON *const cm, int MbIndex )
|
||||
{
|
||||
// Currently the prediction for the macroblock segment ID is
|
||||
// the value stored for this macroblock in the previous frame.
|
||||
return cm->last_frame_seg_map[MbIndex];
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
|
||||
MACROBLOCKD *const xd )
|
||||
{
|
||||
MODE_INFO *m = xd->mode_info_context;
|
||||
|
||||
unsigned char left_pred;
|
||||
unsigned char above_pred;
|
||||
|
||||
MV_REFERENCE_FRAME left;
|
||||
MV_REFERENCE_FRAME above;
|
||||
MV_REFERENCE_FRAME above_left;
|
||||
MV_REFERENCE_FRAME pred_ref = LAST_FRAME;
|
||||
|
||||
// Reference frame used by neighbours
|
||||
left = (m - 1)->mbmi.ref_frame;
|
||||
above = (m - cm->mode_info_stride)->mbmi.ref_frame;
|
||||
above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame;
|
||||
|
||||
// Reference frame prediction status of immediate neigbours.
|
||||
// This can only be set if the mb is "in image"
|
||||
left_pred = (m - 1)->mbmi.ref_predicted;
|
||||
above_pred = (m - cm->mode_info_stride)->mbmi.ref_predicted;
|
||||
|
||||
// Boost prediction scores of above / left if they are predicted and match
|
||||
// the above left.
|
||||
if ( left_pred )
|
||||
left_pred += (left == above_left);
|
||||
if ( above_pred )
|
||||
above_pred += (above == above_left);
|
||||
|
||||
// Only consider "in image" mbs as giving valid prediction.
|
||||
if ( (left == above) &&
|
||||
((m - 1)->mbmi.mb_in_image ||
|
||||
(m - cm->mode_info_stride)->mbmi.mb_in_image) )
|
||||
{
|
||||
pred_ref = left;
|
||||
}
|
||||
else if ( left_pred > above_pred )
|
||||
{
|
||||
pred_ref = left;
|
||||
}
|
||||
else if ( above_pred > left_pred )
|
||||
{
|
||||
pred_ref = above;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Choose from above or left.
|
||||
// For now this is based on a fixed preference order.
|
||||
// Last,Altref,Golden
|
||||
if ( (left == LAST_FRAME) || (above == LAST_FRAME) )
|
||||
pred_ref = LAST_FRAME;
|
||||
else if ( (left == ALTREF_FRAME) || (above == ALTREF_FRAME) )
|
||||
pred_ref = ALTREF_FRAME;
|
||||
else if ( (left == GOLDEN_FRAME) || (above == GOLDEN_FRAME) )
|
||||
pred_ref = GOLDEN_FRAME;
|
||||
}
|
||||
|
||||
return pred_ref;
|
||||
}
|
||||
|
||||
// Functions to computes a set of modified reference frame probabilities
|
||||
// to use when the prediction of the reference frame value fails
|
||||
void calc_ref_probs( int * count, vp8_prob * probs )
|
||||
{
|
||||
int tot_count;
|
||||
|
||||
tot_count = count[0] + count[1] + count[2] + count[3];
|
||||
if ( tot_count )
|
||||
{
|
||||
probs[0] = (vp8_prob)((count[0] * 255) / tot_count);
|
||||
probs[0] += !probs[0];
|
||||
}
|
||||
else
|
||||
probs[0] = 128;
|
||||
|
||||
tot_count -= count[0];
|
||||
if ( tot_count )
|
||||
{
|
||||
probs[1] = (vp8_prob)((count[1] * 255) / tot_count);
|
||||
probs[1] += !probs[1];
|
||||
}
|
||||
else
|
||||
probs[1] = 128;
|
||||
|
||||
tot_count -= count[1];
|
||||
if ( tot_count )
|
||||
{
|
||||
probs[2] = (vp8_prob)((count[2] * 255) / tot_count);
|
||||
probs[2] += !probs[2];
|
||||
}
|
||||
else
|
||||
probs[2] = 128;
|
||||
|
||||
}
|
||||
|
||||
void compute_mod_refprobs( VP8_COMMON *const cm )
|
||||
{
|
||||
int norm_cnt[MAX_REF_FRAMES];
|
||||
int intra_count;
|
||||
int inter_count;
|
||||
int last_count;
|
||||
int gfarf_count;
|
||||
int gf_count;
|
||||
int arf_count;
|
||||
|
||||
intra_count = cm->prob_intra_coded;
|
||||
inter_count = (255 - intra_count);
|
||||
last_count = (inter_count * cm->prob_last_coded)/255;
|
||||
gfarf_count = inter_count - last_count;
|
||||
gf_count = (gfarf_count * cm->prob_gf_coded)/255;
|
||||
arf_count = gfarf_count - gf_count;
|
||||
|
||||
// Work out modified reference frame probabilities to use where prediction
|
||||
// of the reference frame fails
|
||||
norm_cnt[0] = 0;
|
||||
norm_cnt[1] = last_count;
|
||||
norm_cnt[2] = gf_count;
|
||||
norm_cnt[3] = arf_count;
|
||||
calc_ref_probs( norm_cnt, cm->mod_refprobs[INTRA_FRAME] );
|
||||
cm->mod_refprobs[INTRA_FRAME][0] = 0; // This branch implicit
|
||||
|
||||
norm_cnt[0] = intra_count;
|
||||
norm_cnt[1] = 0;
|
||||
norm_cnt[2] = gf_count;
|
||||
norm_cnt[3] = arf_count;
|
||||
calc_ref_probs( norm_cnt, cm->mod_refprobs[LAST_FRAME]);
|
||||
cm->mod_refprobs[LAST_FRAME][1] = 0; // This branch implicit
|
||||
|
||||
norm_cnt[0] = intra_count;
|
||||
norm_cnt[1] = last_count;
|
||||
norm_cnt[2] = 0;
|
||||
norm_cnt[3] = arf_count;
|
||||
calc_ref_probs( norm_cnt, cm->mod_refprobs[GOLDEN_FRAME] );
|
||||
cm->mod_refprobs[GOLDEN_FRAME][2] = 0; // This branch implicit
|
||||
|
||||
norm_cnt[0] = intra_count;
|
||||
norm_cnt[1] = last_count;
|
||||
norm_cnt[2] = gf_count;
|
||||
norm_cnt[3] = 0;
|
||||
calc_ref_probs( norm_cnt, cm->mod_refprobs[ALTREF_FRAME] );
|
||||
cm->mod_refprobs[ALTREF_FRAME][2] = 0; // This branch implicit
|
||||
|
||||
}
|
||||
#endif
|
56
vp8/common/pred_common.h
Normal file
56
vp8/common/pred_common.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "type_aliases.h"
|
||||
#include "onyxc_int.h"
|
||||
#include "vp8/common/blockd.h"
|
||||
|
||||
#ifndef __INC_PRED_COMMON_H__
|
||||
#define __INC_PRED_COMMON_H__ 1
|
||||
|
||||
|
||||
// Predicted items
|
||||
typedef enum
|
||||
{
|
||||
PRED_SEG_ID = 0, // Segment identifier
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
PRED_REF = 1
|
||||
#endif
|
||||
|
||||
} PRED_ID;
|
||||
|
||||
|
||||
extern unsigned char get_pred_context( VP8_COMMON *const cm,
|
||||
MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id );
|
||||
|
||||
extern vp8_prob get_pred_prob( VP8_COMMON *const cm,
|
||||
MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id );
|
||||
|
||||
extern unsigned char get_pred_flag( MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id );
|
||||
|
||||
extern void set_pred_flag( MACROBLOCKD *const xd,
|
||||
PRED_ID pred_id,
|
||||
unsigned char pred_flag);
|
||||
|
||||
|
||||
extern unsigned char get_pred_mb_segid( VP8_COMMON *const cm, int MbIndex );
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
extern MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
|
||||
MACROBLOCKD *const xd );
|
||||
extern void compute_mod_refprobs( VP8_COMMON *const cm );
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __INC_PRED_COMMON_H__ */
|
@ -45,6 +45,8 @@ VP8_COMMON_SRCS-yes += common/loopfilter.h
|
||||
VP8_COMMON_SRCS-yes += common/modecont.h
|
||||
VP8_COMMON_SRCS-yes += common/mv.h
|
||||
VP8_COMMON_SRCS-yes += common/onyxc_int.h
|
||||
VP8_COMMON_SRCS-yes += common/pred_common.h
|
||||
VP8_COMMON_SRCS-yes += common/pred_common.c
|
||||
VP8_COMMON_SRCS-yes += common/quant_common.h
|
||||
VP8_COMMON_SRCS-yes += common/recon.h
|
||||
VP8_COMMON_SRCS-yes += common/reconinter.h
|
||||
@ -74,7 +76,6 @@ VP8_COMMON_SRCS-yes += common/swapyv12buffer.c
|
||||
VP8_COMMON_SRCS-$(CONFIG_POSTPROC_VISUALIZER) += common/textblit.c
|
||||
VP8_COMMON_SRCS-yes += common/treecoder.c
|
||||
VP8_COMMON_SRCS-yes += common/implicit_segmentation.c
|
||||
VP8_COMMON_SRCS-yes += common/implicit_segmentation.h
|
||||
VP8_COMMON_SRCS-yes += common/predict_rotated.c
|
||||
VP8_COMMON_SRCS-yes += common/rotate.h
|
||||
VP8_COMMON_SRCS-yes += common/rotate2.h
|
||||
|
Loading…
Reference in New Issue
Block a user