📄 h263enc.c
字号:
if (run < 2 && level < 4) { \
len = coeff_tab2[run][level - 1][1]; \
code = coeff_tab2[run][level - 1][0]; \
} else if (run >= 2 && run < 42 && level == 1) { \
len = coeff_tab3[run - 2][1]; \
code = coeff_tab3[run - 2][0]; \
} \
} \
}
static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
{
int level, run, last, i, j, last_index, last_non_zero, sign, slevel;
int code = 0, len;
if (s->mb_intra) {
/* DC coef */
level = block[0];
if (level == 128)
put_bits(&s->pb, 8, 0xff);
else
put_bits(&s->pb, 8, level & 0xff);
i = 1;
} else {
i = 0;
}
/* AC coefs */
last_index = s->block_last_index[n];
last_non_zero = i - 1;
for (; i <= last_index; i++) {
j = zigzag_direct[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;
}
len = 0;
CODE_INTER(run, level, last);
if (len == 0) {
put_bits(&s->pb, 7, 3);
put_bits(&s->pb, 1, last);
put_bits(&s->pb, 6, run);
put_bits(&s->pb, 8, slevel & 0xff);
} else {
code = (code << 1) | sign;
put_bits(&s->pb, len + 1, code);
}
last_non_zero = i;
}
}
}
/* write RV 1.0 compatible frame header */
void rv10_encode_picture_header(MpegEncContext * s, int picture_number)
{
align_put_bits(&s->pb);
put_bits(&s->pb, 1, 1); /* marker */
put_bits(&s->pb, 1, (s->pict_type == P_TYPE));
put_bits(&s->pb, 1, 0); /* not PB frame */
put_bits(&s->pb, 5, s->qscale);
if (s->pict_type == I_TYPE) {
/* specific MPEG like DC coding not used */
}
/* if multiple packets per frame are sent, the position at which
to display the macro blocks is coded here */
put_bits(&s->pb, 6, 0); /* mb_x */
put_bits(&s->pb, 6, 0); /* mb_y */
put_bits(&s->pb, 12, s->mb_width * s->mb_height);
put_bits(&s->pb, 3, 0); /* ignored */
}
/***************************************************/
/* write mpeg4 VOP header */
void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
{
align_put_bits(&s->pb);
put_bits(&s->pb, 32, 0x1B6); /* vop header */
put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */
/* XXX: time base + 1 not always correct */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 1, 0);
put_bits(&s->pb, 1, 1); /* marker */
put_bits(&s->pb, 4, 1); /* XXX: correct time increment */
put_bits(&s->pb, 1, 1); /* marker */
put_bits(&s->pb, 1, 1); /* vop coded */
if (s->pict_type == P_TYPE)
put_bits(&s->pb, 1, 0); /* rounding type */
put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */
put_bits(&s->pb, 5, s->qscale);
if (s->pict_type != I_TYPE)
put_bits(&s->pb, 3, s->f_code); /* fcode_for */
}
void h263_dc_scale(MpegEncContext * s)
{
int quant;
quant = s->qscale;
/* luminance */
if (quant < 5)
s->y_dc_scale = 8;
else if (quant > 4 && quant < 9)
s->y_dc_scale = (2 * quant);
else if (quant > 8 && quant < 25)
s->y_dc_scale = (quant + 8);
else
s->y_dc_scale = (2 * quant - 16);
/* chrominance */
if (quant < 5)
s->c_dc_scale = 8;
else if (quant > 4 && quant < 25)
s->c_dc_scale = ((quant + 13) / 2);
else
s->c_dc_scale = (quant - 6);
}
static inline void mpeg4_encode_dc(MpegEncContext * s, int level, int n)
{
int size, v, a, b, c, x, y, wrap, pred, scale;
UINT16 *dc_val;
/* find prediction */
if (n < 4) {
x = 2 * s->mb_x + 1 + (n & 1);
y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
wrap = s->mb_width * 2 + 2;
dc_val = s->dc_val[0];
scale = s->y_dc_scale;
} else {
x = s->mb_x + 1;
y = s->mb_y + 1;
wrap = s->mb_width + 2;
dc_val = s->dc_val[n - 4 + 1];
scale = s->c_dc_scale;
}
/* B C
* A X
*/
a = dc_val[(x - 1) + (y) * wrap];
b = dc_val[(x - 1) + (y - 1) * wrap];
c = dc_val[(x) + (y - 1) * wrap];
if (abs(a - b) < abs(b - c)) {
pred = c;
} else {
pred = a;
}
/* we assume pred is positive */
pred = (pred + (scale >> 1)) / scale;
/* update predictor */
dc_val[(x) + (y) * wrap] = level * scale;
/* do the prediction */
level -= pred;
/* find number of bits */
size = 0;
v = abs(level);
while (v) {
v >>= 1;
size++;
}
if (n < 4) {
/* luminance */
put_bits(&s->pb, DCtab_lum[size][1], DCtab_lum[size][0]);
} else {
/* chrominance */
put_bits(&s->pb, DCtab_chrom[size][1], DCtab_chrom[size][0]);
}
/* encode remaining bits */
if (size > 0) {
if (level < 0)
level = (-level) ^ ((1 << size) - 1);
put_bits(&s->pb, size, level);
if (size > 8)
put_bits(&s->pb, 1, 1);
}
}
static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
{
int level, run, last, i, j, last_index, last_non_zero, sign, slevel, level1, run1;
int code = 0, len;
if (s->mb_intra) {
/* mpeg4 based DC predictor */
mpeg4_encode_dc(s, block[0], n);
i = 1;
} else {
i = 0;
}
/* AC coefs */
last_index = s->block_last_index[n];
last_non_zero = i - 1;
for (; i <= last_index; i++) {
j = zigzag_direct[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;
}
len = 0;
if (s->mb_intra) {
/* intra mb */
CODE_INTRA(run, level, last);
if (len)
goto esc0;
/* first escape */
level1 = level - intra_max_level[last][run];
assert(level1 >= 0);
if (level1 < 28) {
CODE_INTRA(run, level1, last);
if (len)
goto esc1;
}
/* second escape */
run1 = run - (intra_max_run[last][level]+1);
if (level < 28 && run1 >= 0) {
CODE_INTRA(run1, level, last);
if (len)
goto esc2;
}
} else {
/* inter mb */
CODE_INTER(run, level, last);
if (len)
goto esc0;
/* first escape */
level1 = level - inter_max_level[last][run];
assert(level1 >= 0);
if (level1 < 13) {
CODE_INTER(run, level1, last);
if (len)
goto esc1;
}
/* second escape */
run1 = run - (inter_max_run[last][level]+1);
if (level < 13 && run1 >= 0) {
CODE_INTER(run1, level, last);
if (len)
goto esc2;
}
}
/* third escape */
put_bits(&s->pb, 7, 3);
put_bits(&s->pb, 2, 3);
put_bits(&s->pb, 1, last);
put_bits(&s->pb, 6, run);
put_bits(&s->pb, 1, 1); /* marker */
put_bits(&s->pb, 12, slevel & 0xfff);
put_bits(&s->pb, 1, 1); /* marker */
goto next;
esc2:
put_bits(&s->pb, 7, 3);
put_bits(&s->pb, 2, 2);
goto esc0;
esc1:
put_bits(&s->pb, 7, 3);
put_bits(&s->pb, 1, 0);
esc0:
code = (code << 1) | sign;
put_bits(&s->pb, len + 1, code);
next:
last_non_zero = i;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -