encodeframe.c 52 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
 *
 *  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.
John Koleszar's avatar
John Koleszar committed
 */


#include "vpx_ports/config.h"
#include "encodemb.h"
#include "encodemv.h"
#include "vp8/common/common.h"
John Koleszar's avatar
John Koleszar committed
#include "onyx_int.h"
#include "vp8/common/extend.h"
#include "vp8/common/entropymode.h"
#include "vp8/common/quant_common.h"
#include "segmentation.h"
#include "vp8/common/setupintrarecon.h"
John Koleszar's avatar
John Koleszar committed
#include "encodeintra.h"
#include "vp8/common/reconinter.h"
John Koleszar's avatar
John Koleszar committed
#include "rdopt.h"
#include "pickinter.h"
#include "vp8/common/findnearmv.h"
#include "vp8/common/reconintra.h"
John Koleszar's avatar
John Koleszar committed
#include <stdio.h>
#include <math.h>
John Koleszar's avatar
John Koleszar committed
#include <limits.h>
#include "vp8/common/subpixel.h"
John Koleszar's avatar
John Koleszar committed
#include "vpx_ports/vpx_timer.h"

//#if CONFIG_SEGFEATURES
//#define DBG_PRNT_SEGMAP 1
John Koleszar's avatar
John Koleszar committed
#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD(x)     &cpi->common.rtcd.x
#define IF_RTCD(x)  (x)
#else
#define RTCD(x)     NULL
#define IF_RTCD(x)  NULL
#endif
#ifdef ENC_DEBUG
int enc_debug=0;
int mb_row_debug, mb_col_debug;
#endif

John Koleszar's avatar
John Koleszar committed
extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;

extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
extern void vp8_auto_select_speed(VP8_COMP *cpi);
extern void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
                                      MACROBLOCK *x,
                                      MB_ROW_COMP *mbr_ei,
                                      int mb_row,
                                      int count);
void vp8_build_block_offsets(MACROBLOCK *x);
void vp8_setup_block_ptrs(MACROBLOCK *x);
int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int recon_yoffset, int recon_uvoffset);
int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x );
John Koleszar's avatar
John Koleszar committed

John Koleszar's avatar
John Koleszar committed
#ifdef MODE_STATS
unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Yaowu Xu's avatar
Yaowu Xu committed
unsigned int inter_uv_modes[VP8_UV_MODES] = {0, 0, 0, 0};
unsigned int inter_b_modes[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int y_modes[VP8_YMODES] = {0, 0, 0, 0, 0};
unsigned int i8x8_modes[VP8_I8X8_MODES]={0  };
Yaowu Xu's avatar
Yaowu Xu committed
unsigned int uv_modes[VP8_UV_MODES] = {0, 0, 0, 0};
unsigned int uv_modes_y[VP8_YMODES][VP8_UV_MODES]=
{
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
Yaowu Xu's avatar
Yaowu Xu committed
unsigned int b_modes[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
John Koleszar's avatar
John Koleszar committed
#endif


/* activity_avg must be positive, or flat regions could get a zero weight
 *  (infinite lambda), which confounds analysis.
 * This also avoids the need for divide by zero checks in
 *  vp8_activity_masking().
 */
#define VP8_ACTIVITY_AVG_MIN (64)

/* This is used as a reference when computing the source variance for the
 *  purposes of activity masking.
 * Eventually this should be replaced by custom no-reference routines,
 *  which will be faster.
 */
static const unsigned char VP8_VAR_OFFS[16]=
{
    128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
};


#if CONFIG_T8X8

//INTRA mode transform size
//When all three criteria are off the default is 4x4
//#define INTRA_VARIANCE_ENTROPY_CRITERIA
#define INTRA_WTD_SSE_ENTROPY_CRITERIA
//#define INTRA_TEST_8X8_ONLY
//
//INTER mode transform size
//When all three criteria are off the default is 4x4
//#define INTER_VARIANCE_ENTROPY_CRITERIA
#define INTER_WTD_SSE_ENTROPY_CRITERIA
//#define INTER_TEST_8X8_ONLY

double variance_Block(short *b1, int pitch, int dimension)
{
    short ip[8][8]={{0}};
    short *b = b1;
    int i, j = 0;
    double mean = 0.0, variance = 0.0;
    for (i = 0; i < dimension; i++)
    {
        for (j = 0; j < dimension; j++)
        {
            ip[i][j] = b[j];
            mean += ip[i][j];
        }
        b += pitch;
    }
    mean /= (dimension*dimension);

    for (i = 0; i < dimension; i++)
    {
        for (j = 0; j < dimension; j++)
        {
            variance += (ip[i][j]-mean)*(ip[i][j]-mean);
        }
    }
    variance /= (dimension*dimension);
    return variance;
}

double mean_Block(short *b, int pitch, int dimension)
{
    short ip[8][8]={{0}};
    int i, j = 0;
    double mean = 0;
    for (i = 0; i < dimension; i++)
    {
        for (j = 0; j < dimension; j++)
        {
            ip[i][j] = b[j];
            mean += ip[i][j];
        }
        b += pitch;
    }
    mean /= (dimension*dimension);

    return mean;
}

int SSE_Block(short *b, int pitch, int dimension)
{
    int i, j, sse_block = 0;
    for (i = 0; i < dimension; i++)
    {
        for (j = 0; j < dimension; j++)
        {
            sse_block += b[j]*b[j];
        }
        b += pitch;
    }
   return sse_block;
}

double Compute_Variance_Entropy(MACROBLOCK *x)
{
    double variance_8[4] = {0.0, 0.0, 0.0, 0.0}, sum_var = 0.0, all_entropy = 0.0;
    variance_8[0] = variance_Block(x->block[0].src_diff, 16, 8);
    variance_8[1] = variance_Block(x->block[2].src_diff, 16, 8);
    variance_8[2] = variance_Block(x->block[8].src_diff, 16, 8);
    variance_8[3] = variance_Block(x->block[10].src_diff, 16, 8);
    sum_var = variance_8[0] + variance_8[1] + variance_8[2] + variance_8[3];
    if(sum_var)
    {
      int i;
      for(i = 0; i <4; i++)
      {
        if(variance_8[i])
        {
          variance_8[i] /= sum_var;
          all_entropy -= variance_8[i]*log(variance_8[i]);
        }
      }
    }
Loading full blame...