/* strongly inspirated from MPEG4, but not exactly the same ! */
void msmpeg4_dc_scale(MpegEncContext * s)
{
- int scale;
-
- if (s->qscale < 5)
- scale = 8;
- else if (s->qscale < 9)
- scale = 2 * s->qscale;
- else
- scale = s->qscale + 8;
- s->y_dc_scale = scale;
- s->c_dc_scale = (s->qscale + 13) / 2;
+ if (s->qscale < 5){
+ s->y_dc_scale = 8;
+ s->c_dc_scale = 8;
+// s->c_dc_scale = (s->qscale + 13)>>1;
+ }else if (s->qscale < 9){
+ s->y_dc_scale = 2 * s->qscale;
+ s->c_dc_scale = (s->qscale + 13)>>1;
+ }else{
+ s->y_dc_scale = s->qscale + 8;
+ s->c_dc_scale = (s->qscale + 13)>>1;
+ }
+ // this differs for quant >24 from mpeg4
+
+// if(s->qscale==13) s->c_dc_scale=14;
+
+// if(s->qscale>=6)
+// printf("%d", s->qscale);
+
+ /* s->c_dc_scale values (found by Michael Nidermayer)
+ qscale=2 -> 8 (yes iam sure about that)
+ qscale=3 -> 8
+ qscale=4 -> 8
+ qscale=5 -> 9
+ qscale=6 -> 9
+ qscale=7 -> 10
+ qscale=8 -> 10
+ qscale=9 -> 11
+ qscale=10-> 11
+ */
}
/* dir = 0: left, dir = 1: top prediction */
static int msmpeg4_pred_dc(MpegEncContext * s, int n,
- UINT16 **dc_val_ptr, int *dir_ptr)
+ INT16 **dc_val_ptr, int *dir_ptr)
{
int a, b, c, x, y, wrap, pred, scale;
- UINT16 *dc_val;
+ INT16 *dc_val;
/* find prediction */
if (n < 4) {
necessitate to modify mpegvideo.c. The problem comes from the
fact they decided to store the quantized DC (which would lead
to problems if Q could vary !) */
+#ifdef ARCH_X86
+ /* using 16bit divisions as they are large enough and 2x as fast */
+ asm volatile(
+ "movl %3, %%eax \n\t"
+ "shrl $1, %%eax \n\t"
+ "addl %%eax, %2 \n\t"
+ "addl %%eax, %1 \n\t"
+ "addl %0, %%eax \n\t"
+ "xorl %%edx, %%edx \n\t"
+ "divw %w3 \n\t"
+ "movzwl %%ax, %0 \n\t"
+ "movl %1, %%eax \n\t"
+ "xorl %%edx, %%edx \n\t"
+ "divw %w3 \n\t"
+ "movzwl %%ax, %1 \n\t"
+ "movl %2, %%eax \n\t"
+ "xorl %%edx, %%edx \n\t"
+ "divw %w3 \n\t"
+ "movzwl %%ax, %2 \n\t"
+ : "+r" (a), "+r" (b), "+r" (c)
+ : "r" (scale)
+ : "%eax", "%edx"
+ );
+#else
a = (a + (scale >> 1)) / scale;
b = (b + (scale >> 1)) / scale;
c = (c + (scale >> 1)) / scale;
-
+#endif
/* XXX: WARNING: they did not choose the same test as MPEG4. This
is very important ! */
if (abs(a - b) <= abs(b - c)) {
{
int sign, code;
int pred;
- UINT16 *dc_val;
+ INT16 *dc_val;
pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
init_vlc(&mb_non_intra_vlc, 9, 128,
&table_mb_non_intra[0][1], 8, 4,
&table_mb_non_intra[0][0], 8, 4);
- init_vlc(&mb_intra_vlc, 9, 128,
+ init_vlc(&mb_intra_vlc, 9, 64,
&table_mb_intra[0][1], 4, 2,
&table_mb_intra[0][0], 4, 2);
return 0;
static int decode012(GetBitContext *gb)
{
int n;
- n = get_bits(gb, 1);
+ n = get_bits1(gb);
if (n == 0)
return 0;
else
- return get_bits(gb, 1) + 1;
+ return get_bits1(gb) + 1;
}
int msmpeg4_decode_picture_header(MpegEncContext * s)
{
int code;
+static int weirdAl=0;
s->pict_type = get_bits(&s->gb, 2) + 1;
if (s->pict_type != I_TYPE &&
code = get_bits(&s->gb, 5);
/* 0x17: one slice, 0x18: three slices */
/* XXX: implement it */
+ //printf("%d %d %d\n", code, s->slice_height, s->first_slice_line);
if (code < 0x17)
return -1;
s->slice_height = s->mb_height / (code - 0x16);
s->rl_chroma_table_index = decode012(&s->gb);
s->rl_table_index = decode012(&s->gb);
- s->dc_table_index = get_bits(&s->gb, 1);
+ s->dc_table_index = get_bits1(&s->gb);
s->no_rounding = 1;
+/* printf(" %d %d %d %d \n",
+ s->qscale,
+ s->rl_chroma_table_index,
+ s->rl_table_index,
+ s->dc_table_index);*/
} else {
- s->use_skip_mb_code = get_bits(&s->gb, 1);
+ s->use_skip_mb_code = get_bits1(&s->gb);
s->rl_table_index = decode012(&s->gb);
s->rl_chroma_table_index = s->rl_table_index;
- s->dc_table_index = get_bits(&s->gb, 1);
+ s->dc_table_index = get_bits1(&s->gb);
- s->mv_table_index = get_bits(&s->gb, 1);
- s->no_rounding ^= 1;
+ s->mv_table_index = get_bits1(&s->gb);
+/* printf(" %d %d %d %d %d \n",
+ s->use_skip_mb_code,
+ s->rl_table_index,
+ s->rl_chroma_table_index,
+ s->dc_table_index,
+ s->mv_table_index);*/
+ if(weirdAl)
+ s->no_rounding = 0;
+ else
+ s->no_rounding ^= 1;
}
#ifdef DEBUG
printf("*****frame %d:\n", frame_count++);
/* special slice handling */
if (s->mb_x == 0) {
- if ((s->mb_y % s->slice_height) == 0) {
+ if (s->slice_height && (s->mb_y % s->slice_height) == 0) {
int wrap;
/* reset DC pred (set previous line to 1024) */
wrap = 2 * s->mb_width + 2;
1024, s->mb_width);
memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap],
1024, s->mb_width);
+
+ /* reset AC pred (set previous line to 0) */
+ wrap = s->mb_width * 2 + 2;
+ memsetw(s->ac_val[0][0] + (1 + (2 * s->mb_y) * wrap)*16,
+ 0, 2 * s->mb_width*16);
+ wrap = s->mb_width + 2;
+ memsetw(s->ac_val[1][0] + (1 + (s->mb_y) * wrap)*16,
+ 0, s->mb_width*16);
+ memsetw(s->ac_val[2][0] + (1 + (s->mb_y) * wrap)*16,
+ 0, s->mb_width*16);
s->first_slice_line = 1;
} else {
if (s->pict_type == P_TYPE) {
set_stat(ST_INTER_MB);
if (s->use_skip_mb_code) {
- if (get_bits(&s->gb, 1)) {
+ if (get_bits1(&s->gb)) {
/* skip mb */
s->mb_intra = 0;
for(i=0;i<6;i++)
s->mv[0][0][1] = my;
} else {
set_stat(ST_INTRA_MB);
- s->ac_pred = get_bits(&s->gb, 1);
+ s->ac_pred = get_bits1(&s->gb);
}
for (i = 0; i < 6; i++) {
int dc_pred_dir;
RLTable *rl;
const UINT8 *scan_table;
+ int qmul, qadd;
if (s->mb_intra) {
+ qmul=1;
+ qadd=0;
+
/* DC coef */
set_stat(ST_DC);
level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
} else {
rl = &rl_table[3 + s->rl_chroma_table_index];
}
+
run_diff = 0;
i = 1;
if (!coded) {
}
set_stat(ST_INTRA_AC);
} else {
+ qmul = s->qscale << 1;
+ qadd = (s->qscale - 1) | 1;
i = 0;
rl = &rl_table[3 + s->rl_table_index];
run_diff = 1;
return -1;
if (code == rl->n) {
/* escape */
- if (get_bits(&s->gb, 1) == 0) {
- if (get_bits(&s->gb, 1) == 0) {
+ if (get_bits1(&s->gb) == 0) {
+ if (get_bits1(&s->gb) == 0) {
/* third escape */
- last = get_bits(&s->gb, 1);
+ last = get_bits1(&s->gb);
run = get_bits(&s->gb, 6);
level = get_bits(&s->gb, 8);
level = (level << 24) >> 24; /* sign extend */
+ if(level>0) level= level * qmul + qadd;
+ else level= level * qmul - qadd;
} else {
/* second escape */
code = get_vlc(&s->gb, &rl->vlc);
level = rl->table_level[code];
last = code >= rl->last;
run += rl->max_run[last][level] + run_diff;
- if (get_bits(&s->gb, 1))
+ level= level * qmul + qadd;
+ if (get_bits1(&s->gb))
level = -level;
}
} else {
level = rl->table_level[code];
last = code >= rl->last;
level += rl->max_level[last][run];
- if (get_bits(&s->gb, 1))
+ level= level * qmul + qadd;
+ if (get_bits1(&s->gb))
level = -level;
}
} else {
run = rl->table_run[code];
- level = rl->table_level[code];
+ level = rl->table_level[code] * qmul + qadd;
last = code >= rl->last;
- if (get_bits(&s->gb, 1))
+ if (get_bits1(&s->gb))
level = -level;
}
i += run;
static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
{
int level, pred;
- UINT16 *dc_val;
+ INT16 *dc_val;
if (n < 4) {
level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
if (level == DC_MAX) {
level = get_bits(&s->gb, 8);
- if (get_bits(&s->gb, 1))
+ if (get_bits1(&s->gb))
level = -level;
} else if (level != 0) {
- if (get_bits(&s->gb, 1))
+ if (get_bits1(&s->gb))
level = -level;
}