]> granicus.if.org Git - libvpx/commitdiff
Added common prediction modules.
authorPaul Wilkins <paulwilkins@google.com>
Sat, 28 Jan 2012 10:07:08 +0000 (10:07 +0000)
committerPaul Wilkins <paulwilkins@google.com>
Tue, 31 Jan 2012 12:53:36 +0000 (12:53 +0000)
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

configure
vp8/common/alloccommon.c
vp8/common/blockd.h
vp8/common/onyxc_int.h
vp8/common/pred_common.c [new file with mode: 0644]
vp8/common/pred_common.h [new file with mode: 0644]
vp8/vp8_common.mk

index c6bce0461b7018cd6562cd31f032741b29a45968..cdb5f4d1f0c1a83677a981a9f1db5030cd97fe1a 100755 (executable)
--- a/configure
+++ b/configure
@@ -226,6 +226,7 @@ EXPERIMENT_LIST="
     qimode
     uvintra
     newnear
+    compred
     newlpf
     enhanced_interp
 "
index e643eff09016aecb97a14551e90bd78719d27fe0..c49927c2c5cba57176dbe011b77c0a6d5a3c149e 100644 (file)
 
 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;
index 9c1453e2ad1cc4ea096320a4424a583f3a05c220..a2c5426ea9b7fdd0ab4cae8a870f1686a9aa5945 100644 (file)
@@ -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
index 75c1c001df00983ea1809c373e753ad9d5c34b6b..fd6a5580150d2d8ee1f048c0eb92dbf2d84f4862 100644 (file)
@@ -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 */
diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c
new file mode 100644 (file)
index 0000000..1d1d107
--- /dev/null
@@ -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
diff --git a/vp8/common/pred_common.h b/vp8/common/pred_common.h
new file mode 100644 (file)
index 0000000..60476f9
--- /dev/null
@@ -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__ */
index 15951427087621fe88f4b215225cf584c4efdada..5a44cd1b1bb9d6f88ee0c5e68c35b372317ec4a2 100644 (file)
@@ -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