📄 fame_shape.c
字号:
/* libfame - Fast Assembly MPEG Encoder Library Copyright (C) 2000-2001 Vivien Chappelier Damien Vincent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "fame.h"#include "fame_shape.h"static void int_init(fame_shape_t *shape, int mb_width, int mb_height, unsigned int flags);static void int_close(fame_shape_t *shape);static void int_enter(fame_shape_t *shape, unsigned char *mask, unsigned char *ref, unsigned char alpha_th);static fame_bab_t int_encode_intra_shape(fame_shape_t *shape, int mb_x, int mb_y, unsigned char **bab, unsigned char *pattern);FAME_CONSTRUCTOR(fame_shape_t){ FAME_OBJECT(this)->name = "shape coder"; FAME_SHAPE(this)->init = int_init; FAME_SHAPE(this)->close = int_close; FAME_SHAPE(this)->enter = int_enter; FAME_SHAPE(this)->encode_intra_shape = int_encode_intra_shape; return(this);}static unsigned char th[256] ={ 5, 6, 6, 8, 6, 7, 7, 8, 6, 5, 7, 6, 8, 8, 8, 8, 6, 5, 5, 9, 8, 8, 8, 8, 7, 6, 8, 8, 8, 8, 8, 9, 6, 7, 5, 8, 7, 9, 8, 8, 7, 8, 8, 8, 8, 8, 8, 9, 7, 8, 8, 8, 8, 10, 8, 9, 8, 10, 8, 11, 8, 11, 9, 10, 6, 7, 7, 8, 7, 8, 8, 8, 7, 8, 8, 8, 9, 8, 10, 9, 7, 8, 8, 8, 8, 7, 8, 9, 8, 10, 8, 9, 8, 11, 9, 10, 7, 8, 8, 10, 8, 10, 10, 11, 8, 8, 10, 9, 10, 11, 11, 10, 8, 8, 8, 11, 8, 9, 11, 12, 8, 9, 11, 12, 11, 12, 10, 11, 6, 7, 7, 9, 7, 6, 8, 8, 5, 8, 8, 8, 6, 8, 10, 9, 8, 8, 8, 10, 8, 10, 8, 9, 8, 10, 10, 11, 10, 11, 9, 10, 8, 8, 6, 10, 8, 8, 10, 9, 8, 8, 10, 9, 8, 9, 9, 10, 9, 8, 10, 11, 8, 13, 9, 10, 10, 11, 11, 14, 11, 12, 10, 11, 7, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 9, 8, 9, 11, 10, 9, 8, 8, 9, 8, 11, 9, 10, 10, 11, 9, 10, 11, 12, 10, 11, 8, 8, 8, 11, 10, 11, 11, 10, 8, 11, 9, 12, 11, 12, 14, 11, 10, 9, 11, 12, 11, 12, 12, 11, 9, 12, 12, 13, 12, 13, 11, 14};#define SIZE_BAB16 20#define SIZE_BAB8 12#define SIZE_BAB4 8#define SIZE_DS1DEMI 8#define SIZE_DS1QUART 4static unsigned char pbv0[4][4] ={ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};#define INTERPOLATION(tableau,i,j,interp,cf,instr1,instr2,instr3,instr4) \{ \ tmp = \ tableau[i-1][j+1] + tableau[i-1][j] + \ tableau[i][j-1] + tableau[i+1][j-1] + \ tableau[i+2][j] + tableau[i+2][j+1] + \ tableau[i+1][j+2] + tableau[i][j+2] + \ ((tableau[i][j] + tableau[i][j+1] + \ tableau[i+1][j+1] + tableau[i+1][j])<<1); \ /* Interpolation of P1 */ \ cf = \ (tableau[i-1][j+1]<<0) + (tableau[i-1][j]<<1) + \ (tableau[i][j-1]<<2) + (tableau[i+1][j-1]<<3) + \ (tableau[i+2][j]<<4) + (tableau[i+2][j+1]<<5) + \ (tableau[i+1][j+2]<<6) + (tableau[i][j+2]<<7); \ interp = tmp + (tableau[i][j]<<1); \ instr1; \ /* Interpolation of P2 */ \ cf = ((cf<<2)&255) + (tableau[i+1][j+2]<<0) + (tableau[i][j+2]<<1); \ interp = tmp + (tableau[i][j+1]<<1); \ instr2; \ /* Interpolation of P3 */ \ cf = ((cf<<2)&255) + (tableau[i+2][j]<<0) + (tableau[i+2][j+1]<<1); \ interp = tmp + (tableau[i+1][j+1]<<1); \ instr3; \ /* Interpolation of P4 */ \ cf = ((cf<<2)&255) + (tableau[i][j-1]<<0) + (tableau[i+1][j-1]<<1); \ interp = tmp + (tableau[i+1][j]<<1); \ instr4; \}/* Returns the number of different elements between array input1 and input2 */static unsigned char mean_absolute_binary_error(unsigned char *input1, int pitch1, unsigned char *input2, int pitch2, int size){ int j,i; unsigned char error = 0; for(i=0; i<size; i++) { for(j=0; j<size; j++) error += (input2[j] ^ input1[j]) & 1; input1 += pitch1; input2 += pitch2; } return error;}static void int_init(fame_shape_t *shape, int mb_width, int mb_height, unsigned int flags){ shape->mb_width = mb_width; shape->mb_height = mb_height; shape->pitch = (shape->mb_width << 4); shape->flags = flags;}static void int_close(fame_shape_t *shape){}static void int_enter(fame_shape_t *shape, unsigned char *input, unsigned char *ref, unsigned char alpha_th){ shape->recon = ref; shape->input = input; shape->alpha_th = alpha_th;}static fame_bab_t int_encode_intra_shape(fame_shape_t *shape, int mb_x, int mb_y, unsigned char **bab, unsigned char *pattern){ /* tmp values or counters */ int i, j; unsigned char tmp; unsigned char tmp_downsample[8][8]; unsigned char *input; unsigned char *output; /* the interval to point at the next line of the picture (pitch) */ int pitch, pitch4; /* index of the current block in the picture */ int offset; /* the way the bab is coded */ int is_bab_not_coded, is_bab_all_coded, is_bab_coded; /* a modified alpha_th */ unsigned char m_alpha_th; /* Average of 2x2 pixels (s8) and average of 4x4 pixels (s4) */ /* used for downsampling */ unsigned char s8, s4; /* Reconstructed block (after upsampling) : -1 * 0 1 2 ... 15 * 16 */ unsigned char tmp_recon8x8[20][20]; unsigned char tmp_recon4x4[12][12]; /* filter context for upsampling */ unsigned char cf; /* Interpolation for upsampling */ unsigned char interp; /* error between a bab and the bab from the input picture */ unsigned char error; *bab = NULL; m_alpha_th = (shape->alpha_th>>4); pitch = shape->pitch; pitch4 = pitch<<2; offset = (mb_y << 4) * pitch + (mb_x << 4);#define bab16x16 shape->bab16x16#define bab8x8 shape->bab8x8#define bab4x4 shape->bab4x4 /**************************** * not coded or all coded ? * ****************************/ if(!shape->input) { FAME_WARNING("No shape provided! Assuming opaque macroblock\n"); is_bab_all_coded = 1; is_bab_not_coded = 0; } else { input = shape->input + offset; is_bab_not_coded = 1; is_bab_all_coded = 1; for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { error = mean_absolute_binary_error(input, pitch, &(pbv0[0][0]), 4, 4); is_bab_not_coded &= (error>m_alpha_th)?0:1; is_bab_all_coded &= (16-error>m_alpha_th)?0:1; input += 4; } input += pitch4 - 16; } } if(is_bab_not_coded) { output = shape->recon + offset; for(i = 0; i < 16; i++) { memset(output, 0, 16); output += pitch; } *pattern = 0; return bab_not_coded; } if(is_bab_all_coded) { output = shape->recon + offset; for(i = 0; i < 16; i++) { memset(output, 1, 16); output += pitch; } *pattern = 15; return bab_all_coded; } /*************** * shape coded * ***************/ /* --- Down-Sampling --- */ /* Down-sampling : Cr=1 */ input = shape->input + offset; for(i=2; i<18; i++) { for(j=2; j<18; j++) { bab16x16[i][j] = (*input)?1:0; input ++; } input += pitch - 16; } /* Down-sampling : Cr=1/2 */ input = shape->input + offset; for(i=2; i<10; i++) { for(j=2; j<10; j++) { s8 = (input[0] >> 2) + (input[pitch+0] >> 2) + (input[1] >> 2) + (input[pitch+1] >> 2); bab8x8[i][j] = (s8>=126)?1:0; tmp_downsample[i-2][j-2] = s8; /* save to downsample again and faster */ input += 2; } input += (pitch<<1) - 16; } /* Down-sampling : Cr=1/4 */ input = &(tmp_downsample[0][0]); for(i=2; i<6; i++) { for(j=2; j<6; j++) { s4 = (input[0] >> 2) + (input[SIZE_DS1DEMI+0] >> 2) + (input[1] >> 2) + (input[SIZE_DS1DEMI+1] >> 2); bab4x4[i][j] = (s4>=126)?1:0; input += 2; } input += SIZE_DS1DEMI*2 - 8; } /* --- fetch borders for upsampling (p29 and p34) --- */ /* To fill the borders, we need the previous reconstructed binary blocks */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -