*/
//#define DEBUG
+#define DC_VLC_BITS 9
+#define CBPY_VLC_BITS 6
+#define INTER_INTRA_VLC_BITS 3
+#define V1_INTRA_CBPC_VLC_BITS 6
+#define V1_INTER_CBPC_VLC_BITS 6
+#define V2_INTRA_CBPC_VLC_BITS 3
+#define V2_MB_TYPE_VLC_BITS 7
+#define MV_VLC_BITS 9
+#define V2_MV_VLC_BITS 9
+#define TEX_VLC_BITS 9
+#define MB_NON_INTRA_VLC_BITS 9
+#define MB_INTRA_VLC_BITS 9
+
+#define II_BITRATE 128*1024
+#define MBAC_BITRATE 50*1024
+
static UINT32 v2_dc_lum_table[512][2];
static UINT32 v2_dc_chroma_table[512][2];
int *mx_ptr, int *my_ptr);
static void msmpeg4v2_encode_motion(MpegEncContext * s, int val);
static void init_h263_dc_for_msmpeg4(void);
-
+static inline void msmpeg4_memsetw(short *tab, int val, int n);
+static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra);
+static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
extern UINT32 inverse[256];
+
#ifdef DEBUG
int intra_count = 0;
int frame_count = 0;
#include "msmpeg4data.h"
+static UINT8 rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
+
#ifdef STATS
const char *st_names[ST_NB] = {
break;
}
+
if(s->msmpeg4_version==4){
- s->intra_scantable = wmv1_scantable[1];
- s->intra_h_scantable= wmv1_scantable[2];
- s->intra_v_scantable= wmv1_scantable[3];
- s->inter_scantable = wmv1_scantable[0];
- }else{
- s->intra_scantable = zigzag_direct;
- s->intra_h_scantable= ff_alternate_horizontal_scan;
- s->intra_v_scantable= ff_alternate_vertical_scan;
- s->inter_scantable = zigzag_direct;
+ ff_init_scantable(s, &s->intra_scantable , wmv1_scantable[1]);
+ ff_init_scantable(s, &s->intra_h_scantable, wmv1_scantable[2]);
+ ff_init_scantable(s, &s->intra_v_scantable, wmv1_scantable[3]);
+ ff_init_scantable(s, &s->inter_scantable , wmv1_scantable[0]);
}
+ //Note the default tables are set in common_init in mpegvideo.c
if(!inited){
- int i;
inited=1;
init_h263_dc_for_msmpeg4();
-
- /* permute for IDCT */
- for(i=0; i<WMV1_SCANTABLE_COUNT; i++){
- int k;
- for(k=0;k<64;k++) {
- int j = wmv1_scantable[i][k];
- wmv1_scantable[i][k]= block_permute_op(j);
- }
- }
-
}
}
init_mv_table(&mv_tables[1]);
for(i=0;i<NB_RL_TABLES;i++)
init_rl(&rl_table[i]);
+
+ for(i=0; i<NB_RL_TABLES; i++){
+ int level;
+ for(level=0; level<=MAX_LEVEL; level++){
+ int run;
+ for(run=0; run<=MAX_RUN; run++){
+ int last;
+ for(last=0; last<2; last++){
+ rl_length[i][level][run][last]= get_size_of_code(s, &rl_table[ i], last, run, level, 0);
+ }
+ }
+ }
+ }
}
}
int i;
int best =-1, best_size =9999999;
int chroma_best=-1, best_chroma_size=9999999;
- int last_size=0;
-
+
for(i=0; i<3; i++){
int level;
int chroma_size=0;
int run;
for(run=0; run<=MAX_RUN; run++){
int last;
+ const int last_size= size + chroma_size;
for(last=0; last<2; last++){
int inter_count = s->ac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last];
int intra_luma_count = s->ac_stats[1][0][level][run][last];
int intra_chroma_count= s->ac_stats[1][1][level][run][last];
-
+
if(s->pict_type==I_TYPE){
- size += intra_luma_count *get_size_of_code(s, &rl_table[ i], last, run, level,1);
- chroma_size+= intra_chroma_count*get_size_of_code(s, &rl_table[3+i], last, run, level,1);
+ size += intra_luma_count *rl_length[i ][level][run][last];
+ chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last];
}else{
- size+= intra_luma_count *get_size_of_code(s, &rl_table[ i], last, run, level,1)
- +intra_chroma_count*get_size_of_code(s, &rl_table[3+i], last, run, level,1)
- +inter_count *get_size_of_code(s, &rl_table[3+i], last, run, level,0);
+ size+= intra_luma_count *rl_length[i ][level][run][last]
+ +intra_chroma_count*rl_length[i+3][level][run][last]
+ +inter_count *rl_length[i+3][level][run][last];
}
}
+ if(last_size == size+chroma_size) break;
}
}
if(size<best_size){
chroma_best= i;
}
}
+
// printf("type:%d, best:%d, qp:%d, var:%d, mcvar:%d, size:%d //\n",
// s->pict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size);
s->mv_table_index = 1; /* only if P frame */
s->use_skip_mb_code = 1; /* only if P frame */
s->per_mb_rl_table = 0;
+ if(s->msmpeg4_version==4)
+ s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==P_TYPE);
if (s->pict_type == I_TYPE) {
s->no_rounding = 1;
- put_bits(&s->pb, 5, 0x17); /* indicate only one "slice" */
+ s->slice_height= s->mb_height/1;
+ put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height);
if(s->msmpeg4_version==4){
msmpeg4_encode_ext_header(s);
- put_bits(&s->pb, 1, s->per_mb_rl_table);
+ if(s->bit_rate>MBAC_BITRATE)
+ put_bits(&s->pb, 1, s->per_mb_rl_table);
}
if(s->msmpeg4_version>2){
} else {
put_bits(&s->pb, 1, s->use_skip_mb_code);
- if(s->msmpeg4_version==4)
+ if(s->msmpeg4_version==4 && s->bit_rate>MBAC_BITRATE)
put_bits(&s->pb, 1, s->per_mb_rl_table);
if(s->msmpeg4_version>2){
{
put_bits(&s->pb, 5, s->frame_rate / FRAME_RATE_BASE); //yes 29.97 -> 29
- put_bits(&s->pb, 11, MIN(s->bit_rate, 2047));
+ put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047));
if(s->msmpeg4_version<3)
s->flipflop_rounding=0;
}
}
+static inline void handle_slices(MpegEncContext *s){
+ if (s->mb_x == 0) {
+ if (s->slice_height && (s->mb_y % s->slice_height) == 0) {
+ if(s->msmpeg4_version != 4){
+ ff_mpeg4_clean_buffers(s);
+ }
+ s->first_slice_line = 1;
+ } else {
+ s->first_slice_line = 0;
+ }
+ }
+}
+
void msmpeg4_encode_mb(MpegEncContext * s,
DCTELEM block[6][64],
int motion_x, int motion_y)
int pred_x, pred_y;
UINT8 *coded_block;
+ handle_slices(s);
+
if (!s->mb_intra) {
/* compute cbp */
set_stat(ST_INTER_MB);
}
set_stat(ST_INTRA_MB);
put_bits(&s->pb, 1, 0); /* no AC prediction yet */
+ if(s->inter_intra_pred){
+ s->h263_aic_dir=0;
+ put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]);
+ }
}
}
return s->last_dc[i];
}
+static int get_dc(uint8_t *src, int stride, int scale)
+{
+ int y;
+ int sum=0;
+ for(y=0; y<8; y++){
+ int x;
+ for(x=0; x<8; x++){
+ sum+=src[x + y*stride];
+ }
+ }
+ return (sum + (scale>>1))/scale;
+}
+
/* dir = 0: left, dir = 1: top prediction */
static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
UINT16 **dc_val_ptr, int *dir_ptr)
a = dc_val[ - 1];
b = dc_val[ - 1 - wrap];
c = dc_val[ - wrap];
+
+ if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version!=4){
+ b=c=1024;
+ }
/* XXX: the following solution consumes divisions, but it does not
necessitate to modify mpegvideo.c. The problem comes from the
/* XXX: WARNING: they did not choose the same test as MPEG4. This
is very important ! */
if(s->msmpeg4_version>3){
- if (abs(a - b) < abs(b - c)) {
- pred = c;
- *dir_ptr = 1;
- } else {
- pred = a;
- *dir_ptr = 0;
+ if(s->inter_intra_pred){
+ uint8_t *dest;
+ int wrap;
+
+ if(n==1){
+ pred=a;
+ *dir_ptr = 0;
+ }else if(n==2){
+ pred=c;
+ *dir_ptr = 1;
+ }else if(n==3){
+ if (abs(a - b) < abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1;
+ } else {
+ pred = a;
+ *dir_ptr = 0;
+ }
+ }else{
+ if(n<4){
+ wrap= s->linesize;
+ dest= s->current_picture[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8;
+ }else{
+ wrap= s->uvlinesize;
+ dest= s->current_picture[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
+ }
+ if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
+ else a= get_dc(dest-8, wrap, scale*8);
+ if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
+ else c= get_dc(dest-8*wrap, wrap, scale*8);
+
+ if (s->h263_aic_dir==0) {
+ pred= a;
+ *dir_ptr = 0;
+ }else if (s->h263_aic_dir==1) {
+ if(n==0){
+ pred= c;
+ *dir_ptr = 1;
+ }else{
+ pred= a;
+ *dir_ptr = 0;
+ }
+ }else if (s->h263_aic_dir==2) {
+ if(n==0){
+ pred= a;
+ *dir_ptr = 0;
+ }else{
+ pred= c;
+ *dir_ptr = 1;
+ }
+ } else {
+ pred= c;
+ *dir_ptr = 1;
+ }
+ }
+ }else{
+ if (abs(a - b) < abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1;
+ } else {
+ pred = a;
+ *dir_ptr = 0;
+ }
}
}else{
if (abs(a - b) <= abs(b - c)) {
rl = &rl_table[3 + s->rl_chroma_table_index];
}
run_diff = 0;
- scantable= s->intra_scantable;
+ scantable= s->intra_scantable.permutated;
set_stat(ST_INTRA_AC);
} else {
i = 0;
run_diff = 0;
else
run_diff = 1;
- scantable= s->inter_scantable;
+ scantable= s->inter_scantable.permutated;
set_stat(ST_INTER_AC);
}
/* recalculate block_last_index for M$ wmv1 */
- if(scantable!=zigzag_direct && s->block_last_index[n]>0){
+ if(s->msmpeg4_version==4 && 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 */
sign = 1;
level = -level;
}
+
if(level<=MAX_LEVEL && run<=MAX_RUN){
s->ac_stats[s->mb_intra][n>3][level][run][last]++;
}
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 its inverted */
static void init_h263_dc_for_msmpeg4(void)
}
for(i=0;i<2;i++) {
mv = &mv_tables[i];
- init_vlc(&mv->vlc, 9, mv->n + 1,
+ init_vlc(&mv->vlc, MV_VLC_BITS, mv->n + 1,
mv->table_mv_bits, 1, 1,
mv->table_mv_code, 2, 2);
}
- init_vlc(&dc_lum_vlc[0], 9, 120,
+ init_vlc(&dc_lum_vlc[0], DC_VLC_BITS, 120,
&table0_dc_lum[0][1], 8, 4,
&table0_dc_lum[0][0], 8, 4);
- init_vlc(&dc_chroma_vlc[0], 9, 120,
+ init_vlc(&dc_chroma_vlc[0], DC_VLC_BITS, 120,
&table0_dc_chroma[0][1], 8, 4,
&table0_dc_chroma[0][0], 8, 4);
- init_vlc(&dc_lum_vlc[1], 9, 120,
+ init_vlc(&dc_lum_vlc[1], DC_VLC_BITS, 120,
&table1_dc_lum[0][1], 8, 4,
&table1_dc_lum[0][0], 8, 4);
- init_vlc(&dc_chroma_vlc[1], 9, 120,
+ init_vlc(&dc_chroma_vlc[1], DC_VLC_BITS, 120,
&table1_dc_chroma[0][1], 8, 4,
&table1_dc_chroma[0][0], 8, 4);
- init_vlc(&v2_dc_lum_vlc, 9, 512,
+ 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);
- init_vlc(&v2_dc_chroma_vlc, 9, 512,
+ 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);
- init_vlc(&cbpy_vlc, 6, 16,
+ init_vlc(&cbpy_vlc, CBPY_VLC_BITS, 16,
&cbpy_tab[0][1], 2, 1,
&cbpy_tab[0][0], 2, 1);
- init_vlc(&v2_intra_cbpc_vlc, 3, 4,
+ 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);
- init_vlc(&v2_mb_type_vlc, 5, 8,
+ 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);
- init_vlc(&v2_mv_vlc, 9, 33,
+ init_vlc(&v2_mv_vlc, V2_MV_VLC_BITS, 33,
&mvtab[0][1], 2, 1,
&mvtab[0][0], 2, 1);
- init_vlc(&mb_non_intra_vlc, 9, 128,
+ init_vlc(&mb_non_intra_vlc, MB_NON_INTRA_VLC_BITS, 128,
&table_mb_non_intra[0][1], 8, 4,
&table_mb_non_intra[0][0], 8, 4);
- init_vlc(&mb_intra_vlc, 9, 64,
+ init_vlc(&mb_intra_vlc, MB_INTRA_VLC_BITS, 64,
&table_mb_intra[0][1], 4, 2,
&table_mb_intra[0][0], 4, 2);
- init_vlc(&v1_intra_cbpc_vlc, 6, 8,
+ init_vlc(&v1_intra_cbpc_vlc, V1_INTRA_CBPC_VLC_BITS, 8,
intra_MCBPC_bits, 1, 1,
intra_MCBPC_code, 1, 1);
- init_vlc(&v1_inter_cbpc_vlc, 6, 25,
+ init_vlc(&v1_inter_cbpc_vlc, V1_INTER_CBPC_VLC_BITS, 25,
inter_MCBPC_bits, 1, 1,
inter_MCBPC_code, 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);
+ }
+
+ 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;
}
+
+ s->slice_height= s->mb_height; //to avoid 1/0 if the first frame isnt a keyframe
+
return 0;
}
fprintf(stderr, "invalid picture type\n");
return -1;
}
-
+#if 0
+{
+ static int had_i=0;
+ if(s->pict_type == I_TYPE) had_i=1;
+ if(!had_i) return -1;
+}
+#endif
s->qscale = get_bits(&s->gb, 5);
if (s->pict_type == I_TYPE) {
s->slice_height = code;
}else{
/* 0x17: one slice, 0x18: two slices, ... */
- if (code < 0x17)
+ if (code < 0x17){
+ fprintf(stderr, "error, slice code was %X\n", code);
return -1;
+ }
s->slice_height = s->mb_height / (code - 0x16);
}
case 4:
msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
- s->per_mb_rl_table= get_bits1(&s->gb);
+ if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
+ else s->per_mb_rl_table= 0;
+
if(!s->per_mb_rl_table){
s->rl_chroma_table_index = decode012(&s->gb);
s->rl_table_index = decode012(&s->gb);
}
s->dc_table_index = get_bits1(&s->gb);
+ s->inter_intra_pred= 0;
break;
}
s->no_rounding = 1;
-/* printf(" %d %d %d %d %d \n",
+/* printf("qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n",
s->qscale,
s->rl_chroma_table_index,
s->rl_table_index,
s->dc_table_index,
- s->per_mb_rl_table);*/
+ s->per_mb_rl_table,
+ s->slice_height);*/
} else {
-
switch(s->msmpeg4_version){
case 1:
case 2:
break;
case 4:
s->use_skip_mb_code = get_bits1(&s->gb);
- s->per_mb_rl_table= get_bits1(&s->gb);
+
+ if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
+ else s->per_mb_rl_table= 0;
+
if(!s->per_mb_rl_table){
s->rl_table_index = decode012(&s->gb);
s->rl_chroma_table_index = s->rl_table_index;
s->dc_table_index = get_bits1(&s->gb);
s->mv_table_index = get_bits1(&s->gb);
+ s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
break;
}
-/* printf(" %d %d %d %d %d %d \n",
+/* printf("skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n",
s->use_skip_mb_code,
s->rl_table_index,
s->rl_chroma_table_index,
s->dc_table_index,
s->mv_table_index,
- s->per_mb_rl_table);*/
+ s->per_mb_rl_table,
+ s->qscale);*/
if(s->flipflop_rounding){
s->no_rounding ^= 1;
}else{
int fps;
fps= get_bits(&s->gb, 5);
- s->bit_rate= get_bits(&s->gb, 11);
+ s->bit_rate= get_bits(&s->gb, 11)*1024;
if(s->msmpeg4_version>=3)
s->flipflop_rounding= get_bits1(&s->gb);
else
s->flipflop_rounding= 0;
-// printf("fps:%2d bps:%2d roundingType:%1d\n", fps, s->bit_rate, s->flipflop_rounding);
+// printf("fps:%2d bps:%2d roundingType:%1d\n", fps, s->bit_rate/1024, s->flipflop_rounding);
}
else if(left<length+8)
{
{
int code, val, sign, shift;
- code = get_vlc(&s->gb, &v2_mv_vlc);
+ code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2);
// printf("MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred);
if (code < 0)
return 0xffff;
return val;
}
-
-static int msmpeg4v12_decode_mb(MpegEncContext *s,
- DCTELEM block[6][64])
+static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
{
int cbp, code, i;
+
+ s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
+
if (s->pict_type == P_TYPE) {
if (s->use_skip_mb_code) {
if (get_bits1(&s->gb)) {
}
if(s->msmpeg4_version==2)
- code = get_vlc(&s->gb, &v2_mb_type_vlc);
+ code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1);
else
- code = get_vlc(&s->gb, &v1_inter_cbpc_vlc);
+ code = get_vlc2(&s->gb, v1_inter_cbpc_vlc.table, V1_INTER_CBPC_VLC_BITS, 3);
if(code<0 || code>7){
fprintf(stderr, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y);
return -1;
} else {
s->mb_intra = 1;
if(s->msmpeg4_version==2)
- cbp= get_vlc(&s->gb, &v2_intra_cbpc_vlc);
+ cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1);
else
- cbp= get_vlc(&s->gb, &v1_intra_cbpc_vlc);
+ cbp= get_vlc2(&s->gb, v1_intra_cbpc_vlc.table, V1_INTRA_CBPC_VLC_BITS, 1);
if(cbp<0 || cbp>3){
fprintf(stderr, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
return -1;
if (!s->mb_intra) {
int mx, my, cbpy;
- cbpy= get_vlc(&s->gb, &cbpy_vlc);
+ cbpy= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(cbpy<0){
fprintf(stderr, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
return -1;
} else {
if(s->msmpeg4_version==2){
s->ac_pred = get_bits1(&s->gb);
- cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2; //FIXME check errors
+ cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
} else{
s->ac_pred = 0;
- cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2; //FIXME check errors
+ cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
if(s->pict_type==P_TYPE) cbp^=0x3C;
}
}
return 0;
}
-int msmpeg4_decode_mb(MpegEncContext *s,
- DCTELEM block[6][64])
+static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
{
int cbp, code, i;
UINT8 *coded_val;
if(s->mb_y==0) printf("\n");
}
#endif
- /* special slice handling */
- if (s->mb_x == 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;
- msmpeg4_memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap],
- 1024, 2 * s->mb_width);
- wrap = s->mb_width + 2;
- msmpeg4_memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap],
- 1024, s->mb_width);
- msmpeg4_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;
- msmpeg4_memsetw(s->ac_val[0][0] + (1 + (2 * s->mb_y) * wrap)*16,
- 0, 2 * s->mb_width*16);
- wrap = s->mb_width + 2;
- msmpeg4_memsetw(s->ac_val[1][0] + (1 + (s->mb_y) * wrap)*16,
- 0, s->mb_width*16);
- msmpeg4_memsetw(s->ac_val[2][0] + (1 + (s->mb_y) * wrap)*16,
- 0, s->mb_width*16);
- s->first_slice_line = 1;
- } else {
- s->first_slice_line = 0;
- }
- }
-
- if(s->msmpeg4_version<=2) return msmpeg4v12_decode_mb(s, block); //FIXME export function & call from outside perhaps
+ s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
if (s->pict_type == P_TYPE) {
set_stat(ST_INTER_MB);
}
}
- code = get_vlc(&s->gb, &mb_non_intra_vlc);
+ code = get_vlc2(&s->gb, mb_non_intra_vlc.table, MB_NON_INTRA_VLC_BITS, 3);
if (code < 0)
return -1;
//s->mb_intra = (code & 0x40) ? 0 : 1;
} else {
set_stat(ST_INTRA_MB);
s->mb_intra = 1;
- code = get_vlc(&s->gb, &mb_intra_vlc);
+ code = get_vlc2(&s->gb, mb_intra_vlc.table, MB_INTRA_VLC_BITS, 2);
if (code < 0)
return -1;
/* predict coded block pattern */
#ifdef PRINT_MB
printf("%c", s->ac_pred ? 'A' : 'I');
#endif
+ if(s->inter_intra_pred){
+ s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
+// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
+ }
if(s->per_mb_rl_table && cbp){
s->rl_table_index = decode012(&s->gb);
s->rl_chroma_table_index = s->rl_table_index;
return 0;
}
-
+//#define ERROR_DETAILS
static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
int n, int coded)
{
- int code, level, i, j, last, run, run_diff;
+ int level, i, last, run, run_diff;
int dc_pred_dir;
RLTable *rl;
+ RL_VLC_ELEM *rl_vlc;
const UINT8 *scan_table;
int qmul, qadd;
#endif
if (level < 0){
fprintf(stderr, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
- return -1;
+ if(s->inter_intra_pred) level=0;
+ else return -1;
}
if (n < 4) {
rl = &rl_table[s->rl_table_index];
if(level > 256*s->y_dc_scale){
fprintf(stderr, "dc overflow+ L qscale: %d//\n", s->qscale);
- return -1;
+ if(!s->inter_intra_pred) return -1;
}
} else {
rl = &rl_table[3 + s->rl_chroma_table_index];
if(level > 256*s->c_dc_scale){
fprintf(stderr, "dc overflow+ C qscale: %d//\n", s->qscale);
- return -1;
+ if(!s->inter_intra_pred) return -1;
}
}
block[0] = level;
run_diff = 0;
- i = 1;
+ i = 0;
if (!coded) {
goto not_coded;
}
if (s->ac_pred) {
if (dc_pred_dir == 0)
- scan_table = s->intra_v_scantable; /* left */
+ scan_table = s->intra_v_scantable.permutated; /* left */
else
- scan_table = s->intra_h_scantable; /* top */
+ scan_table = s->intra_h_scantable.permutated; /* top */
} else {
- scan_table = s->intra_scantable;
+ scan_table = s->intra_scantable.permutated;
}
set_stat(ST_INTRA_AC);
+ rl_vlc= rl->rl_vlc[0];
} else {
qmul = s->qscale << 1;
qadd = (s->qscale - 1) | 1;
- i = 0;
+ i = -1;
rl = &rl_table[3 + s->rl_table_index];
if(s->msmpeg4_version==2)
run_diff = 1;
if (!coded) {
- s->block_last_index[n] = i - 1;
+ s->block_last_index[n] = i;
return 0;
}
- scan_table = s->inter_scantable;
+ scan_table = s->inter_scantable.permutated;
set_stat(ST_INTER_AC);
+ rl_vlc= rl->rl_vlc[s->qscale];
}
-
+ {
+ OPEN_READER(re, &s->gb);
for(;;) {
- code = get_vlc(&s->gb, &rl->vlc);
- if (code < 0){
- fprintf(stderr, "illegal AC-VLC code at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- if (code == rl->n) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+ if (level==0) {
+ int cache;
+ cache= GET_CACHE(re, &s->gb);
/* escape */
- if (s->msmpeg4_version==1 || get_bits1(&s->gb) == 0) {
- if (s->msmpeg4_version==1 || get_bits1(&s->gb) == 0) {
+ if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {
+ if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {
/* third escape */
+ if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);
+ UPDATE_CACHE(re, &s->gb);
if(s->msmpeg4_version<=3){
- last= get_bits1(&s->gb);
- run= get_bits(&s->gb, 6);
- level= get_bits(&s->gb, 8);
- level= ((int8_t)level);
- }else{
+ last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
+ run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
+ level= SHOW_SBITS(re, &s->gb, 8); LAST_SKIP_CACHE(re, &s->gb, 8);
+ SKIP_COUNTER(re, &s->gb, 1+6+8);
+ }else{
int sign;
- last= get_bits1(&s->gb);
+ last= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
if(!s->esc3_level_length){
int ll;
//printf("ESC-3 %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y);
if(s->qscale<8){
- ll= get_bits(&s->gb, 3);
+ ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);
if(ll==0){
- if(get_bits1(&s->gb)) printf("cool a new vlc code ,contact the ffmpeg developers and upload the file\n");
+ if(SHOW_UBITS(re, &s->gb, 1)) printf("cool a new vlc code ,contact the ffmpeg developers and upload the file\n");
+ SKIP_BITS(re, &s->gb, 1);
ll=8;
}
}else{
ll=2;
- while(ll<8 && get_bits1(&s->gb)==0) ll++;
+ while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){
+ ll++;
+ SKIP_BITS(re, &s->gb, 1);
+ }
+ if(ll<8) SKIP_BITS(re, &s->gb, 1);
}
s->esc3_level_length= ll;
- s->esc3_run_length= get_bits(&s->gb, 2) + 3;
+ s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
//printf("level length:%d, run length: %d\n", ll, s->esc3_run_length);
+ UPDATE_CACHE(re, &s->gb);
}
- run= get_bits(&s->gb, s->esc3_run_length);
- sign= get_bits1(&s->gb);
- level= get_bits(&s->gb, s->esc3_level_length);
+ run= SHOW_UBITS(re, &s->gb, s->esc3_run_length);
+ SKIP_BITS(re, &s->gb, s->esc3_run_length);
+
+ sign= SHOW_UBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+
+ level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);
+ SKIP_BITS(re, &s->gb, s->esc3_level_length);
if(sign) level= -level;
}
//printf("level: %d, run: %d at %d %d\n", level, run, s->mb_x, s->mb_y);
fprintf(stderr, "|level| overflow in 3. esc\n");
return DECODING_AC_LOST;
}
+#endif
+ i+= run + 1;
+ if(last) i+=192;
+#ifdef ERROR_DETAILS
+ if(run==66)
+ fprintf(stderr, "illegal vlc code in ESC3 level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ fprintf(stderr, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);
#endif
} else {
/* second escape */
- code = get_vlc(&s->gb, &rl->vlc);
- if (code < 0 || code >= rl->n){
- fprintf(stderr, "illegal ESC2-VLC code %d at %d %d\n", code, s->mb_x, s->mb_y);
- return -1;
- }
- run = rl->table_run[code];
- level = rl->table_level[code];
- last = code >= rl->last;
- run += rl->max_run[last][level] + run_diff;
- level= level * qmul + qadd;
- if (get_bits1(&s->gb))
- level = -level;
+#if MIN_CACHE_BITS < 23
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ UPDATE_CACHE(re, &s->gb);
+#else
+ SKIP_BITS(re, &s->gb, 2);
+#endif
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+ i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+ if(run==66)
+ fprintf(stderr, "illegal vlc code in ESC2 level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ fprintf(stderr, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);
+#endif
}
} else {
/* first escape */
- code = get_vlc(&s->gb, &rl->vlc);
- if (code < 0 || code >= rl->n){
- fprintf(stderr, "illegal ESC2-VLC code %d at %d %d\n", code, s->mb_x, s->mb_y);
- return -1;
- }
- run = rl->table_run[code];
- level = rl->table_level[code];
- last = code >= rl->last;
- level += rl->max_level[last][run];
- level= level * qmul + qadd;
- if (get_bits1(&s->gb))
- level = -level;
+#if MIN_CACHE_BITS < 22
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ UPDATE_CACHE(re, &s->gb);
+#else
+ SKIP_BITS(re, &s->gb, 1);
+#endif
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);
+ i+= run;
+ level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+ if(run==66)
+ fprintf(stderr, "illegal vlc code in ESC1 level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ fprintf(stderr, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);
+#endif
}
} else {
- run = rl->table_run[code];
- level = rl->table_level[code] * qmul + qadd;
- last = code >= rl->last;
- if (get_bits1(&s->gb))
- level = -level;
- }
- i += run;
- if (i >= 64){
- fprintf(stderr, "run too long at %d %d\n", s->mb_x, s->mb_y);
- return -1;
+ i+= run;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+ if(run==66)
+ fprintf(stderr, "illegal vlc code level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ fprintf(stderr, "run overflow i=%d run=%d level=%d\n", i, run, level);
+#endif
}
+ if (i > 62){
+ i-= 192;
+ if(i&(~63)){
+ const int left= s->gb.size*8 - get_bits_count(&s->gb);
+ if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<=1) && left>=0){
+ fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
+ break;
+ }else{
+ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ }
- j = scan_table[i];
- block[j] = level;
- i++;
- if (last)
+ block[scan_table[i]] = level;
break;
+ }
+
+ block[scan_table[i]] = level;
}
+ CLOSE_READER(re, &s->gb);
+ }
not_coded:
if (s->mb_intra) {
mpeg4_pred_ac(s, block, n, dc_pred_dir);
if (s->ac_pred) {
- i = 64; /* XXX: not optimal */
+ i = 63; /* XXX: not optimal */
}
}
- if(s->msmpeg4_version==4 && i>1) i=64; //FIXME/XXX optimize
- s->block_last_index[n] = i - 1;
+ if(s->msmpeg4_version==4 && i>0) i=63; //FIXME/XXX optimize
+ s->block_last_index[n] = i;
return 0;
}
if(s->msmpeg4_version<=2){
if (n < 4) {
- level = get_vlc(&s->gb, &v2_dc_lum_vlc);
+ level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3);
} else {
- level = get_vlc(&s->gb, &v2_dc_chroma_vlc);
+ level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3);
}
if (level < 0)
return -1;
level-=256;
}else{ //FIXME optimize use unified tables & index
if (n < 4) {
- level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
+ level = get_vlc2(&s->gb, dc_lum_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
} else {
- level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]);
+ level = get_vlc2(&s->gb, dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
}
if (level < 0){
fprintf(stderr, "illegal dc vlc\n");
mv = &mv_tables[s->mv_table_index];
- code = get_vlc(&s->gb, &mv->vlc);
+ code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2);
if (code < 0){
fprintf(stderr, "illegal MV code at %d %d\n", s->mb_x, s->mb_y);
return -1;