?? mbcoding.c
字號:
/******************************************************************************
* *
* This file is part of XviD, a free MPEG-4 video encoder/decoder *
* *
* XviD is an implementation of a part of one or more MPEG-4 Video tools *
* as specified in ISO/IEC 14496-2 standard. Those intending to use this *
* software module in hardware or software products are advised that its *
* use may infringe existing patents or copyrights, and any such use *
* would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies, will have no liability for use of this software or *
* modifications or derivatives thereof. *
* *
* XviD 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. *
* *
* XviD 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-1307 USA *
* *
******************************************************************************/
/******************************************************************************
* *
* mbcoding.c *
* *
* Copyright (C) 2002 - Michael Militzer <isibaar@xvid.org> *
* *
* For more information visit the XviD homepage: http://www.xvid.org *
* *
******************************************************************************/
/******************************************************************************
* *
* Revision history: *
* *
* 28.06.2002 added check_resync_marker() *
* 14.04.2002 bframe encoding *
* 08.03.2002 initial version; isibaar *
* *
******************************************************************************/
#include <stdlib.h>
/*#include <malloc.h>*/
#include "../portab.h"
#include "bitstream.h"
#include "zigzag.h"
#include "vlc_codes.h"
#include "mbcoding.h"
#include "../utils/mbfunctions.h"
/* size=4095*64*2=524160,whq,2002.12-11 */
/* save intra,inter (run,level,last) pair */
VLC intra_table[524160];
VLC inter_table[524160];
/*!
************************************************************************
* \replace goto using function run_level_code
* \brief
* get vlc code for run-level pair
*
* \author , whq
************************************************************************
*/
/*
void run_level_code(VLC **coeff_ptr,VLC *vlc[2],
int32_t level,ptr_t run,int32_t intra);*/
static __inline
void run_level_code(VLC **coeff_ptr, /*pointer to the suitable coeff table*/
VLC *vlc[2], /*pointer to the array for inter or intra table*/
int32_t level, /* level */
ptr_t run, /* run */
int32_t intra) /* intra or inter*/
{
int32_t abs_level;
if (level != 0) {
abs_level = abs(level)-1;
vlc[intra]->code =
(vlc[intra]->
code << (coeff_ptr[run][abs_level ].len +
1)) | (coeff_ptr[run][abs_level ].code<<1);
vlc[intra]->len =
(coeff_ptr[run][abs_level ].len + 1) +
vlc[intra]->len;
if (level < 0)
/*vlc[intra]->code += 1;*/
vlc[intra]->code ++;
}
vlc[intra]++;
}
/*!
************************************************************************
* \brief
* init,get vlc code for all (last,run,level) pair
*
*
************************************************************************
*/
void
init_vlc_tables(void)
{
int32_t k, l, i, intra, last;
/* int32_t temp;*//*用于保存level,run值改變之前的值,用于后來恢復使用*/
VLC *vlc[2];
VLC **coeff_ptr;
/* move variable out of loop */
/* whq,2002.12.19,save array index */
int32_t index;
int8_t *max_level_ptr;
int8_t *max_run_ptr;
int32_t level,abs_level;
uint32_t run;
/* whq,2002.12.19 */
vlc[0] = intra_table;
vlc[1] = inter_table;
/* generate encoding vlc lookup tables*/
/* the lookup table idea is taken from the excellent fame project by Vivien Chapellier*/
for (i = 0; i < 4; i++) {
/* to be optimize */
intra = i % 2;
last = i / 2;
index = last + 2 * intra;
coeff_ptr = coeff_vlc[index];
for (k = -2047; k < 2048; k++) { /* level*/
max_level_ptr = max_level[index];
max_run_ptr = max_run[index];
for (l = 0; l < 64; l++) { /* run*/
level = k;
abs_level = abs(level);
run = l;
if ((abs_level <= max_level_ptr[run]) && (run <= (uint32_t) max_run_ptr[abs_level])) { /* level < max_level and run < max_run*/
vlc[intra]->code = 0;
vlc[intra]->len = 0;
/* if (level != 0) {
vlc[intra]->code =
(vlc[intra]->
code << (coeff_ptr[run][abs(level) - 1].len +
1)) | (coeff_ptr[run][abs(level) -
1].code << 1);
vlc[intra]->len =
(coeff_ptr[run][abs(level) - 1].len + 1) +
vlc[intra]->len;
if (level < 0)
vlc[intra]->code += 1;
}
vlc[intra]++; */
run_level_code(coeff_ptr,vlc,level,run,intra);
continue;
/*goto loop_end;*/
}
else
{
if (level > 0) /* correct level*/
level -= max_level_ptr[run];
else
level += max_level_ptr[run];
abs_level = abs(level);
if ((abs_level <= max_level_ptr[run]) &&
(run <= (uint32_t) max_run_ptr[abs_level])) {
vlc[intra]->code = 0x06;
vlc[intra]->len = 8;
/* if (level != 0) {
vlc[intra]->code =
(vlc[intra]->
code << (coeff_ptr[run][abs(level) - 1].len +
1)) | (coeff_ptr[run][abs(level) -
1].code << 1);
vlc[intra]->len =
(coeff_ptr[run][abs(level) - 1].len + 1) +
vlc[intra]->len;
if (level < 0)
vlc[intra]->code += 1;
}
vlc[intra]++;*/
run_level_code(coeff_ptr,vlc,level,run,intra);
continue;
/*goto loop_end;*/
}
/* restore level*/
level=k;
abs_level = abs(level);
run -= max_run_ptr[abs_level] + 1; /* and change run*/
if ((abs_level <= max_level_ptr[run]) &&
(run <= (uint32_t) max_run_ptr[abs_level])) {
vlc[intra]->code = 0x0e;
vlc[intra]->len = 9;
/* if (level != 0) {
vlc[intra]->code =
(vlc[intra]->
code << (coeff_ptr[run][abs(level) - 1].len +
1)) | (coeff_ptr[run][abs(level) -
1].code << 1);
vlc[intra]->len =
(coeff_ptr[run][abs(level) - 1].len + 1) +
vlc[intra]->len;
if (level < 0)
vlc[intra]->code += 1;
}
vlc[intra]++; */
run_level_code(coeff_ptr,vlc,level,run,intra);
continue;
/* goto loop_end;*/
}
/*restore run*/
/*run += max_run_ptr[abs(level)] + 1;*/
run=l;
}
vlc[intra]->code =
(uint32_t) ((l << 14) | (0x1e + last) << 20) | (1 << 13) |
((k & 0xfff) << 1) | 1;
vlc[intra]->len = 30;
vlc[intra]++;
continue;
/* loop_end:
if (level != 0) {
vlc[intra]->code =
(vlc[intra]->
code << (coeff_ptr[run][abs(level) - 1].len +
1)) | (coeff_ptr[run][abs(level) -
1].code << 1);
vlc[intra]->len =
(coeff_ptr[run][abs(level) - 1].len + 1) +
vlc[intra]->len;
if (level < 0)
vlc[intra]->code += 1;
}
vlc[intra]++; */
}
}
}
}
/*!
************************************************************************
* \brief
* get vlc code for motion vector
*
************************************************************************
*/
static /*__inline*/ int16_t /* ==> return the bits for vector */
CodeVector(Bitstream * bs, /*<--> bitstream buffer */
int32_t value, /*<-- vector value */
int32_t f_code, /*<-- range of vector */
Statistics * pStat /*<--> stat vector count and value */
)/*修改此函數使其返回運動向量占的位數 modify by lxq*/
{
int16_t vector_length=0;
uint16_t code;
const int scale_factor = 1 << (f_code - 1);
const int cmp = scale_factor << 5;
if (value < (-1 * cmp))
/*value += 64 * scale_factor;*/
value += scale_factor<<6;
if (value > (cmp - 1))
/*value -= 64 * scale_factor;*/
value -= scale_factor<<6;
pStat->iMvSum += value * value;
pStat->iMvCount++;
code =value + 32;
BitstreamPutBits(bs, mb_motion_table[code].code,
mb_motion_table[code].len);
vector_length+=mb_motion_table[code].len;
/* if (value == 0) {
BitstreamPutBits(bs, mb_motion_table[32].code,
mb_motion_table[32].len);
vector_length+=mb_motion_table[32].len;
} else {*/
/* f_code--;
sign = (value < 0);
*/
/*whq,2002,12,25*/
/*
if (value >= length)*/
/* value -= 2 * length;*/
/* value -= length<<1;*/
/* else if (value < -length)*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -