?? analyse.c
字號(hào):
/***************************************************************************** * analyse.c: h264 encoder library ***************************************************************************** * Copyright (C) 2003 Laurent Aimar * $Id: analyse.c,v 1.6 2004/03/28 12:37:11 fenrir Exp $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <stdint.h>#include <math.h>#include "../core/common.h"#include "me.h"static const uint8_t block_idx_x[16] = { 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3 };static const uint8_t block_idx_y[16] = { 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 };/* * Handle intra mb *//* Max = 4 */static void predict_16x16_mode_available( x264_macroblock_t *mb, int *mode, int *pi_count ){ if( ( mb->i_neighbour & (MB_LEFT|MB_TOP) ) == (MB_LEFT|MB_TOP) ) { /* top and left avaible */ *mode++ = I_PRED_16x16_V; *mode++ = I_PRED_16x16_H; *mode++ = I_PRED_16x16_DC; *mode++ = I_PRED_16x16_P; *pi_count = 4; } else if( ( mb->i_neighbour & MB_LEFT ) ) { /* left available*/ *mode++ = I_PRED_16x16_DC_LEFT; *mode++ = I_PRED_16x16_H; *pi_count = 2; } else if( ( mb->i_neighbour & MB_TOP ) ) { /* top available*/ *mode++ = I_PRED_16x16_DC_TOP; *mode++ = I_PRED_16x16_V; *pi_count = 2; } else { /* none avaible */ *mode = I_PRED_16x16_DC_128; *pi_count = 1; }}/* Max = 4 */static void predict_8x8_mode_available( x264_macroblock_t *mb, int *mode, int *pi_count ){ if( ( mb->i_neighbour & (MB_LEFT|MB_TOP) ) == (MB_LEFT|MB_TOP) ) { /* top and left avaible */ *mode++ = I_PRED_CHROMA_V; *mode++ = I_PRED_CHROMA_H; *mode++ = I_PRED_CHROMA_DC; *mode++ = I_PRED_CHROMA_P; *pi_count = 4; } else if( ( mb->i_neighbour & MB_LEFT ) ) { /* left available*/ *mode++ = I_PRED_CHROMA_DC_LEFT; *mode++ = I_PRED_CHROMA_H; *pi_count = 2; } else if( ( mb->i_neighbour & MB_TOP ) ) { /* top available*/ *mode++ = I_PRED_CHROMA_DC_TOP; *mode++ = I_PRED_CHROMA_V; *pi_count = 2; } else { /* none avaible */ *mode = I_PRED_CHROMA_DC_128; *pi_count = 1; }}/* MAX = 8 */static void predict_4x4_mode_available( x264_macroblock_t *mb, int idx, int *mode, int *pi_count ){ int b_a, b_b, b_c; static const int needmb[16] = { MB_LEFT|MB_TOP, MB_TOP, MB_LEFT, MB_PRIVATE, MB_TOP, MB_TOP|MB_TOPRIGHT, 0, MB_PRIVATE, MB_LEFT, 0, MB_LEFT, MB_PRIVATE, 0, MB_PRIVATE, 0, MB_PRIVATE }; /* FIXME even when b_c == 0 there is some case where missing pixels * are emulated and thus more mode are available TODO * analysis and encode should be fixed too */ b_a = (needmb[idx]&mb->i_neighbour&MB_LEFT) == (needmb[idx]&MB_LEFT); b_b = (needmb[idx]&mb->i_neighbour&MB_TOP) == (needmb[idx]&MB_TOP); b_c = (needmb[idx]&mb->i_neighbour&(MB_TOPRIGHT|MB_PRIVATE)) == (needmb[idx]&(MB_TOPRIGHT|MB_PRIVATE)); if( b_a && b_b ) { *mode++ = I_PRED_4x4_DC; *mode++ = I_PRED_4x4_H; *mode++ = I_PRED_4x4_V; *mode++ = I_PRED_4x4_DDR; *mode++ = I_PRED_4x4_VR; *mode++ = I_PRED_4x4_HD; *mode++ = I_PRED_4x4_HU; *pi_count = 7; if( b_c ) { *mode++ = I_PRED_4x4_DDL; *mode++ = I_PRED_4x4_VL; (*pi_count) += 2; } } else if( b_a && !b_b ) { *mode++ = I_PRED_4x4_DC_LEFT; *mode++ = I_PRED_4x4_H; *pi_count = 2; } else if( !b_a && b_b ) { *mode++ = I_PRED_4x4_DC_TOP; *mode++ = I_PRED_4x4_V; *pi_count = 2; } else { *mode++ = I_PRED_4x4_DC_128; *pi_count = 1; }}typedef struct{ /* conduct the analysis using this lamda and QP */ int i_lambda; int i_qp; /* I: Intra part */ /* Luma part 16x16 and 4x4 modes stats */ int i_sad_i16x16; int i_predict16x16; int i_sad_i4x4; int i_predict4x4[4][4]; /* Chroma part */ int i_sad_i8x8; int i_predict8x8; /* II: Inter part P frame */ int i_sad_p16x16; int i_ref_p16x16; int i_mv_p16x16[2]; int i_sad_p16x8; int i_ref_p16x8; int i_mv_p16x8[2][2]; int i_sad_p8x16; int i_ref_p8x16; int i_mv_p8x16[2][2]; int i_sad_p8x8; int i_ref_p8x8; int i_sub_partition_p8x8[4]; int i_mv_p8x8[4][4][2]; /* II: Inter part B frame */ int i_sad_b16x16_l0; int i_ref_b16x16_l0; int i_mv_b16x16_l0[2]; int i_sad_b16x16_l1; int i_ref_b16x16_l1; int i_mv_b16x16_l1[2]; int i_sad_b16x16_bi; /* used the same ref and mv as l0 and l1 (at least for now) */ int i_sad_b16x8_l0; int i_ref_b16x8_l0; int i_mv_b16x8_l0[2]; int i_sad_b8x16_l0; int i_ref_b8x16_l0; int i_mv_b8x16_l0[2];} x264_mb_analysis_t;static const int i_qp0_cost_table[52] ={ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 8, 9,10,11,13,14, 16,18,20,23,25,29,32,36, 40,45,51,57,64,72,81,91};static void x264_mb_analyse_intra_chroma( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ x264_mb_context_t *ctx = mb->context; int i; int i_max; int predict_mode[9]; uint8_t *p_dstc[2], *p_srcc[2]; int i_dstc[2], i_srcc[2]; /* 8x8 prediction selection for chroma */ p_dstc[0] = ctx->p_fdec[1]; i_dstc[0] = ctx->i_fdec[1]; p_dstc[1] = ctx->p_fdec[2]; i_dstc[1] = ctx->i_fdec[2]; p_srcc[0] = ctx->p_img[1]; i_srcc[0] = ctx->i_img[1]; p_srcc[1] = ctx->p_img[2]; i_srcc[1] = ctx->i_img[2]; predict_8x8_mode_available( mb, predict_mode, &i_max ); res->i_sad_i8x8 = -1; for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_8x8[i_mode]( p_dstc[0], i_dstc[0] ); h->predict_8x8[i_mode]( p_dstc[1], i_dstc[1] ); /* we calculate the cost */ i_sad = h->pixf.satd[PIXEL_8x8]( p_dstc[0], i_dstc[0], p_srcc[0], i_srcc[0] ) + h->pixf.satd[PIXEL_8x8]( p_dstc[1], i_dstc[1], p_srcc[1], i_srcc[1] ) + res->i_lambda * bs_size_ue( x264_mb_pred_mode8x8_fix[i_mode] ); /* if i_score is lower it is better */ if( res->i_sad_i8x8 == -1 || res->i_sad_i8x8 > i_sad ) { res->i_predict8x8 = i_mode; res->i_sad_i8x8 = i_sad; } }}static void x264_mb_analyse_intra( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ int i, idx; int i_max; int predict_mode[9]; uint8_t *p_dst, *p_src; int i_dst, i_src; p_dst = mb->context->p_fdec[0]; i_dst = mb->context->i_fdec[0]; p_src = mb->context->p_img[0]; i_src = mb->context->i_img[0]; /*---------------- Try all mode and calculate their score ---------------*/ /* 16x16 prediction selection */ mb->i_type = I_16x16; res->i_sad_i16x16 = -1; predict_16x16_mode_available( mb, predict_mode, &i_max ); for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_16x16[i_mode]( p_dst, i_dst ); /* we calculate the diff and get the square sum of the diff */ i_sad = h->pixf.satd[PIXEL_16x16]( p_dst, i_dst, p_src, i_src ) + res->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] ); /* if i_score is lower it is better */ if( res->i_sad_i16x16 == -1 || res->i_sad_i16x16 > i_sad ) { res->i_predict16x16 = i_mode; res->i_sad_i16x16 = i_sad; } } /* 4x4 prediction selection */ mb->i_type = I_4x4; res->i_sad_i4x4 = 0; for( idx = 0; idx < 16; idx++ ) { uint8_t *p_src_by; uint8_t *p_dst_by; int i_best; int x, y; int i_pred_mode; i_pred_mode= x264_mb_predict_intra4x4_mode( h, mb, idx ); x = block_idx_x[idx]; y = block_idx_y[idx]; p_src_by = p_src + 4 * x + 4 * y * i_src; p_dst_by = p_dst + 4 * x + 4 * y * i_dst; i_best = -1; predict_4x4_mode_available( mb, idx, predict_mode, &i_max ); for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_4x4[i_mode]( p_dst_by, i_dst ); /* we calculate diff and get the square sum of the diff */ i_sad = h->pixf.satd[PIXEL_4x4]( p_dst_by, i_dst, p_src_by, i_src ); i_sad += res->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix[i_mode] ? 1 : 4); /* if i_score is lower it is better */ if( i_best == -1 || i_best > i_sad ) { res->i_predict4x4[x][y] = i_mode; i_best = i_sad; } } res->i_sad_i4x4 += i_best; /* we need to encode this mb now (for next ones) */ mb->block[idx].i_intra4x4_pred_mode = res->i_predict4x4[x][y]; h->predict_4x4[res->i_predict4x4[x][y]]( p_dst_by, i_dst ); x264_mb_encode_i4x4( h, mb, idx, res->i_qp ); } res->i_sad_i4x4 += res->i_lambda * 24; /* from JVT (SATD0) */}static void x264_mb_analyse_inter_p_p8x8( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ x264_mb_context_t *ctx = mb->context; int i_ref = res->i_ref_p16x16; uint8_t *p_fref = ctx->p_fref0[i_ref][0]; int i_fref = ctx->i_fref0[i_ref][0]; uint8_t *p_img = ctx->p_img[0]; int i_img = ctx->i_img[0]; int i; res->i_ref_p8x8 = i_ref; res->i_sad_p8x8 = 0; mb->i_partition = D_8x8; for( i = 0; i < 4; i++ ) { static const int test8x8_mode[4] = { D_L0_8x8, D_L0_8x4, D_L0_4x8, D_L0_4x4 }; static const int test8x8_pix[4] = { PIXEL_8x8, PIXEL_8x4, PIXEL_4x8, PIXEL_4x4 }; static const int test8x8_pos_x[4][4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 4, 0, 0 }, { 0, 4, 0, 4 } }; static const int test8x8_pos_y[4][4] = { { 0, 0, 0, 0 }, { 0, 4, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 4, 4 } }; int i_test; int mvp[4][2]; int mv[4][2]; int x, y; int i_sub; int i_b_satd; y = 8 * (i / 2); x = 8 * (i % 2); i_b_satd = -1; i_test = 0; /* FIXME as it's tooooooo slow test only 8x8 */ //for( i_test = 0; i_test < 4; i_test++ ) { int i_satd; i_satd = 0; mb->i_sub_partition[i] = test8x8_mode[i_test]; for( i_sub = 0; i_sub < x264_mb_partition_count_table[test8x8_mode[i_test]]; i_sub++ ) { x264_mb_predict_mv( mb, 0, i, i_sub, mvp[i_sub] ); mv[i_sub][0] = mvp[i_sub][0]; mv[i_sub][1] = mvp[i_sub][1]; i_satd += h->me( h, &p_fref[(y+test8x8_pos_y[i_test][i_sub])*i_fref +x+test8x8_pos_x[i_test][i_sub]], i_fref, &p_img[(y+test8x8_pos_y[i_test][i_sub])*i_img +x+test8x8_pos_x[i_test][i_sub]], i_img, test8x8_pix[i_test], res->i_lambda, &mv[i_sub][0], &mv[i_sub][1] ); }
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -