📄 mvblock.c
字号:
#include "MVGlobal.h"
#include "MVBitstream.h"
#include "MVBlock.h"
extern const uint16_t scan_tables[3][64];
extern REVERSE_EVENT DCT3D[2][4096];
extern uint8_t const max_level[2][2][64];
extern uint8_t const max_run[2][2][64];
/*extracted from MbCoding.c 20070122 wuhaibin */
static __inline int get_coeff(Bitstream * bs,
int *run,
int *last,
int intra,
int short_video_header)
{
uint32_t mode;
int32_t level;
REVERSE_EVENT *reverse_event;
uint32_t cache = BitstreamShowBits(bs, 32);
if (GET_BITS(cache, 7) != ESCAPE) {
reverse_event = &DCT3D[intra][GET_BITS(cache, 12)];
if ((level = reverse_event->event.level) == 0)
goto error;
*last = reverse_event->event.last;
*run = reverse_event->event.run;
/* Don't forget to update the bitstream position */
BitstreamSkip(bs, reverse_event->len+1);
return (GET_BITS(cache, reverse_event->len+1)&0x01) ? -level : level;
}
/* flush 7bits of cache */
cache <<= 7;
if ((mode = GET_BITS(cache, 2)) < 3)
{
const int skip[3] = {1, 1, 2};
cache <<= skip[mode];
reverse_event = &DCT3D[intra][GET_BITS(cache, 12)];
if ((level = reverse_event->event.level) == 0)
goto error;
*last = reverse_event->event.last;
*run = reverse_event->event.run;
if (mode < 2)
{
/* first escape mode, level is offset */
level += max_level[intra][*last][*run];
}
else
{
/* second escape mode, run is offset */
*run += max_run[intra][*last][level] + 1;
}
/* Update bitstream position */
BitstreamSkip(bs, 7 + skip[mode] + reverse_event->len + 1);
return (GET_BITS(cache, reverse_event->len+1)&0x01) ? -level : level;
}
/* third escape mode - fixed length codes */
cache <<= 2;
*last = GET_BITS(cache, 1);
*run = (GET_BITS(cache, 7)&0x3f);
level = (GET_BITS(cache, 20)&0xfff);
/* Update bitstream position */
BitstreamSkip(bs, 30);
return (level << 20) >> 20;
error:
*run = VLC_ERROR;
return 0;
}
void get_intra_block(Bitstream * bs, int16_t * block,
int direction, int coeff)
{
const uint16_t *scan = scan_tables[direction];
int level, run, last;
do{
level = get_coeff(bs, &run, &last, 1, 0);
if (run == -1)
{
break;
}
coeff += run;
if(coeff>=64)
{
return;
}
block[scan[coeff]] = level;
coeff++;
}while (!last);
}
void get_inter_block_h263(Bitstream * bs, int16_t * block,
int direction, const int quant,
const uint16_t *matrix)
{
const uint16_t *scan = scan_tables[direction];
const uint16_t quant_m_2 = quant << 1;
const uint16_t quant_add = (quant & 1 ? quant : quant - 1);
int p;
int level;
int run;
int last;
p = 0;
do
{
level = get_coeff(bs, &run, &last, 0, 0);
if (run == -1)
{
break;
}
p += run;
if(p>=64)
{
return;
}
if (level < 0)
{
level = level*quant_m_2 - quant_add;
block[scan[p]] = (level >= -2048 ? level : -2048);
}
else
{
level = level * quant_m_2 + quant_add;
block[scan[p]] = (level <= 2047 ? level : 2047);
}
p++;
} while (!last);
}
void get_inter_block_mpeg(Bitstream * bs, int16_t * block,
int direction, const int quant,
const uint16_t *matrix)
{
const uint16_t *scan = scan_tables[direction];
uint32_t sum = 0;
int p;
int level;
int run;
int last;
p = 0;
do
{
level = get_coeff(bs, &run, &last, 0, 0);
if (run == -1)
{
break;
}
p += run;
if(p>=64)
{
return;
}
if (level < 0)
{
level = ((2 * -level + 1) * matrix[scan[p]] * quant) >> 4;
block[scan[p]] = (level <= 2048 ? -level : -2048);
}
else
{
level = ((2 * level + 1) * matrix[scan[p]] * quant) >> 4;
block[scan[p]] = (level <= 2047 ? level : 2047);
}
sum ^= block[scan[p]];
p++;
} while (!last);
if ((sum & 1) == 0)
{
block[63] ^= 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -