/*
* MSMPEG4 backend for ffmpeg encoder and decoder
- * Copyright (c) 2001 Gerard Lantau.
+ * Copyright (c) 2001 Fabrice Bellard.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
+ */
+
+/**
+ * @file msmpeg4.c
+ * MSMPEG4 backend for ffmpeg encoder and decoder.
*/
+
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
*/
//#define DEBUG
-/* motion vector table */
-typedef struct MVTable {
- int n;
- const UINT16 *table_mv_code;
- const UINT8 *table_mv_bits;
- const UINT8 *table_mvx;
- const UINT8 *table_mvy;
- UINT16 *table_mv_index; /* encoding: convert mv to index in table_mv */
- VLC vlc; /* decoding: vlc */
-} MVTable;
-
-static UINT32 v2_dc_lum_table[512][2];
-static UINT32 v2_dc_chroma_table[512][2];
-
-static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
-static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
- int n, int coded);
+#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
+
+#define DEFAULT_INTER_INDEX 3
+
+static uint32_t v2_dc_lum_table[512][2];
+static uint32_t v2_dc_chroma_table[512][2];
+
+static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
+static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded, const uint8_t *scantable);
static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr);
static int msmpeg4_decode_motion(MpegEncContext * s,
int *mx_ptr, int *my_ptr);
static void msmpeg4v2_encode_motion(MpegEncContext * s, int val);
-static void init_h263_dc_for_msmpeg4();
-
+static void init_h263_dc_for_msmpeg4(void);
+static inline void msmpeg4_memsetw(short *tab, int val, int n);
+#ifdef CONFIG_ENCODERS
+static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra);
+#endif //CONFIG_ENCODERS
+static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
-extern UINT32 inverse[256];
#ifdef DEBUG
int intra_count = 0;
int frame_count = 0;
#endif
-/* XXX: move it to mpegvideo.h */
-
-static int init_done = 0;
#include "msmpeg4data.h"
+#ifdef CONFIG_ENCODERS //strangely gcc includes this even if its not references
+static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
+#endif //CONFIG_ENCODERS
+
#ifdef STATS
const char *st_names[ST_NB] = {
#endif
+static void common_init(MpegEncContext * s)
+{
+ static int inited=0;
+
+ switch(s->msmpeg4_version){
+ case 1:
+ case 2:
+ s->y_dc_scale_table=
+ s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
+ break;
+ case 3:
+ if(s->workaround_bugs){
+ s->y_dc_scale_table= old_ff_y_dc_scale_table;
+ s->c_dc_scale_table= old_ff_c_dc_scale_table;
+ } else{
+ s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
+ s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
+ }
+ break;
+ case 4:
+ case 5:
+ s->y_dc_scale_table= wmv1_y_dc_scale_table;
+ s->c_dc_scale_table= wmv1_c_dc_scale_table;
+ break;
+ }
+
+
+ if(s->msmpeg4_version>=4){
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , wmv1_scantable[1]);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, wmv1_scantable[2]);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, wmv1_scantable[3]);
+ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , wmv1_scantable[0]);
+ }
+ //Note the default tables are set in common_init in mpegvideo.c
+
+ if(!inited){
+ inited=1;
+
+ init_h263_dc_for_msmpeg4();
+ }
+}
+
+#ifdef CONFIG_ENCODERS
+
/* build the table which associate a (x,y) motion vector to a vlc */
static void init_mv_table(MVTable *tab)
{
int i, x, y;
- tab->table_mv_index = av_malloc(sizeof(UINT16) * 4096);
+ tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096);
/* mark all entries as not used */
for(i=0;i<4096;i++)
tab->table_mv_index[i] = tab->n;
}
}
-/* write MSMPEG4 V3 compatible frame header */
-void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
+void ff_msmpeg4_encode_init(MpegEncContext *s)
{
+ static int init_done=0;
int i;
- align_put_bits(&s->pb);
+ common_init(s);
+ if(s->msmpeg4_version>=4){
+ s->min_qcoeff= -255;
+ s->max_qcoeff= 255;
+ }
+
+ if (!init_done) {
+ /* init various encoding tables */
+ init_done = 1;
+ init_mv_table(&mv_tables[0]);
+ 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);
+ }
+ }
+ }
+ }
+ }
+}
+
+static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra){
+ int size=0;
+ int code;
+ int run_diff= intra ? 0 : 1;
+
+ code = get_rl_index(rl, last, run, level);
+ size+= rl->table_vlc[code][1];
+ if (code == rl->n) {
+ int level1, run1;
+
+ level1 = level - rl->max_level[last][run];
+ if (level1 < 1)
+ goto esc2;
+ code = get_rl_index(rl, last, run, level1);
+ if (code == rl->n) {
+ esc2:
+ size++;
+ if (level > MAX_LEVEL)
+ goto esc3;
+ run1 = run - rl->max_run[last][level] - run_diff;
+ if (run1 < 0)
+ goto esc3;
+ code = get_rl_index(rl, last, run1, level);
+ if (code == rl->n) {
+ esc3:
+ /* third escape */
+ size+=1+1+6+8;
+ } else {
+ /* second escape */
+ size+= 1+1+ rl->table_vlc[code][1];
+ }
+ } else {
+ /* first escape */
+ size+= 1+1+ rl->table_vlc[code][1];
+ }
+ } else {
+ size++;
+ }
+ return size;
+}
+
+static void find_best_tables(MpegEncContext * s)
+{
+ int i;
+ int best =-1, best_size =9999999;
+ int chroma_best=-1, best_chroma_size=9999999;
+
+ for(i=0; i<3; i++){
+ int level;
+ int chroma_size=0;
+ int size=0;
+
+ if(i>0){// ;)
+ size++;
+ chroma_size++;
+ }
+ for(level=0; level<=MAX_LEVEL; level++){
+ 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 *rl_length[i ][level][run][last];
+ chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last];
+ }else{
+ 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){
+ best_size= size;
+ best= i;
+ }
+ if(chroma_size<best_chroma_size){
+ best_chroma_size= chroma_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);
+
+ if(s->pict_type==P_TYPE) chroma_best= best;
+
+ memset(s->ac_stats, 0, sizeof(int)*(MAX_LEVEL+1)*(MAX_RUN+1)*2*2*2);
+ s->rl_table_index = best;
+ s->rl_chroma_table_index= chroma_best;
+
+ if(s->pict_type != s->last_non_b_pict_type){
+ s->rl_table_index= 2;
+ if(s->pict_type==I_TYPE)
+ s->rl_chroma_table_index= 1;
+ else
+ s->rl_chroma_table_index= 2;
+ }
+
+}
+
+/* write MSMPEG4 compatible frame header */
+void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
+{
+ find_best_tables(s);
+
+ align_put_bits(&s->pb);
put_bits(&s->pb, 2, s->pict_type - 1);
put_bits(&s->pb, 5, s->qscale);
-
- s->rl_table_index = 2;
- if(s->msmpeg4_version==2)
- s->rl_chroma_table_index = 2; /* only for I frame */
- else
- s->rl_chroma_table_index = 1; /* only for I frame */
+ if(s->msmpeg4_version<=2){
+ s->rl_table_index = 2;
+ s->rl_chroma_table_index = 2;
+ }
s->dc_table_index = 1;
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);
+//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height);
+
if (s->pict_type == I_TYPE) {
- 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);
+ if(s->bit_rate>MBAC_BITRATE)
+ put_bits(&s->pb, 1, s->per_mb_rl_table);
+ }
- if(s->msmpeg4_version!=2){
- code012(&s->pb, s->rl_chroma_table_index);
- code012(&s->pb, s->rl_table_index);
+ if(s->msmpeg4_version>2){
+ if(!s->per_mb_rl_table){
+ code012(&s->pb, s->rl_chroma_table_index);
+ code012(&s->pb, s->rl_table_index);
+ }
put_bits(&s->pb, 1, s->dc_table_index);
}
- s->no_rounding = 1;
} else {
put_bits(&s->pb, 1, s->use_skip_mb_code);
- s->rl_chroma_table_index = s->rl_table_index;
- if(s->msmpeg4_version!=2){
- code012(&s->pb, s->rl_table_index);
+ 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){
+ if(!s->per_mb_rl_table)
+ code012(&s->pb, s->rl_table_index);
put_bits(&s->pb, 1, s->dc_table_index);
put_bits(&s->pb, 1, s->mv_table_index);
}
-
- if(s->flipflop_rounding){
- s->no_rounding ^= 1;
- }else{
- s->no_rounding = 0;
- }
}
- if (!init_done) {
- /* init various encoding tables */
- init_done = 1;
- init_mv_table(&mv_tables[0]);
- init_mv_table(&mv_tables[1]);
- for(i=0;i<NB_RL_TABLES;i++)
- init_rl(&rl_table[i]);
-
- init_h263_dc_for_msmpeg4();
- }
+ s->esc3_level_length= 0;
+ s->esc3_run_length= 0;
#ifdef DEBUG
intra_count = 0;
void msmpeg4_encode_ext_header(MpegEncContext * s)
{
- s->flipflop_rounding=1;
- s->bitrate= 910; // FIXME
-
- put_bits(&s->pb, 5, s->frame_rate / FRAME_RATE_BASE); //yes 29.97 -> 29
+ put_bits(&s->pb, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29
- put_bits(&s->pb, 11, s->bitrate);
+ put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047));
- put_bits(&s->pb, 1, s->flipflop_rounding);
+ if(s->msmpeg4_version>=3)
+ put_bits(&s->pb, 1, s->flipflop_rounding);
+ else
+ assert(s->flipflop_rounding==0);
}
+#endif //CONFIG_ENCODERS
+
/* predict coded block */
-static inline int coded_block_pred(MpegEncContext * s, int n, UINT8 **coded_block_ptr)
+static inline int coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
{
int xy, wrap, pred, a, b, c;
return pred;
}
+#ifdef CONFIG_ENCODERS
+
static void msmpeg4_encode_motion(MpegEncContext * s,
int mx, int my)
{
}
}
+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 cbp, coded_cbp, i;
int pred_x, pred_y;
- UINT8 *coded_block;
+ uint8_t *coded_block;
+ handle_slices(s);
+
if (!s->mb_intra) {
/* compute cbp */
set_stat(ST_INTER_MB);
if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) {
/* skip macroblock */
put_bits(&s->pb, 1, 1);
+ s->last_bits++;
+ s->misc_bits++;
+ s->skip_count++;
+
return;
}
if (s->use_skip_mb_code)
put_bits(&s->pb, 1, 0); /* mb coded */
- if(s->msmpeg4_version==2){
+ if(s->msmpeg4_version<=2){
put_bits(&s->pb,
v2_mb_type[cbp&3][1],
v2_mb_type[cbp&3][0]);
put_bits(&s->pb,
cbpy_tab[coded_cbp>>2][1],
cbpy_tab[coded_cbp>>2][0]);
-
+
+ s->misc_bits += get_bits_diff(s);
+
h263_pred_motion(s, 0, &pred_x, &pred_y);
msmpeg4v2_encode_motion(s, motion_x - pred_x);
msmpeg4v2_encode_motion(s, motion_y - pred_y);
table_mb_non_intra[cbp + 64][1],
table_mb_non_intra[cbp + 64][0]);
+ s->misc_bits += get_bits_diff(s);
+
/* motion vector */
h263_pred_motion(s, 0, &pred_x, &pred_y);
msmpeg4_encode_motion(s, motion_x - pred_x,
motion_y - pred_y);
}
+
+ s->mv_bits += get_bits_diff(s);
+
+ for (i = 0; i < 6; i++) {
+ msmpeg4_encode_block(s, block[i], i);
+ }
+ s->p_tex_bits += get_bits_diff(s);
} else {
/* compute cbp */
cbp = 0;
printf("cbp=%x %x\n", cbp, coded_cbp);
#endif
- if(s->msmpeg4_version==2){
+ if(s->msmpeg4_version<=2){
if (s->pict_type == I_TYPE) {
put_bits(&s->pb,
v2_intra_cbpc[cbp&3][1], v2_intra_cbpc[cbp&3][0]);
}
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]);
+ }
}
- }
+ s->misc_bits += get_bits_diff(s);
- for (i = 0; i < 6; i++) {
- msmpeg4_encode_block(s, block[i], i);
+ for (i = 0; i < 6; i++) {
+ msmpeg4_encode_block(s, block[i], i);
+ }
+ s->i_tex_bits += get_bits_diff(s);
+ s->i_count++;
}
}
+#endif //CONFIG_ENCODERS
-#if 0
-/* identical to mpeg4 for msmpeg4v3 but not msmpeg4v2 */
-void msmpeg4_dc_scale(MpegEncContext * s)
+/* old ffmpeg msmpeg4v3 mode */
+static void ff_old_msmpeg4_dc_scale(MpegEncContext * s)
{
- if (s->qscale < 5 || s->msmpeg4_version==2){
+ if (s->qscale < 5){
s->y_dc_scale = 8;
s->c_dc_scale = 8;
}else if (s->qscale < 9){
s->y_dc_scale = 2 * s->qscale;
s->c_dc_scale = (s->qscale + 13)>>1;
- }else if(s->qscale < 25){
+ }else{
s->y_dc_scale = s->qscale + 8;
s->c_dc_scale = (s->qscale + 13)>>1;
- }else{
- s->y_dc_scale = 2 * s->qscale - 16;
- s->c_dc_scale = s->qscale - 6;
}
}
-#endif
+
+static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
+ int32_t **dc_val_ptr)
+{
+ int i;
+
+ if (n < 4) {
+ i= 0;
+ } else {
+ i= n-3;
+ }
+
+ *dc_val_ptr= &s->last_dc[i];
+ 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 FASTDIV((sum + (scale>>1)), scale);
+}
/* dir = 0: left, dir = 1: top prediction */
-static int msmpeg4_pred_dc(MpegEncContext * s, int n,
- INT16 **dc_val_ptr, int *dir_ptr)
+static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
+ uint16_t **dc_val_ptr, int *dir_ptr)
{
int a, b, c, wrap, pred, scale;
- INT16 *dc_val;
+ int16_t *dc_val;
/* find prediction */
if (n < 4) {
} else {
scale = s->c_dc_scale;
}
+
wrap = s->block_wrap[n];
dc_val= s->dc_val[0] + s->block_index[n];
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
b = (b + (8 >> 1)) / 8;
c = (c + (8 >> 1)) / 8;
} else {
- a = (a + (scale >> 1)) / scale;
- b = (b + (scale >> 1)) / scale;
- c = (c + (scale >> 1)) / scale;
+ a = FASTDIV((a + (scale >> 1)), scale);
+ b = FASTDIV((b + (scale >> 1)), scale);
+ c = FASTDIV((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)) {
- pred = c;
- *dir_ptr = 1;
- } else {
- pred = a;
- *dir_ptr = 0;
+ if(s->msmpeg4_version>3){
+ 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.data[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8;
+ }else{
+ wrap= s->uvlinesize;
+ dest= s->current_picture.data[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)) {
+ pred = c;
+ *dir_ptr = 1;
+ } else {
+ pred = a;
+ *dir_ptr = 0;
+ }
}
/* update predictor */
{
int sign, code;
int pred;
- INT16 *dc_val;
- pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+ if(s->msmpeg4_version==1){
+ int32_t *dc_val;
+ pred = msmpeg4v1_pred_dc(s, n, &dc_val);
+
+ /* update predictor */
+ *dc_val= level;
+ }else{
+ uint16_t *dc_val;
+ pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
- /* update predictor */
- if (n < 4) {
- *dc_val = level * s->y_dc_scale;
- } else {
- *dc_val = level * s->c_dc_scale;
+ /* update predictor */
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
}
/* do the prediction */
level -= pred;
- if(s->msmpeg4_version==2){
+ if(s->msmpeg4_version<=2){
if (n < 4) {
put_bits(&s->pb,
v2_dc_lum_table[level+256][1],
/* Encoding of a block. Very similar to MPEG4 except for a different
escape coding (same as H263) and more vlc tables.
*/
-static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
{
int level, run, last, i, j, last_index;
int last_non_zero, sign, slevel;
int code, run_diff, dc_pred_dir;
const RLTable *rl;
+ const uint8_t *scantable;
if (s->mb_intra) {
set_stat(ST_DC);
rl = &rl_table[3 + s->rl_chroma_table_index];
}
run_diff = 0;
+ scantable= s->intra_scantable.permutated;
set_stat(ST_INTRA_AC);
} else {
i = 0;
rl = &rl_table[3 + s->rl_table_index];
- if(s->msmpeg4_version==2)
+ if(s->msmpeg4_version<=2)
run_diff = 0;
else
run_diff = 1;
+ scantable= s->inter_scantable.permutated;
set_stat(ST_INTER_AC);
}
+ /* recalculate block_last_index for M$ wmv1 */
+ 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 */
- last_index = s->block_last_index[n];
last_non_zero = i - 1;
for (; i <= last_index; i++) {
- j = zigzag_direct[i];
+ j = scantable[i];
level = block[j];
if (level) {
run = i - last_non_zero - 1;
sign = 1;
level = -level;
}
+
+ if(level<=MAX_LEVEL && run<=MAX_RUN){
+ s->ac_stats[s->mb_intra][n>3][level][run][last]++;
+ }
+#if 0
+else
+ s->ac_stats[s->mb_intra][n>3][40][63][0]++; //esc3 like
+#endif
code = get_rl_index(rl, last, run, level);
put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
if (code == rl->n) {
/* third escape */
put_bits(&s->pb, 1, 0);
put_bits(&s->pb, 1, last);
- put_bits(&s->pb, 6, run);
- put_bits(&s->pb, 8, slevel & 0xff);
+ if(s->msmpeg4_version>=4){
+ if(s->esc3_level_length==0){
+ s->esc3_level_length=8;
+ s->esc3_run_length= 6;
+ if(s->qscale<8)
+ put_bits(&s->pb, 6, 3);
+ else
+ put_bits(&s->pb, 8, 3);
+ }
+ put_bits(&s->pb, s->esc3_run_length, run);
+ put_bits(&s->pb, 1, sign);
+ put_bits(&s->pb, s->esc3_level_length, level);
+ }else{
+ put_bits(&s->pb, 6, run);
+ put_bits(&s->pb, 8, slevel & 0xff);
+ }
} else {
/* second escape */
put_bits(&s->pb, 1, 1);
/****************************************/
/* decoding stuff */
-static VLC mb_non_intra_vlc;
+static VLC mb_non_intra_vlc[4];
static VLC mb_intra_vlc;
static VLC dc_lum_vlc[2];
static VLC dc_chroma_vlc[2];
static VLC v2_intra_cbpc_vlc;
static VLC v2_mb_type_vlc;
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()
+static void init_h263_dc_for_msmpeg4(void)
{
- static int inited=0;
-
- if(!inited){
int level, uni_code, uni_len;
- inited=1;
for(level=-256; level<256; level++){
int size, v, l;
v2_dc_chroma_table[level+256][1]= uni_len;
}
- }
}
/* init all vlc decoding tables */
-int msmpeg4_decode_init_vlc(MpegEncContext *s)
+int ff_msmpeg4_decode_init(MpegEncContext *s)
{
+ static int done = 0;
int i;
MVTable *mv;
- for(i=0;i<NB_RL_TABLES;i++) {
- init_rl(&rl_table[i]);
- init_vlc_rl(&rl_table[i]);
+ common_init(s);
+
+ if (!done) {
+ done = 1;
+
+ for(i=0;i<NB_RL_TABLES;i++) {
+ init_rl(&rl_table[i]);
+ init_vlc_rl(&rl_table[i]);
+ }
+ for(i=0;i<2;i++) {
+ mv = &mv_tables[i];
+ 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], DC_VLC_BITS, 120,
+ &table0_dc_lum[0][1], 8, 4,
+ &table0_dc_lum[0][0], 8, 4);
+ 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], DC_VLC_BITS, 120,
+ &table1_dc_lum[0][1], 8, 4,
+ &table1_dc_lum[0][0], 8, 4);
+ 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, 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, DC_VLC_BITS, 512,
+ &v2_dc_chroma_table[0][1], 8, 4,
+ &v2_dc_chroma_table[0][0], 8, 4);
+
+ 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, 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, 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, V2_MV_VLC_BITS, 33,
+ &mvtab[0][1], 2, 1,
+ &mvtab[0][0], 2, 1);
+
+ for(i=0; i<4; i++){
+ init_vlc(&mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128,
+ &wmv2_inter_table[i][0][1], 8, 4,
+ &wmv2_inter_table[i][0][0], 8, 4); //FIXME name?
+ }
+
+ 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, V1_INTRA_CBPC_VLC_BITS, 8,
+ intra_MCBPC_bits, 1, 1,
+ intra_MCBPC_code, 1, 1);
+ 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);
}
- for(i=0;i<2;i++) {
- mv = &mv_tables[i];
- init_vlc(&mv->vlc, 9, mv->n + 1,
- mv->table_mv_bits, 1, 1,
- mv->table_mv_code, 2, 2);
+
+ 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;
+ case 5:
+ s->decode_mb= wmv2_decode_mb;
+ break;
}
-
- init_vlc(&dc_lum_vlc[0], 9, 120,
- &table0_dc_lum[0][1], 8, 4,
- &table0_dc_lum[0][0], 8, 4);
- init_vlc(&dc_chroma_vlc[0], 9, 120,
- &table0_dc_chroma[0][1], 8, 4,
- &table0_dc_chroma[0][0], 8, 4);
- init_vlc(&dc_lum_vlc[1], 9, 120,
- &table1_dc_lum[0][1], 8, 4,
- &table1_dc_lum[0][0], 8, 4);
- init_vlc(&dc_chroma_vlc[1], 9, 120,
- &table1_dc_chroma[0][1], 8, 4,
- &table1_dc_chroma[0][0], 8, 4);
- init_h263_dc_for_msmpeg4();
- init_vlc(&v2_dc_lum_vlc, 9, 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,
- &v2_dc_chroma_table[0][1], 8, 4,
- &v2_dc_chroma_table[0][0], 8, 4);
+ s->slice_height= s->mb_height; //to avoid 1/0 if the first frame isnt a keyframe
- init_vlc(&cbpy_vlc, 6, 16,
- &cbpy_tab[0][1], 2, 1,
- &cbpy_tab[0][0], 2, 1);
- init_vlc(&v2_intra_cbpc_vlc, 3, 4,
- &v2_intra_cbpc[0][1], 2, 1,
- &v2_intra_cbpc[0][0], 2, 1);
- init_vlc(&v2_mb_type_vlc, 5, 8,
- &v2_mb_type[0][1], 2, 1,
- &v2_mb_type[0][0], 2, 1);
- init_vlc(&v2_mv_vlc, 9, 33,
- &mvtab[0][1], 2, 1,
- &mvtab[0][0], 2, 1);
-
- 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, 64,
- &table_mb_intra[0][1], 4, 2,
- &table_mb_intra[0][0], 4, 2);
return 0;
}
int msmpeg4_decode_picture_header(MpegEncContext * s)
{
- int code, code2;
+ int code;
#if 0
{
int i;
-for(i=0; i<s->gb.size*8; i++)
+for(i=0; i<s->gb.size_in_bits; i++)
printf("%d", get_bits1(&s->gb));
// get_bits1(&s->gb);
printf("END\n");
return -1;
}
#endif
+
+ if(s->msmpeg4_version==1){
+ int start_code, num;
+ start_code = (get_bits(&s->gb, 16)<<16) | get_bits(&s->gb, 16);
+ if(start_code!=0x00000100){
+ fprintf(stderr, "invalid startcode\n");
+ return -1;
+ }
+
+ num= get_bits(&s->gb, 5); // frame number */
+ }
+
s->pict_type = get_bits(&s->gb, 2) + 1;
if (s->pict_type != I_TYPE &&
- s->pict_type != P_TYPE)
+ s->pict_type != P_TYPE){
+ 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->qscale==0){
+ fprintf(stderr, "invalid qscale\n");
+ return -1;
+ }
if (s->pict_type == I_TYPE) {
code = get_bits(&s->gb, 5);
- /* 0x17: one slice, 0x18: two slices */
- if (code < 0x17)
- return -1;
- s->slice_height = s->mb_height / (code - 0x16);
+ if(s->msmpeg4_version==1){
+ if(code==0 || code>s->mb_height){
+ fprintf(stderr, "invalid slice height %d\n", code);
+ return -1;
+ }
+
+ s->slice_height = code;
+ }else{
+ /* 0x17: one slice, 0x18: two slices, ... */
+ if (code < 0x17){
+ fprintf(stderr, "error, slice code was %X\n", code);
+ return -1;
+ }
+
+ s->slice_height = s->mb_height / (code - 0x16);
+ }
switch(s->msmpeg4_version){
+ case 1:
case 2:
s->rl_chroma_table_index = 2;
s->rl_table_index = 2;
s->dc_table_index = get_bits1(&s->gb);
break;
case 4:
- msmpeg4_decode_ext_header(s, 999 /* bufer size (useless here) */);
- printf("%X\n", show_bits(&s->gb, 24));
- code= get_bits(&s->gb, 2);
- if(code==1){
- code2= get_bits(&s->gb, 3);
- if(code2==7) skip_bits(&s->gb, 1);
+ msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
+
+ 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);
}
- printf("%X\n", show_bits(&s->gb, 24));
- s->rl_chroma_table_index = 2;
- s->rl_table_index = 2;
- s->dc_table_index = 0;
+ s->dc_table_index = get_bits1(&s->gb);
+ s->inter_intra_pred= 0;
break;
}
s->no_rounding = 1;
-/* printf(" %d %d %d %d \n",
+ if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+ 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->dc_table_index,
+ s->per_mb_rl_table,
+ s->slice_height);
} else {
- s->use_skip_mb_code = get_bits1(&s->gb);
-
- if(s->msmpeg4_version==2){
+ switch(s->msmpeg4_version){
+ case 1:
+ case 2:
+ if(s->msmpeg4_version==1)
+ s->use_skip_mb_code = 1;
+ else
+ s->use_skip_mb_code = get_bits1(&s->gb);
s->rl_table_index = 2;
s->rl_chroma_table_index = s->rl_table_index;
-
s->dc_table_index = 0; //not used
-
s->mv_table_index = 0;
- }else{
+ break;
+ case 3:
+ 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_bits1(&s->gb);
s->mv_table_index = get_bits1(&s->gb);
+ break;
+ case 4:
+ s->use_skip_mb_code = 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 \n",
+
+ if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+ 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->mv_table_index,
+ s->per_mb_rl_table,
+ s->qscale);
+
if(s->flipflop_rounding){
s->no_rounding ^= 1;
}else{
s->no_rounding = 0;
}
-// printf("%d", s->no_rounding);
-//return -1;
}
-
-#if 0
-if(s->msmpeg4_version==2)
-{
-int i;
-for(i=0; i<s->gb.size*8; i++)
-// printf("%d", get_bits1(&s->gb));
- get_bits1(&s->gb);
-printf("END\n");
-return -1;
-}
-#endif
+//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height);
+
+ s->esc3_level_length= 0;
+ s->esc3_run_length= 0;
#ifdef DEBUG
printf("*****frame %d:\n", frame_count++);
int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
{
+ int left= buf_size*8 - get_bits_count(&s->gb);
+ int length= s->msmpeg4_version>=3 ? 17 : 16;
/* the alt_bitstream reader could read over the end so we need to check it */
- if(get_bits_count(&s->gb) + 16 < buf_size*8)
+ if(left>=length && left<length+8)
{
int fps;
fps= get_bits(&s->gb, 5);
- s->bitrate= get_bits(&s->gb, 11);
- s->flipflop_rounding= get_bits1(&s->gb);
+ 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->bitrate, s->flipflop_rounding);
+// printf("fps:%2d bps:%2d roundingType:%1d\n", fps, s->bit_rate/1024, s->flipflop_rounding);
}
- else
+ else if(left<length+8)
{
s->flipflop_rounding= 0;
- s->bitrate= 0;
+ if(s->msmpeg4_version != 2)
+ printf("ext header missing, %d left\n", left);
+ }
+ else
+ {
+ fprintf(stderr, "I frame too long, ignoring ext header\n");
}
return 0;
}
-static inline void memsetw(short *tab, int val, int n)
+static inline void msmpeg4_memsetw(short *tab, int val, int n)
{
int i;
for(i=0;i<n;i++)
{
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 pred;
sign = get_bits1(&s->gb);
shift = f_code - 1;
- val = (code - 1) << shift;
- if (shift > 0)
+ val = code;
+ if (shift) {
+ val = (val - 1) << shift;
val |= get_bits(&s->gb, shift);
- val++;
+ val++;
+ }
if (sign)
val = -val;
- val += pred;
+ val += pred;
if (val <= -64)
val += 64;
else if (val >= 64)
return val;
}
-
-int msmpeg4v2_decode_mb(MpegEncContext *s,
- DCTELEM block[6][64])
+static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
{
int cbp, code, i;
+
if (s->pict_type == P_TYPE) {
if (s->use_skip_mb_code) {
if (get_bits1(&s->gb)) {
}
}
- code = get_vlc(&s->gb, &v2_mb_type_vlc);
+ if(s->msmpeg4_version==2)
+ code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1);
+ else
+ 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;
+ }
+
s->mb_intra = code >>2;
cbp = code & 0x3;
} else {
s->mb_intra = 1;
- cbp= get_vlc(&s->gb, &v2_intra_cbpc_vlc);
+ if(s->msmpeg4_version==2)
+ cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1);
+ else
+ 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;
+ int mx, my, cbpy;
+
+ 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;
+ }
- cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2;
- if((cbp&3) != 3) cbp^= 0x3C;
+ cbp|= cbpy<<2;
+ if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C;
h263_pred_motion(s, 0, &mx, &my);
mx= msmpeg4v2_decode_motion(s, mx, 1);
s->mv[0][0][0] = mx;
s->mv[0][0][1] = my;
} else {
- s->ac_pred = get_bits1(&s->gb);
- cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2;
+ if(s->msmpeg4_version==2){
+ s->ac_pred = get_bits1(&s->gb);
+ cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
+ } else{
+ s->ac_pred = 0;
+ cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
+ if(s->pict_type==P_TYPE) cbp^=0x3C;
+ }
}
for (i = 0; i < 6; i++) {
- if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
+ if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
{
- fprintf(stderr,"\nIgnoring error while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+ fprintf(stderr,"\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
return -1;
}
}
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;
-
- /* 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;
- memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap],
- 1024, 2 * s->mb_width);
- wrap = s->mb_width + 2;
- memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap],
- 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 {
- s->first_slice_line = 0;
- }
- }
+ uint8_t *coded_val;
+ uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ];
- if(s->msmpeg4_version==2) return msmpeg4v2_decode_mb(s, block); //FIXME merge if possible
-
if (s->pict_type == P_TYPE) {
set_stat(ST_INTER_MB);
if (s->use_skip_mb_code) {
s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0;
s->mb_skiped = 1;
+ *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+
return 0;
}
}
- code = get_vlc(&s->gb, &mb_non_intra_vlc);
+ code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].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 */
if (!s->mb_intra) {
int mx, my;
+//printf("P at %d %d\n", 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;
+ }
set_stat(ST_MV);
h263_pred_motion(s, 0, &mx, &my);
if (msmpeg4_decode_motion(s, &mx, &my) < 0)
s->mv_type = MV_TYPE_16X16;
s->mv[0][0][0] = mx;
s->mv[0][0][1] = my;
+ *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;
} else {
+//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24));
set_stat(ST_INTRA_MB);
s->ac_pred = get_bits1(&s->gb);
+ *mb_type_ptr = MB_TYPE_INTRA;
+ 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;
+ }
}
for (i = 0; i < 6; i++) {
- if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
+ if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
{
- fprintf(stderr,"\nIgnoring error while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
- // return -1;
+ fprintf(stderr,"\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+ return -1;
}
}
+
return 0;
}
-
-static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
- int n, int coded)
+//#define ERROR_DETAILS
+static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded, const uint8_t *scan_table)
{
- int code, level, i, j, last, run, run_diff;
+ int level, i, last, run, run_diff;
int dc_pred_dir;
RLTable *rl;
- const UINT8 *scan_table;
+ RL_VLC_ELEM *rl_vlc;
int qmul, qadd;
if (s->mb_intra) {
/* DC coef */
set_stat(ST_DC);
level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
- if (level < 0)
- return -1;
- block[0] = level;
+
+ if (level < 0){
+ fprintf(stderr, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
+ 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);
+ 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);
+ 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 = ff_alternate_vertical_scan; /* left */
+ scan_table = s->intra_v_scantable.permutated; /* left */
else
- scan_table = ff_alternate_horizontal_scan; /* top */
+ scan_table = s->intra_h_scantable.permutated; /* top */
} else {
- scan_table = zigzag_direct;
+ 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 = zigzag_direct;
+ if(!scan_table)
+ 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)
- 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 (get_bits1(&s->gb) == 0) {
- if (get_bits1(&s->gb) == 0) {
+ if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {
+ if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {
/* third escape */
- last = get_bits1(&s->gb);
- run = get_bits(&s->gb, 6);
- level = get_bits(&s->gb, 8);
- level = (level << 24) >> 24; /* sign extend */
+ if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);
+ UPDATE_CACHE(re, &s->gb);
+ if(s->msmpeg4_version<=3){
+ 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= 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= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);
+ if(ll==0){
+ 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 && 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= 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= 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);
+#if 0 // waste of time / this will detect very few errors
+ {
+ const int abs_level= ABS(level);
+ const int run1= run - rl->max_run[last][abs_level] - run_diff;
+ if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
+ if(abs_level <= rl->max_level[last][run]){
+ fprintf(stderr, "illegal 3. esc, vlc encoding possible\n");
+ return DECODING_AC_LOST;
+ }
+ if(abs_level <= rl->max_level[last][run]*2){
+ fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n");
+ return DECODING_AC_LOST;
+ }
+ if(run1>=0 && abs_level <= rl->max_level[last][run1]){
+ fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n");
+ return DECODING_AC_LOST;
+ }
+ }
+ }
+#endif
//level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;
if (level>0) level= level * qmul + qadd;
- else level= level * qmul - qadd;
+ else level= level * qmul - qadd;
+#if 0 // waste of time too :(
+ if(level>2048 || level<-2048){
+ 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)
- 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)
- 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;
+ 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
}
- i += run;
- if (i >= 64)
- return -1;
-//printf("RL:%d %d %d ", run, level, last);
- j = scan_table[i];
- block[j] = level;
- i++;
- if (last)
+ if (i > 62){
+ i-= 192;
+ if(i&(~63)){
+ const int left= s->gb.size_in_bits - 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;
+ }
+ }
+
+ 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 */
}
}
- 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;
}
static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
{
int level, pred;
- INT16 *dc_val;
- if(s->msmpeg4_version==2){
+ 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)
+ if (level < 0){
+ fprintf(stderr, "illegal dc vlc\n");
return -1;
+ }
if (level == DC_MAX) {
level = get_bits(&s->gb, 8);
}
}
- pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
- level += pred;
+ if(s->msmpeg4_version==1){
+ int32_t *dc_val;
+ pred = msmpeg4v1_pred_dc(s, n, &dc_val);
+ level += pred;
+
+ /* update predictor */
+ *dc_val= level;
+ }else{
+ uint16_t *dc_val;
+ pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+ level += pred;
- /* update predictor */
- if (n < 4) {
- *dc_val = level * s->y_dc_scale;
- } else {
- *dc_val = level * s->c_dc_scale;
+ /* update predictor */
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
}
return level;
mv = &mv_tables[s->mv_table_index];
- code = get_vlc(&s->gb, &mv->vlc);
- if (code < 0)
+ 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;
+ }
if (code == mv->n) {
+//printf("MV ESC %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y);
mx = get_bits(&s->gb, 6);
my = get_bits(&s->gb, 6);
} else {
*my_ptr = my;
return 0;
}
+
+/* cleanest way to support it
+ * there is too much shared between versions so that we cant have 1 file per version & 1 common
+ * as allmost everything would be in the common file
+ */
+#include "wmv2.c"