📄 mvcommon.c
字号:
#include "MVCommon.h"
#include "MVBitstream.h"
extern const uint8_t default_intra_matrix[64];
extern const uint8_t default_inter_matrix[64];
extern VLC sprite_trajectory_len[15];
extern const uint32_t multipliers[32];
int mavrix_fine_start_code(Bitstream * bs)
{
unsigned int start_tag = 0x00000001;
unsigned int start_code;
BitstreamByteAlign(bs);
repeat:
while(BitstreamShowBits(bs, 24) != start_tag)
{
BitstreamSkip(bs, 8);
if((uint32_t)((bs->tail - bs->start)<<2) >= bs->length)
return -1;
}
start_code = BitstreamGetBits(bs, 32);
if((start_code >> 4) == 0x12)
return VIDOBJLAY_START_CODE;
else
if(start_code == VOP_START_CODE)
return VOP_START_CODE;
else
goto repeat;
return -1;
}
uint32_t log2bin(uint32_t value)
{
int n = 0;
while (value)
{
value >>= 1;
n++;
}
return n;
}
const uint16_t *get_intra_matrix(const uint16_t * mpeg_quant_matrices)
{
return(mpeg_quant_matrices + 0*64);
}
const uint16_t *get_inter_matrix(const uint16_t * mpeg_quant_matrices)
{
return(mpeg_quant_matrices + 4*64);
}
const uint8_t *get_default_intra_matrix(void)
{
return default_intra_matrix;
}
const uint8_t *get_default_inter_matrix(void)
{
return default_inter_matrix;
}
void set_intra_matrix(uint16_t * mpeg_quant_matrices, const uint8_t * matrix)
{
int i;
uint16_t *intra_matrix = mpeg_quant_matrices + 0*64;
uint16_t *intra_matrix1 = mpeg_quant_matrices + 1*64;
uint16_t *intra_matrix_fix = mpeg_quant_matrices + 2*64;
uint16_t *intra_matrix_fixl = mpeg_quant_matrices + 3*64;
for (i = 0; i < 64; i++)
{
intra_matrix[i] = (!i) ? (uint16_t)8: (uint16_t)matrix[i];
intra_matrix1[i] = (intra_matrix[i]>>1);
intra_matrix1[i] += ((intra_matrix[i] == 1) ? 1: 0);
intra_matrix_fix[i] = FIX(intra_matrix[i]);
intra_matrix_fixl[i] = FIXL(intra_matrix[i]);
}
}
void set_inter_matrix(uint16_t * mpeg_quant_matrices, const uint8_t * matrix)
{
int i;
uint16_t *inter_matrix = mpeg_quant_matrices + 4*64;
uint16_t *inter_matrix1 = mpeg_quant_matrices + 5*64;
uint16_t *inter_matrix_fix = mpeg_quant_matrices + 6*64;
uint16_t *inter_matrix_fixl = mpeg_quant_matrices + 7*64;
for (i = 0; i < 64; i++)
{
inter_matrix1[i] = ((inter_matrix[i] = (int16_t) matrix[i])>>1);
inter_matrix1[i] += ((inter_matrix[i] == 1) ? 1: 0);
inter_matrix_fix[i] = FIX(inter_matrix[i]);
inter_matrix_fixl[i] = FIXL(inter_matrix[i]);
}
}
int bs_get_spritetrajectory(Bitstream * bs)
{
int i;
for (i = 0; i < 12; i++)
{
if (BitstreamShowBits(bs, sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code)
{
BitstreamSkip(bs, sprite_trajectory_len[i].len);
return i;
}
}
return -1;
}
int check_resync_marker(Bitstream * bs, int addbits)
{
uint32_t nbits;
uint32_t code;
uint32_t nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits;
nbits = BitstreamNumBitsToByteAlign(bs);
code = BitstreamShowBits(bs, nbits);
if (code == (((uint32_t)1 << (nbits - 1)) - 1))
{
return BitstreamShowBitsFromByteAlign(bs, nbitsresyncmarker) == RESYNC_MARKER;
}
return 0;
}
uint32_t get_dc_scaler(uint32_t quant,
uint32_t lum)
{
if (quant < 5)
return 8;
if (quant < 25 && !lum)
return (quant + 13) / 2;
if (quant < 9)
return 2 * quant;
if (quant < 25)
return quant + 8;
if (lum)
return 2 * quant - 16;
else
return quant - 6;
}
uint32_t quant_h263_intra(int16_t * coeff,
const int16_t * data,
const uint32_t quant,
const uint32_t dcscalar,
const uint16_t * mpeg_quant_matrices)
{
const uint32_t mult = multipliers[quant];
const uint16_t quant_m_2 = quant << 1;
int i;
coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);
for (i = 1; i < 64; i++)
{
int16_t acLevel = data[i];
if (acLevel < 0)
{
acLevel = -acLevel;
if (acLevel < quant_m_2)
{
coeff[i] = 0;
continue;
}
acLevel = (acLevel * mult) >> SCALEBITS;
coeff[i] = -acLevel;
}
else
{
if (acLevel < quant_m_2)
{
coeff[i] = 0;
continue;
}
acLevel = (acLevel * mult) >> SCALEBITS;
coeff[i] = acLevel;
}
}
return(0);
}
int dequant_h263_intra(int16_t * data,
const int16_t * coeff,
const uint32_t quant,
const uint32_t dcscalar,
const uint16_t * mpeg_quant_matrices)
{
const int32_t quant_m_2 = quant << 1;
const int32_t quant_add = (quant & 1 ? quant : quant - 1);
int i;
data[0] = coeff[0] * dcscalar;
if (data[0] < -2048)
{
data[0] = -2048;
}
else
if(data[0] > 2047)
{
data[0] = 2047;
}
for (i = 1; i < 64; i++)
{
int32_t acLevel = coeff[i];
if (acLevel == 0)
{
data[i] = 0;
}
else
if (acLevel < 0)
{
acLevel = quant_m_2 * -acLevel + quant_add;
data[i] = (acLevel <= 2048 ? -acLevel : -2048);
}
else
{
acLevel = quant_m_2 * acLevel + quant_add;
data[i] = (acLevel <= 2047 ? acLevel : 2047);
}
}
return(0);
}
uint32_t quant_mpeg_intra(int16_t * coeff,
const int16_t * data,
const uint32_t quant,
const uint32_t dcscalar,
const uint16_t * mpeg_quant_matrices)
{
const uint32_t quantd = ((VM18P * quant) + (VM18Q / 2)) / VM18Q;
const uint32_t mult = multipliers[quant];
const uint16_t *intra_matrix = get_intra_matrix(mpeg_quant_matrices);
int i;
coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);
for (i = 1; i < 64; i++)
{
if (data[i] < 0)
{
uint32_t level = -data[i];
level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
level = ((level + quantd) * mult) >> SCALEBITS;
coeff[i] = -(int16_t) level;
}
else
if (data[i] > 0)
{
uint32_t level = data[i];
level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
level = ((level + quantd) * mult) >> SCALEBITS;
coeff[i] = level;
}
else
{
coeff[i] = 0;
}
}
return(0);
}
/* quantize inter-block
*
* level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
* coeff[i] = (level + quantd) / quant2;
* sum += abs(level);
*/
uint32_t quant_mpeg_inter(int16_t * coeff,
const int16_t * data,
const uint32_t quant,
const uint16_t * mpeg_quant_matrices)
{
const uint32_t mult = multipliers[quant];
const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
uint32_t sum = 0;
int i;
for (i = 0; i < 64; i++)
{
if (data[i] < 0)
{
uint32_t level = -data[i];
level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
level = (level * mult) >> 17;
sum += level;
coeff[i] = -(int16_t) level;
}
else
if (data[i] > 0)
{
uint32_t level = data[i];
level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
level = (level * mult) >> 17;
sum += level;
coeff[i] = level;
}
else
{
coeff[i] = 0;
}
}
return(sum);
}
/* dequantize intra-block & clamp to [-2048,2047]
*
* data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4;
*/
uint32_t dequant_mpeg_intra(int16_t * data,
const int16_t * coeff,
const uint32_t quant,
const uint32_t dcscalar,
const uint16_t * mpeg_quant_matrices)
{
const uint16_t *intra_matrix = get_intra_matrix(mpeg_quant_matrices);
int i;
data[0] = coeff[0] * dcscalar;
if (data[0] < -2048)
{
data[0] = -2048;
}
else
if(data[0] > 2047)
{
data[0] = 2047;
}
for (i = 1; i < 64; i++)
{
if (coeff[i] == 0)
{
data[i] = 0;
}
else
if(coeff[i] < 0)
{
uint32_t level = -coeff[i];
level = (level * intra_matrix[i] * quant) >> 3;
data[i] = (level <= 2048 ? -(int16_t) level : -2048);
}
else
{
uint32_t level = coeff[i];
level = (level * intra_matrix[i] * quant) >> 3;
data[i] = (level <= 2047 ? level : 2047);
}
}
return(0);
}
/* dequantize inter-block & clamp to [-2048,2047]
* data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16
*/
uint32_t dequant_mpeg_inter(int16_t * data,
const int16_t * coeff,
const uint32_t quant,
const uint16_t * mpeg_quant_matrices)
{
uint32_t sum = 0;
const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
int i;
for (i = 0; i < 64; i++)
{
if (coeff[i] == 0)
{
data[i] = 0;
}
else
if (coeff[i] < 0)
{
int32_t level = -coeff[i];
level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
data[i] = (level <= 2048 ? -level : -2048);
}
else
{
uint32_t level = coeff[i];
level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
data[i] = (level <= 2047 ? level : 2047);
}
sum ^= data[i];
}
/* mismatch control */
if ((sum & 1) == 0)
{
data[63] ^= 1;
}
return(0);
}
void init_mpeg_matrix(uint16_t * mpeg_quant_matrices)
{
set_intra_matrix(mpeg_quant_matrices, default_intra_matrix);
set_inter_matrix(mpeg_quant_matrices, default_inter_matrix);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -