📄 msmpeg4.c
字号:
int pred, extquant;
int extrabits = 0;
if(s->msmpeg4_version==1){
int32_t *dc_val;
pred = msmpeg4v1_pred_dc(s, n, &dc_val);
/* update predictor */
*dc_val= level;
}else{
int16_t *dc_val;
pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
/* update predictor */
if (n < 4) {
*dc_val = level * s->y_dc_scale;
} else {
*dc_val = level * s->c_dc_scale;
}
}
/* do the prediction */
level -= pred;
if(s->msmpeg4_version<=2){
if (n < 4) {
put_bits(&s->pb,
v2_dc_lum_table[level+256][1],
v2_dc_lum_table[level+256][0]);
}else{
put_bits(&s->pb,
v2_dc_chroma_table[level+256][1],
v2_dc_chroma_table[level+256][0]);
}
}else{
sign = 0;
if (level < 0) {
level = -level;
sign = 1;
}
code = level;
if (code > DC_MAX)
code = DC_MAX;
else if( s->msmpeg4_version>=6 ) {
if( s->qscale == 1 ) {
extquant = (level + 3) & 0x3;
code = ((level+3)>>2);
} else if( s->qscale == 2 ) {
extquant = (level + 1) & 0x1;
code = ((level+1)>>1);
}
}
if (s->dc_table_index == 0) {
if (n < 4) {
put_bits(&s->pb, ff_table0_dc_lum[code][1], ff_table0_dc_lum[code][0]);
} else {
put_bits(&s->pb, ff_table0_dc_chroma[code][1], ff_table0_dc_chroma[code][0]);
}
} else {
if (n < 4) {
put_bits(&s->pb, ff_table1_dc_lum[code][1], ff_table1_dc_lum[code][0]);
} else {
put_bits(&s->pb, ff_table1_dc_chroma[code][1], ff_table1_dc_chroma[code][0]);
}
}
if(s->msmpeg4_version>=6 && s->qscale<=2)
extrabits = 3 - s->qscale;
if (code == DC_MAX)
put_bits(&s->pb, 8 + extrabits, level);
else if(extrabits > 0)//== VC1 && s->qscale<=2
put_bits(&s->pb, extrabits, extquant);
if (level != 0) {
put_bits(&s->pb, 1, sign);
}
}
}
/* Encoding of a block. Very similar to MPEG4 except for a different
escape coding (same as H263) and more vlc tables.
*/
void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
{
int level, run, last, i, j, last_index;
int last_non_zero, sign, slevel;
int code, run_diff, dc_pred_dir;
const RLTable *rl;
const uint8_t *scantable;
if (s->mb_intra) {
msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir);
i = 1;
if (n < 4) {
rl = &rl_table[s->rl_table_index];
} else {
rl = &rl_table[3 + s->rl_chroma_table_index];
}
run_diff = s->msmpeg4_version>=4;
scantable= s->intra_scantable.permutated;
} else {
i = 0;
rl = &rl_table[3 + s->rl_table_index];
if(s->msmpeg4_version<=2)
run_diff = 0;
else
run_diff = 1;
scantable= s->inter_scantable.permutated;
}
/* recalculate block_last_index for M$ wmv1 */
if(s->msmpeg4_version>=4 && s->msmpeg4_version<6 && s->block_last_index[n]>0){
for(last_index=63; last_index>=0; last_index--){
if(block[scantable[last_index]]) break;
}
s->block_last_index[n]= last_index;
}else
last_index = s->block_last_index[n];
/* AC coefs */
last_non_zero = i - 1;
for (; i <= last_index; i++) {
j = scantable[i];
level = block[j];
if (level) {
run = i - last_non_zero - 1;
last = (i == last_index);
sign = 0;
slevel = level;
if (level < 0) {
sign = 1;
level = -level;
}
if(level<=MAX_LEVEL && run<=MAX_RUN){
s->ac_stats[s->mb_intra][n>3][level][run][last]++;
}
#if 0
else
s->ac_stats[s->mb_intra][n>3][40][63][0]++; //esc3 like
#endif
code = get_rl_index(rl, last, run, level);
put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
if (code == rl->n) {
int level1, run1;
level1 = level - rl->max_level[last][run];
if (level1 < 1)
goto esc2;
code = get_rl_index(rl, last, run, level1);
if (code == rl->n) {
esc2:
put_bits(&s->pb, 1, 0);
if (level > MAX_LEVEL)
goto esc3;
run1 = run - rl->max_run[last][level] - run_diff;
if (run1 < 0)
goto esc3;
code = get_rl_index(rl, last, run1+1, level);
if (s->msmpeg4_version == 4 && code == rl->n)
goto esc3;
code = get_rl_index(rl, last, run1, level);
if (code == rl->n) {
esc3:
/* third escape */
put_bits(&s->pb, 1, 0);
put_bits(&s->pb, 1, last);
if(s->msmpeg4_version>=4){
if(s->esc3_level_length==0){
s->esc3_level_length=8;
s->esc3_run_length= 6;
//ESCLVLSZ + ESCRUNSZ
if(s->qscale<8)
put_bits(&s->pb, 6 + (s->msmpeg4_version>=6), 3);
else
put_bits(&s->pb, 8, 3);
}
put_bits(&s->pb, s->esc3_run_length, run);
put_bits(&s->pb, 1, sign);
put_bits(&s->pb, s->esc3_level_length, level);
}else{
put_bits(&s->pb, 6, run);
put_bits(&s->pb, 8, slevel & 0xff);
}
} else {
/* second escape */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
put_bits(&s->pb, 1, sign);
}
} else {
/* first escape */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
put_bits(&s->pb, 1, sign);
}
} else {
put_bits(&s->pb, 1, sign);
}
last_non_zero = i;
}
}
}
/****************************************/
/* decoding stuff */
static VLC mb_non_intra_vlc[4];
static VLC v2_dc_lum_vlc;
static VLC v2_dc_chroma_vlc;
static VLC cbpy_vlc;
static VLC v2_intra_cbpc_vlc;
static VLC v2_mb_type_vlc;
static VLC v2_mv_vlc;
static VLC v1_intra_cbpc_vlc;
static VLC v1_inter_cbpc_vlc;
static VLC inter_intra_vlc;
/* This table is practically identical to the one from h263
* except that it is inverted. */
static void init_h263_dc_for_msmpeg4(void)
{
int level, uni_code, uni_len;
for(level=-256; level<256; level++){
int size, v, l;
/* find number of bits */
size = 0;
v = abs(level);
while (v) {
v >>= 1;
size++;
}
if (level < 0)
l= (-level) ^ ((1 << size) - 1);
else
l= level;
/* luminance h263 */
uni_code= DCtab_lum[size][0];
uni_len = DCtab_lum[size][1];
uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility
if (size > 0) {
uni_code<<=size; uni_code|=l;
uni_len+=size;
if (size > 8){
uni_code<<=1; uni_code|=1;
uni_len++;
}
}
v2_dc_lum_table[level+256][0]= uni_code;
v2_dc_lum_table[level+256][1]= uni_len;
/* chrominance h263 */
uni_code= DCtab_chrom[size][0];
uni_len = DCtab_chrom[size][1];
uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility
if (size > 0) {
uni_code<<=size; uni_code|=l;
uni_len+=size;
if (size > 8){
uni_code<<=1; uni_code|=1;
uni_len++;
}
}
v2_dc_chroma_table[level+256][0]= uni_code;
v2_dc_chroma_table[level+256][1]= uni_len;
}
}
/* init all vlc decoding tables */
int ff_msmpeg4_decode_init(MpegEncContext *s)
{
static int done = 0;
int i;
MVTable *mv;
common_init(s);
if (!done) {
done = 1;
for(i=0;i<NB_RL_TABLES;i++) {
init_rl(&rl_table[i], static_rl_table_store[i]);
init_vlc_rl(&rl_table[i], 1);
}
for(i=0;i<2;i++) {
mv = &mv_tables[i];
init_vlc(&mv->vlc, MV_VLC_BITS, mv->n + 1,
mv->table_mv_bits, 1, 1,
mv->table_mv_code, 2, 2, 1);
}
init_vlc(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120,
&ff_table0_dc_lum[0][1], 8, 4,
&ff_table0_dc_lum[0][0], 8, 4, 1);
init_vlc(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120,
&ff_table0_dc_chroma[0][1], 8, 4,
&ff_table0_dc_chroma[0][0], 8, 4, 1);
init_vlc(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120,
&ff_table1_dc_lum[0][1], 8, 4,
&ff_table1_dc_lum[0][0], 8, 4, 1);
init_vlc(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120,
&ff_table1_dc_chroma[0][1], 8, 4,
&ff_table1_dc_chroma[0][0], 8, 4, 1);
init_vlc(&v2_dc_lum_vlc, DC_VLC_BITS, 512,
&v2_dc_lum_table[0][1], 8, 4,
&v2_dc_lum_table[0][0], 8, 4, 1);
init_vlc(&v2_dc_chroma_vlc, DC_VLC_BITS, 512,
&v2_dc_chroma_table[0][1], 8, 4,
&v2_dc_chroma_table[0][0], 8, 4, 1);
init_vlc(&cbpy_vlc, CBPY_VLC_BITS, 16,
&cbpy_tab[0][1], 2, 1,
&cbpy_tab[0][0], 2, 1, 1);
init_vlc(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4,
&v2_intra_cbpc[0][1], 2, 1,
&v2_intra_cbpc[0][0], 2, 1, 1);
init_vlc(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8,
&v2_mb_type[0][1], 2, 1,
&v2_mb_type[0][0], 2, 1, 1);
init_vlc(&v2_mv_vlc, V2_MV_VLC_BITS, 33,
&mvtab[0][1], 2, 1,
&mvtab[0][0], 2, 1, 1);
for(i=0; i<4; i++){
init_vlc(&mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128,
&wmv2_inter_table[i][0][1], 8, 4,
&wmv2_inter_table[i][0][0], 8, 4, 1); //FIXME name?
}
init_vlc(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
&ff_msmp4_mb_i_table[0][1], 4, 2,
&ff_msmp4_mb_i_table[0][0], 4, 2, 1);
init_vlc(&v1_intra_cbpc_vlc, V1_INTRA_CBPC_VLC_BITS, 8,
intra_MCBPC_bits, 1, 1,
intra_MCBPC_code, 1, 1, 1);
init_vlc(&v1_inter_cbpc_vlc, V1_INTER_CBPC_VLC_BITS, 25,
inter_MCBPC_bits, 1, 1,
inter_MCBPC_code, 1, 1, 1);
init_vlc(&inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
&table_inter_intra[0][1], 2, 1,
&table_inter_intra[0][0], 2, 1, 1);
}
switch(s->msmpeg4_version){
case 1:
case 2:
s->decode_mb= msmpeg4v12_decode_mb;
break;
case 3:
case 4:
s->decode_mb= msmpeg4v34_decode_mb;
break;
case 5:
s->decode_mb= wmv2_decode_mb;
case 6:
//FIXME + TODO VC1 decode mb
break;
}
s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe
return 0;
}
int msmpeg4_decode_picture_header(MpegEncContext * s)
{
int code;
#if 0
{
int i;
for(i=0; i<s->gb.size_in_bits; i++)
av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
// get_bits1(&s->gb);
av_log(s->avctx, AV_LOG_DEBUG, "END\n");
return -1;
}
#endif
if(s->msmpeg4_version==1){
int start_code, num;
start_code = (get_bits(&s->gb, 16)<<16) | get_bits(&s->gb, 16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -