diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-06-23 21:04:35 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-06-23 21:04:35 +0000 |
commit | 8292ca3541e7375c0d05c40000e8359884027b74 (patch) | |
tree | 35f327de2108eea249b9c0720bb69ca30fba2901 | |
parent | 6bd244f210873b33611713256c58d9d139e0e945 (diff) | |
download | xine-lib-8292ca3541e7375c0d05c40000e8359884027b74.tar.gz xine-lib-8292ca3541e7375c0d05c40000e8359884027b74.tar.bz2 |
quick ffmpeg update (enables wmv1 decoding)
thanks to the ffmpeg team for their amazing work!
CVS patchset: 2141
CVS date: 2002/06/23 21:04:35
-rw-r--r-- | src/libffmpeg/libavcodec/avcodec.h | 10 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/common.h | 17 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/dsputil.c | 15 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/dsputil.h | 19 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/h263.c | 77 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/h263data.h | 6 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/h263dec.c | 41 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/i386/fdct_mmx.c | 2 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpeg12.c | 78 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpeg12data.h | 10 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpeg4data.h | 10 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpegvideo.c | 62 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/mpegvideo.h | 34 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/msmpeg4.c | 506 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/msmpeg4data.h | 85 |
15 files changed, 706 insertions, 266 deletions
diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h index 68b67154d..d9775db52 100644 --- a/src/libffmpeg/libavcodec/avcodec.h +++ b/src/libffmpeg/libavcodec/avcodec.h @@ -329,6 +329,8 @@ extern AVCodec mpeg4_encoder; extern AVCodec msmpeg4v1_encoder; extern AVCodec msmpeg4v2_encoder; extern AVCodec msmpeg4v3_encoder; +extern AVCodec wmv1_encoder; +extern AVCodec wmv2_encoder; extern AVCodec h263_decoder; extern AVCodec mpeg4_decoder; @@ -336,6 +338,7 @@ extern AVCodec msmpeg4v1_decoder; extern AVCodec msmpeg4v2_decoder; extern AVCodec msmpeg4v3_decoder; extern AVCodec wmv1_decoder; +extern AVCodec wmv2_decoder; extern AVCodec mpeg_decoder; extern AVCodec h263i_decoder; extern AVCodec rv10_decoder; @@ -520,4 +523,11 @@ typedef enum { */ int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout); +/* memory */ +void *av_malloc(int size); +void *av_mallocz(int size); +void av_free(void *ptr); +void __av_freep(void **ptr); +#define av_freep(p) __av_freep((void **)(p)) + #endif /* AVCODEC_H */ diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h index 24bd367d6..0d2c560c6 100644 --- a/src/libffmpeg/libavcodec/common.h +++ b/src/libffmpeg/libavcodec/common.h @@ -111,10 +111,10 @@ typedef signed long long INT64; #endif /* !CONFIG_WIN32 */ -#include "bswap.h" - #ifdef HAVE_AV_CONFIG_H +#include "bswap.h" + #if defined(__MINGW32__) || defined(__CYGWIN__) || \ defined(__OS2__) || defined (__OpenBSD__) #define MANGLE(a) "_" #a @@ -144,8 +144,6 @@ inline void dprintf(const char* fmt,...) {} #endif /* !CONFIG_WIN32 */ -#endif /* HAVE_AV_CONFIG_H */ - #define av_abort() do { fprintf(stderr, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0) /* assume b>0 */ @@ -888,13 +886,6 @@ static inline int clip(int a, int amin, int amax) return a; } -/* memory */ -void *av_malloc(int size); -void *av_mallocz(int size); -void av_free(void *ptr); -void __av_freep(void **ptr); -#define av_freep(p) __av_freep((void **)(p)) - /* math */ int ff_gcd(int a, int b); @@ -936,4 +927,6 @@ if((y)<(x)){\ #define CLAMP_TO_8BIT(d) ((d > 0xff) ? 0xff : (d < 0) ? 0 : d) -#endif +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* COMMON_H */ diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c index 945b7cc9d..6bc5c8b45 100644 --- a/src/libffmpeg/libavcodec/dsputil.c +++ b/src/libffmpeg/libavcodec/dsputil.c @@ -252,21 +252,6 @@ void add_pixels_clamped_c(const DCTELEM *block, UINT8 *pixels, int line_size) } } -#ifdef __GNUC__ - -struct unaligned_64 { uint64_t l; } __attribute__((packed)); -struct unaligned_32 { uint32_t l; } __attribute__((packed)); - -#define LD32(a) (((const struct unaligned_32 *) (a))->l) -#define LD64(a) (((const struct unaligned_64 *) (a))->l) - -#else /* __GNUC__ */ - -#define LD32(a) (*((uint32_t*)(a))) -#define LD64(a) (*((uint64_t*)(a))) - -#endif /* !__GNUC__ */ - #if 0 #define PIXOP2(OPNAME, OP) \ diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h index b7b7e999c..8c3fdb716 100644 --- a/src/libffmpeg/libavcodec/dsputil.h +++ b/src/libffmpeg/libavcodec/dsputil.h @@ -178,6 +178,25 @@ void dsputil_init_alpha(void); #endif +#ifdef __GNUC__ + +struct unaligned_64 { uint64_t l; } __attribute__((packed)); +struct unaligned_32 { uint32_t l; } __attribute__((packed)); + +#define LD32(a) (((const struct unaligned_32 *) (a))->l) +#define LD64(a) (((const struct unaligned_64 *) (a))->l) + +#define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b) + +#else /* __GNUC__ */ + +#define LD32(a) (*((uint32_t*)(a))) +#define LD64(a) (*((uint64_t*)(a))) + +#define ST32(a, b) *((uint32_t*)(a)) = (b) + +#endif /* !__GNUC__ */ + /* PSNR */ void get_psnr(UINT8 *orig_image[3], UINT8 *coded_image[3], int orig_linesize[3], int coded_linesize, diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c index decddd344..ae1eea7d7 100644 --- a/src/libffmpeg/libavcodec/h263.c +++ b/src/libffmpeg/libavcodec/h263.c @@ -50,7 +50,6 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded); static int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr); -static inline int mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr); static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, int dir); static void mpeg4_decode_sprite_trajectory(MpegEncContext * s); @@ -176,6 +175,14 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) } put_bits(&s->pb, 1, 0); /* no PEI */ + + if(s->h263_aic){ + s->y_dc_scale_table= + s->c_dc_scale_table= h263_aic_dc_scale_table; + }else{ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } } int h263_encode_gob_header(MpegEncContext * s, int mb_line) @@ -496,7 +503,7 @@ void mpeg4_encode_mb(MpegEncContext * s, const int level= block[i][0]; UINT16 *dc_ptr; - dc_diff[i]= level - mpeg4_pred_dc(s, i, &dc_ptr, &dir[i]); + dc_diff[i]= level - ff_mpeg4_pred_dc(s, i, &dc_ptr, &dir[i]); if (i < 4) { *dc_ptr = level * s->y_dc_scale; } else { @@ -1098,9 +1105,12 @@ void h263_encode_init(MpegEncContext *s) s->min_qcoeff= -128; s->max_qcoeff= 127; break; + //Note for mpeg4 & h263 the dc-scale table will be set per frame as needed later default: //nothing needed default table allready set in mpegvideo.c s->min_qcoeff= -128; s->max_qcoeff= 127; + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; } /* h263 type bias */ @@ -1326,44 +1336,18 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) if (s->pict_type == B_TYPE) put_bits(&s->pb, 3, s->b_code); /* fcode_back */ // printf("****frame %d\n", picture_number); + + s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support + s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; } -void h263_dc_scale(MpegEncContext * s) +static void h263_dc_scale(MpegEncContext * s) { -#if 1 - const static UINT8 y_tab[32]={ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 0, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,34,36,38,40,42,44,46 - }; - const static UINT8 c_tab[32]={ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,20,21,22,23,24,25 - }; - s->y_dc_scale = y_tab[s->qscale]; - s->c_dc_scale = c_tab[s->qscale]; -#else - 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); -#endif + s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; } -static inline int mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr) +inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr) { int a, b, c, wrap, pred, scale; UINT16 *dc_val; @@ -2653,10 +2637,6 @@ intra: if (s->ac_pred && s->h263_aic) s->h263_aic_dir = get_bits1(&s->gb); } - if (s->h263_aic) { - s->y_dc_scale = 2 * s->qscale; - s->c_dc_scale = 2 * s->qscale; - } cbpy = get_vlc(&s->gb, &cbpy_vlc); if(cbpy<0) return -1; cbp = (cbpc & 3) | (cbpy << 2); @@ -2867,7 +2847,7 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) } } - pred = mpeg4_pred_dc(s, n, &dc_val, dir_ptr); + pred = ff_mpeg4_pred_dc(s, n, &dc_val, dir_ptr); level += pred; if (level < 0) level = 0; @@ -2956,8 +2936,8 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, #if 1 { const int abs_level= ABS(level); - int run1; if(abs_level<=MAX_LEVEL && run<=MAX_RUN && s->error_resilience>=0){ + const int run1= run - rl->max_run[last][abs_level] - 1; if(abs_level <= rl->max_level[last][run]){ fprintf(stderr, "illegal 3. esc, vlc encoding possible\n"); return DECODING_AC_LOST; @@ -2966,7 +2946,6 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n"); return DECODING_AC_LOST; } - run1 = run - rl->max_run[last][abs_level] - 1; if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n"); return DECODING_AC_LOST; @@ -3185,6 +3164,15 @@ int h263_decode_picture_header(MpegEncContext *s) skip_bits(&s->gb, 8); } s->f_code = 1; + + if(s->h263_aic){ + s->y_dc_scale_table= + s->c_dc_scale_table= h263_aic_dc_scale_table; + }else{ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } + return 0; } @@ -3626,7 +3614,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s) }else{ printf("hmm, i havnt seen that version of divx yet, lets assume they fixed these bugs ...\n" "using mpeg4 decoder, if it fails contact the developers (of ffmpeg)\n"); -#endif +#endif } } } @@ -3760,6 +3748,9 @@ int mpeg4_decode_picture_header(MpegEncContext * s) s->picture_number++; // better than pic number==0 allways ;) //printf("done\n"); + s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support + s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; + return 0; } diff --git a/src/libffmpeg/libavcodec/h263data.h b/src/libffmpeg/libavcodec/h263data.h index 5a7b943ea..5aa1e18db 100644 --- a/src/libffmpeg/libavcodec/h263data.h +++ b/src/libffmpeg/libavcodec/h263data.h @@ -202,3 +202,9 @@ static const UINT16 h263_format[8][2] = { { 704, 576 }, { 1408, 1152 }, }; + +static UINT8 h263_aic_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 +}; + diff --git a/src/libffmpeg/libavcodec/h263dec.c b/src/libffmpeg/libavcodec/h263dec.c index 3c90a1e47..83b76dbe9 100644 --- a/src/libffmpeg/libavcodec/h263dec.c +++ b/src/libffmpeg/libavcodec/h263dec.c @@ -76,6 +76,11 @@ static int h263_decode_init(AVCodecContext *avctx) s->h263_pred = 1; s->msmpeg4_version=4; break; + case CODEC_ID_WMV2: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=5; + break; case CODEC_ID_H263I: s->h263_intel = 1; break; @@ -91,7 +96,7 @@ static int h263_decode_init(AVCodecContext *avctx) return -1; if (s->h263_msmpeg4) - msmpeg4_decode_init_vlc(s); + ff_msmpeg4_decode_init(s); else h263_decode_init_vlc(s); @@ -169,8 +174,10 @@ uint64_t time= rdtsc(); if(ret==FRAME_SKIPED) return 0; /* skip if the header was thrashed */ - if (ret < 0) + if (ret < 0){ + fprintf(stderr, "header damaged\n"); return -1; + } /* skip b frames if we dont have reference frames */ if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return 0; /* skip b frames if we are in a hurry */ @@ -216,6 +223,9 @@ uint64_t time= rdtsc(); s->last_dc[2]= 128; } + s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; + s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1; s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1); s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1; @@ -245,6 +255,9 @@ uint64_t time= rdtsc(); } } s->qscale= s->next_resync_qscale; + s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; + s->gb= s->next_resync_gb; s->resync_mb_x= s->mb_x; //we know that the marker is here cuz mb_num_left was the distance to it s->resync_mb_y= s->mb_y; @@ -265,18 +278,6 @@ uint64_t time= rdtsc(); //fprintf(stderr,"\nFrame: %d\tMB: %d",avctx->frame_number, (s->mb_y * s->mb_width) + s->mb_x); /* DCT & quantize */ - if (s->h263_pred && !(s->msmpeg4_version==1 || s->msmpeg4_version==2)) { - /* old ffmpeg encoded msmpeg4v3 workaround */ - if(s->workaround_bugs==1 && s->msmpeg4_version==3) - ff_old_msmpeg4_dc_scale(s); - else - h263_dc_scale(s); - } else { - /* default quantization values */ - s->y_dc_scale = 8; - s->c_dc_scale = 8; - } - if(s->decoding_error!=DECODING_DESYNC){ int last_error= s->decoding_error; clear_blocks(s->block[0]); @@ -521,6 +522,18 @@ AVCodec wmv1_decoder = { CODEC_CAP_DRAW_HORIZ_BAND, }; +AVCodec wmv2_decoder = { + "wmv2", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV2, + sizeof(MpegEncContext), + h263_decode_init, + NULL, + h263_decode_end, + h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, +}; + AVCodec h263i_decoder = { "h263i", CODEC_TYPE_VIDEO, diff --git a/src/libffmpeg/libavcodec/i386/fdct_mmx.c b/src/libffmpeg/libavcodec/i386/fdct_mmx.c index 7135beb21..dcc5c514c 100644 --- a/src/libffmpeg/libavcodec/i386/fdct_mmx.c +++ b/src/libffmpeg/libavcodec/i386/fdct_mmx.c @@ -46,7 +46,7 @@ const int16_t ocos_4_16[4] = { }; static const mmx_t fdct_one_corr = {0x0001000100010001LL}; -static volatile mmx_t fdct_r_row = { d:{RND_FRW_ROW, RND_FRW_ROW} }; +static const mmx_t fdct_r_row = { d:{RND_FRW_ROW, RND_FRW_ROW} }; const int16_t tab_frw_01234567[] ATTR_ALIGN(8) = { // forward_dct coeff table //row0 diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c index 37e9b70ac..9b917ce27 100644 --- a/src/libffmpeg/libavcodec/mpeg12.c +++ b/src/libffmpeg/libavcodec/mpeg12.c @@ -184,41 +184,14 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num) put_bits(&s->pb, 1, 1); } -void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) +static void common_init(MpegEncContext *s) { - static int done=0; - - if (!done) { - int i; - done = 1; - init_rl(&rl_mpeg1); - - for(i=0; i<64; i++) - { - mpeg1_max_level[0][i]= rl_mpeg1.max_level[0][i]; - mpeg1_index_run[0][i]= rl_mpeg1.index_run[0][i]; - } - - /* build unified dc encoding tables */ - for(i=-255; i<256; i++) - { - int adiff, index; - int bits, code; - int diff=i; - - adiff = ABS(diff); - if(diff<0) diff--; - index = vlc_dc_table[adiff]; + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; +} - bits= vlc_dc_lum_bits[index] + index; - code= (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)); - mpeg1_lum_dc_uni[i+255]= bits + (code<<8); - - bits= vlc_dc_chroma_bits[index] + index; - code= (vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)); - mpeg1_chr_dc_uni[i+255]= bits + (code<<8); - } - } +void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) +{ mpeg1_encode_sequence_header(s); /* mpeg1 picture header */ @@ -354,14 +327,46 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val) } } -void mpeg1_encode_init(MpegEncContext *s) +void ff_mpeg1_encode_init(MpegEncContext *s) { static int done=0; + + common_init(s); + if(!done){ int f_code; int mv; + int i; done=1; + init_rl(&rl_mpeg1); + + for(i=0; i<64; i++) + { + mpeg1_max_level[0][i]= rl_mpeg1.max_level[0][i]; + mpeg1_index_run[0][i]= rl_mpeg1.index_run[0][i]; + } + + /* build unified dc encoding tables */ + for(i=-255; i<256; i++) + { + int adiff, index; + int bits, code; + int diff=i; + + adiff = ABS(diff); + if(diff<0) diff--; + index = vlc_dc_table[adiff]; + + bits= vlc_dc_lum_bits[index] + index; + code= (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)); + mpeg1_lum_dc_uni[i+255]= bits + (code<<8); + + bits= vlc_dc_chroma_bits[index] + index; + code= (vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)); + mpeg1_chr_dc_uni[i+255]= bits + (code<<8); + } + for(f_code=1; f_code<=MAX_FCODE; f_code++){ for(mv=-MAX_MV; mv<=MAX_MV; mv++){ int len; @@ -403,7 +408,7 @@ void mpeg1_encode_init(MpegEncContext *s) s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x s->inter_quant_bias= 0; } - + static inline void encode_dc(MpegEncContext *s, int diff, int component) { if (component == 0) { @@ -533,6 +538,7 @@ void mpeg1_init_vlc(MpegEncContext *s) static int done = 0; if (!done) { + done = 1; init_vlc(&dc_lum_vlc, 9, 12, vlc_dc_lum_bits, 1, 1, @@ -1182,6 +1188,8 @@ typedef struct Mpeg1Context { static int mpeg_decode_init(AVCodecContext *avctx) { Mpeg1Context *s = avctx->priv_data; + + common_init(&s->mpeg_enc_ctx); s->header_state = 0xff; s->mpeg_enc_ctx_allocated = 0; diff --git a/src/libffmpeg/libavcodec/mpeg12data.h b/src/libffmpeg/libavcodec/mpeg12data.h index 65a8a2b9a..cfb6e1d0f 100644 --- a/src/libffmpeg/libavcodec/mpeg12data.h +++ b/src/libffmpeg/libavcodec/mpeg12data.h @@ -402,3 +402,13 @@ static const UINT8 non_linear_qscale[32] = { 24,28,32,36,40,44,48,52, 56,64,72,80,88,96,104,112, }; + +UINT8 ff_mpeg1_dc_scale_table[128]={ // MN: mpeg2 really can have such large qscales? +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + + diff --git a/src/libffmpeg/libavcodec/mpeg4data.h b/src/libffmpeg/libavcodec/mpeg4data.h index e972a7576..3d8de7ca6 100644 --- a/src/libffmpeg/libavcodec/mpeg4data.h +++ b/src/libffmpeg/libavcodec/mpeg4data.h @@ -153,3 +153,13 @@ INT16 ff_mpeg4_default_non_intra_matrix[64] = { 23, 24, 25, 27, 28, 30, 31, 33, }; +UINT8 ff_mpeg4_y_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,34,36,38,40,42,44,46 +}; +UINT8 ff_mpeg4_c_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,20,21,22,23,24,25 +}; + + diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c index 63242c9de..105fb5502 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.c +++ b/src/libffmpeg/libavcodec/mpegvideo.c @@ -460,6 +460,22 @@ int MPV_encode_init(AVCodecContext *avctx) s->msmpeg4_version= 3; avctx->delay=0; break; + case CODEC_ID_WMV1: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 4; + avctx->delay=0; + break; + case CODEC_ID_WMV2: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 5; + avctx->delay=0; + break; default: return -1; } @@ -483,7 +499,9 @@ int MPV_encode_init(AVCodecContext *avctx) if (s->out_format == FMT_H263) h263_encode_init(s); else if (s->out_format == FMT_MPEG1) - mpeg1_encode_init(s); + ff_mpeg1_encode_init(s); + if(s->msmpeg4_version) + ff_msmpeg4_encode_init(s); /* dont use mv_penalty table for crap MV as it would be confused */ if (s->me_method < ME_EPZS) s->mv_penalty = default_mv_penalty; @@ -1521,16 +1539,6 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) } #endif /* DCT & quantize */ - if (s->h263_pred && !(s->msmpeg4_version==1 || s->msmpeg4_version==2)) { - h263_dc_scale(s); - } else if (s->h263_aic) { - s->y_dc_scale = 2*s->qscale; - s->c_dc_scale = 2*s->qscale; - } else { - /* default quantization values */ - s->y_dc_scale = 8; - s->c_dc_scale = 8; - } if(s->out_format==FMT_MJPEG){ for(i=0;i<6;i++) { int overflow; @@ -1585,7 +1593,6 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) void ff_copy_bits(PutBitContext *pb, UINT8 *src, int length) { -#if 1 int bytes= length>>4; int bits= length&15; int i; @@ -1594,14 +1601,6 @@ void ff_copy_bits(PutBitContext *pb, UINT8 *src, int length) for(i=0; i<bytes; i++) put_bits(pb, 16, be2me_16(((uint16_t*)src)[i])); put_bits(pb, bits, be2me_16(((uint16_t*)src)[i])>>(16-bits)); -#else - int bytes= length>>3; - int bits= length&7; - int i; - - for(i=0; i<bytes; i++) put_bits(pb, 8, src[i]); - put_bits(pb, bits, src[i]>>(8-bits)); -#endif } static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){ @@ -1874,6 +1873,9 @@ static void encode_picture(MpegEncContext *s, int picture_number) } } } + + s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; s->block_index[0]= s->block_wrap[0]*(mb_y*2 + 1) - 1; s->block_index[1]= s->block_wrap[0]*(mb_y*2 + 1); @@ -2587,3 +2589,23 @@ AVCodec msmpeg4v3_encoder = { MPV_encode_picture, MPV_encode_end, }; + +AVCodec wmv1_encoder = { + "wmv1", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV1, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, +}; + +AVCodec wmv2_encoder = { + "wmv2", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV2, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, +}; diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h index 2e957451b..f25f5dcb3 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.h +++ b/src/libffmpeg/libavcodec/mpegvideo.h @@ -41,6 +41,10 @@ enum OutputFormat { #define ME_MAP_SHIFT 3 #define ME_MAP_MV_BITS 11 +/* run length table */ +#define MAX_RUN 64 +#define MAX_LEVEL 64 + typedef struct Predictor{ double coeff; double count; @@ -143,6 +147,8 @@ typedef struct MpegEncContext { int last_dc[3]; /* last DC values for MPEG1 */ INT16 *dc_val[3]; /* used for mpeg4 DC prediction, all 3 arrays must be continuous */ int y_dc_scale, c_dc_scale; + UINT8 *y_dc_scale_table; /* qscale -> y_dc_scale table */ + UINT8 *c_dc_scale_table; /* qscale -> c_dc_scale table */ UINT8 *coded_block; /* used for coded block pattern prediction (msmpeg4v3, wmv1)*/ INT16 (*ac_val[3])[16]; /* used for for mpeg4 AC prediction, all 3 arrays must be continuous */ int ac_pred; @@ -376,7 +382,18 @@ typedef struct MpegEncContext { int slice_height; /* in macroblocks */ int first_slice_line; /* used in mpeg4 too to handle resync markers */ int flipflop_rounding; - int msmpeg4_version; /* 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 */ + int msmpeg4_version; /* 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 4=wmv1/7 5=wmv2/8*/ + int per_mb_rl_table; + int esc3_level_length; + int esc3_run_length; + UINT8 *inter_scantable; + UINT8 *intra_scantable; + UINT8 *intra_v_scantable; + UINT8 *intra_h_scantable; + /* [mb_intra][isChroma][level][run][last] */ + int ac_stats[2][2][MAX_LEVEL+1][MAX_RUN+1][2]; + + /* decompression specific */ GetBitContext gb; @@ -452,19 +469,16 @@ void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, i /* mpeg12.c */ extern INT16 default_intra_matrix[64]; extern INT16 default_non_intra_matrix[64]; +extern UINT8 ff_mpeg1_dc_scale_table[128]; void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y); -void mpeg1_encode_init(MpegEncContext *s); +void ff_mpeg1_encode_init(MpegEncContext *s); /* h263enc.c */ -/* run length table */ -#define MAX_RUN 64 -#define MAX_LEVEL 64 - typedef struct RLTable { int n; /* number of entries of table_vlc minus 1 */ int last; /* number of values for last = 0 */ @@ -491,6 +505,8 @@ static inline int get_rl_index(const RLTable *rl, int last, int run, int level) return index + level - 1; } +extern UINT8 ff_mpeg4_y_dc_scale_table[32]; +extern UINT8 ff_mpeg4_c_dc_scale_table[32]; void h263_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y); @@ -499,7 +515,6 @@ void mpeg4_encode_mb(MpegEncContext *s, int motion_x, int motion_y); void h263_encode_picture_header(MpegEncContext *s, int picture_number); int h263_encode_gob_header(MpegEncContext * s, int mb_line); -void h263_dc_scale(MpegEncContext *s); INT16 *h263_pred_motion(MpegEncContext * s, int block, int *px, int *py); void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, @@ -523,6 +538,7 @@ void ff_mpeg4_clean_buffers(MpegEncContext *s); void ff_mpeg4_stuffing(PutBitContext * pbc); void ff_mpeg4_init_partitions(MpegEncContext *s); void ff_mpeg4_merge_partitions(MpegEncContext *s); +extern inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr); /* rv10.c */ void rv10_encode_picture_header(MpegEncContext *s, int picture_number); @@ -538,8 +554,8 @@ int msmpeg4_decode_picture_header(MpegEncContext * s); int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size); int msmpeg4_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); -int msmpeg4_decode_init_vlc(MpegEncContext *s); -void ff_old_msmpeg4_dc_scale(MpegEncContext *s); +int ff_msmpeg4_decode_init(MpegEncContext *s); +void ff_msmpeg4_encode_init(MpegEncContext *s); /* mjpegenc.c */ diff --git a/src/libffmpeg/libavcodec/msmpeg4.c b/src/libffmpeg/libavcodec/msmpeg4.c index 629c74497..0cac44457 100644 --- a/src/libffmpeg/libavcodec/msmpeg4.c +++ b/src/libffmpeg/libavcodec/msmpeg4.c @@ -21,7 +21,7 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" - +//#define PRINT_MB /* * You can also call this codec : MPEG4 with a twist ! @@ -32,23 +32,12 @@ */ //#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); +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); 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); @@ -62,9 +51,6 @@ extern UINT32 inverse[256]; int intra_count = 0; int frame_count = 0; #endif -/* XXX: move it to mpegvideo.h */ - -static int init_done = 0; #include "msmpeg4data.h" @@ -132,6 +118,61 @@ void print_stats(void) #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: + 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){ + 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; + } + + 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); + } + } + + } +} + /* build the table which associate a (x,y) motion vector to a vlc */ static void init_mv_table(MVTable *tab) { @@ -159,43 +200,178 @@ static void code012(PutBitContext *pb, int n) } } +void ff_msmpeg4_encode_init(MpegEncContext *s) +{ + static int init_done=0; + int i; + + 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]); + } +} + +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; + int last_size=0; + + 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; + 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); + }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); + } + } + } + } + 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) { - int i; + 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->pict_type == I_TYPE) { + s->no_rounding = 1; put_bits(&s->pb, 5, 0x17); /* indicate only one "slice" */ + + if(s->msmpeg4_version==4){ + msmpeg4_encode_ext_header(s); + 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->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==4) + put_bits(&s->pb, 1, s->per_mb_rl_table); + if(s->msmpeg4_version>2){ - code012(&s->pb, s->rl_table_index); + if(!s->per_mb_rl_table) + code012(&s->pb, s->rl_table_index); put_bits(&s->pb, 1, s->dc_table_index); @@ -209,16 +385,8 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) } } - 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; @@ -427,8 +595,8 @@ void ff_old_msmpeg4_dc_scale(MpegEncContext * s) } } -static int msmpeg4v1_pred_dc(MpegEncContext * s, int n, - INT32 **dc_val_ptr) +static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n, + INT32 **dc_val_ptr) { int i; @@ -443,8 +611,8 @@ static int msmpeg4v1_pred_dc(MpegEncContext * s, int n, } /* 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 **dc_val_ptr, int *dir_ptr) { int a, b, c, wrap, pred, scale; INT16 *dc_val; @@ -506,12 +674,22 @@ static int msmpeg4_pred_dc(MpegEncContext * s, int n, #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 (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 */ @@ -533,7 +711,7 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr /* update predictor */ *dc_val= level; }else{ - INT16 *dc_val; + UINT16 *dc_val; pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); /* update predictor */ @@ -593,12 +771,13 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr /* 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 *scantable; if (s->mb_intra) { set_stat(ST_DC); @@ -610,6 +789,7 @@ static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) rl = &rl_table[3 + s->rl_chroma_table_index]; } run_diff = 0; + scantable= s->intra_scantable; set_stat(ST_INTRA_AC); } else { i = 0; @@ -618,14 +798,21 @@ static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) run_diff = 0; else run_diff = 1; + scantable= s->inter_scantable; set_stat(ST_INTER_AC); } + /* recalculate block_last_index for M$ wmv1 */ + if(scantable!=zigzag_direct && s->block_last_index[n]>0){ + for(last_index=63; last_index>=0; last_index--){ + if(block[scantable[last_index]]) break; + } + }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; @@ -636,6 +823,13 @@ static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) 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) { @@ -659,8 +853,22 @@ static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int 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); @@ -700,11 +908,7 @@ static VLC v1_inter_cbpc_vlc; /* this table is practically identical to the one from h263 except that its inverted */ 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; @@ -754,16 +958,16 @@ static void init_h263_dc_for_msmpeg4(void) 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; + common_init(s); if (!done) { done = 1; @@ -792,7 +996,6 @@ int msmpeg4_decode_init_vlc(MpegEncContext *s) &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); @@ -842,7 +1045,7 @@ static int decode012(GetBitContext *gb) int msmpeg4_decode_picture_header(MpegEncContext * s) { - int code, code2; + int code; #if 0 { @@ -907,26 +1110,24 @@ return -1; 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); + + s->per_mb_rl_table= get_bits1(&s->gb); + 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); break; } s->no_rounding = 1; -/* printf(" %d %d %d %d \n", +/* printf(" %d %d %d %d %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);*/ } else { switch(s->msmpeg4_version){ @@ -950,33 +1151,35 @@ return -1; s->mv_table_index = get_bits1(&s->gb); break; + case 4: + s->use_skip_mb_code = get_bits1(&s->gb); + s->per_mb_rl_table= get_bits1(&s->gb); + 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); + break; } -/* printf(" %d %d %d %d %d \n", +/* printf(" %d %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);*/ + s->mv_table_index, + s->per_mb_rl_table);*/ 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 + + s->esc3_level_length= 0; + s->esc3_run_length= 0; #ifdef DEBUG printf("*****frame %d:\n", frame_count++); @@ -1177,6 +1380,12 @@ int msmpeg4_decode_mb(MpegEncContext *s, int cbp, code, i; UINT8 *coded_val; +#ifdef PRINT_MB +if(s->mb_x==0){ + printf("\n"); + 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) { @@ -1222,6 +1431,9 @@ int msmpeg4_decode_mb(MpegEncContext *s, s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; s->mb_skiped = 1; +#ifdef PRINT_MB +printf("S "); +#endif return 0; } } @@ -1254,6 +1466,11 @@ int msmpeg4_decode_mb(MpegEncContext *s, 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) @@ -1262,9 +1479,20 @@ int msmpeg4_decode_mb(MpegEncContext *s, s->mv_type = MV_TYPE_16X16; s->mv[0][0][0] = mx; s->mv[0][0][1] = my; +#ifdef PRINT_MB +printf("P "); +#endif } 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); +#ifdef PRINT_MB +printf("%c", s->ac_pred ? 'A' : 'I'); +#endif + 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++) { @@ -1274,11 +1502,11 @@ int msmpeg4_decode_mb(MpegEncContext *s, return -1; } } - + return 0; } -static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, +static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded) { int code, level, i, j, last, run, run_diff; @@ -1294,20 +1522,28 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, /* DC coef */ set_stat(ST_DC); level = msmpeg4_decode_dc(s, n, &dc_pred_dir); +#ifdef PRINT_MB +{ + static int c; + if(n==0) c=0; + if(n==4) printf("%X", c); + c+= c +dc_pred_dir; +} +#endif if (level < 0){ - fprintf(stderr, "dc overflow-\n"); + fprintf(stderr, "dc overflow- block: %d qscale: %d//\n", n, s->qscale); return -1; } if (n < 4) { rl = &rl_table[s->rl_table_index]; if(level > 256*s->y_dc_scale){ - fprintf(stderr, "dc overflow+\n"); + fprintf(stderr, "dc overflow+ L qscale: %d//\n", s->qscale); return -1; } } else { rl = &rl_table[3 + s->rl_chroma_table_index]; if(level > 256*s->c_dc_scale){ - fprintf(stderr, "dc overflow+\n"); + fprintf(stderr, "dc overflow+ C qscale: %d//\n", s->qscale); return -1; } } @@ -1320,11 +1556,11 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, } if (s->ac_pred) { if (dc_pred_dir == 0) - scan_table = ff_alternate_vertical_scan; /* left */ + scan_table = s->intra_v_scantable; /* left */ else - scan_table = ff_alternate_horizontal_scan; /* top */ + scan_table = s->intra_h_scantable; /* top */ } else { - scan_table = zigzag_direct; + scan_table = s->intra_scantable; } set_stat(ST_INTRA_AC); } else { @@ -1342,23 +1578,53 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, s->block_last_index[n] = i - 1; return 0; } - scan_table = zigzag_direct; + scan_table = s->inter_scantable; set_stat(ST_INTER_AC); } for(;;) { code = get_vlc(&s->gb, &rl->vlc); - if (code < 0) + 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) { /* escape */ if (s->msmpeg4_version==1 || get_bits1(&s->gb) == 0) { if (s->msmpeg4_version==1 || get_bits1(&s->gb) == 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<=3){ + last= get_bits1(&s->gb); + run= get_bits(&s->gb, 6); + level= get_bits(&s->gb, 8); + level= ((int8_t)level); + }else{ + int sign; + last= get_bits1(&s->gb); + 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); + if(ll==0){ + if(get_bits1(&s->gb)) printf("cool a new vlc code ,contact the ffmpeg developers and upload the file\n"); + ll=8; + } + }else{ + ll=2; + while(ll<8 && get_bits1(&s->gb)==0) ll++; + } + + s->esc3_level_length= ll; + s->esc3_run_length= get_bits(&s->gb, 2) + 3; +//printf("level length:%d, run length: %d\n", ll, s->esc3_run_length); + } + run= get_bits(&s->gb, s->esc3_run_length); + sign= get_bits1(&s->gb); + level= get_bits(&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); @@ -1372,7 +1638,7 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n"); return DECODING_AC_LOST; } - if(abs_level <= rl->max_level[last][run1] && 0){ + if(run1>=0 && abs_level <= rl->max_level[last][run1]){ fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n"); return DECODING_AC_LOST; } @@ -1391,8 +1657,10 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, } else { /* second escape */ code = get_vlc(&s->gb, &rl->vlc); - if (code < 0 || code >= rl->n) + 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; @@ -1404,8 +1672,10 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, } else { /* first escape */ code = get_vlc(&s->gb, &rl->vlc); - if (code < 0 || code >= rl->n) + 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; @@ -1422,8 +1692,10 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, level = -level; } i += run; - if (i >= 64) + if (i >= 64){ + fprintf(stderr, "run too long at %d %d\n", s->mb_x, s->mb_y); return -1; + } j = scan_table[i]; block[j] = level; @@ -1438,8 +1710,9 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, i = 64; /* XXX: not optimal */ } } + if(s->msmpeg4_version==4 && i>1) i=64; //FIXME/XXX optimize s->block_last_index[n] = i - 1; - + return 0; } @@ -1485,7 +1758,7 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) /* update predictor */ *dc_val= level; }else{ - INT16 *dc_val; + UINT16 *dc_val; pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); level += pred; @@ -1509,9 +1782,12 @@ static int msmpeg4_decode_motion(MpegEncContext * s, mv = &mv_tables[s->mv_table_index]; code = get_vlc(&s->gb, &mv->vlc); - if (code < 0) + 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 { diff --git a/src/libffmpeg/libavcodec/msmpeg4data.h b/src/libffmpeg/libavcodec/msmpeg4data.h index 66e0a3d89..9d728ef2e 100644 --- a/src/libffmpeg/libavcodec/msmpeg4data.h +++ b/src/libffmpeg/libavcodec/msmpeg4data.h @@ -578,8 +578,8 @@ extern const UINT8 mvtab[33][2]; extern const UINT8 intra_MCBPC_code[8]; extern const UINT8 intra_MCBPC_bits[8]; -extern const UINT8 inter_MCBPC_code[8]; -extern const UINT8 inter_MCBPC_bits[8]; +extern const UINT8 inter_MCBPC_code[25]; +extern const UINT8 inter_MCBPC_bits[25]; #define NB_RL_TABLES 6 @@ -1761,6 +1761,17 @@ static const UINT8 table1_mvy[1099] = { 34, 28, 21, }; +/* 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 MVTable mv_tables[2] = { { 1099, @@ -1786,3 +1797,73 @@ static const UINT8 v2_mb_type[8][2] = { static const UINT8 v2_intra_cbpc[4][2] = { {1, 1}, {0, 3}, {1, 3}, {1, 2}, }; + +static UINT8 wmv1_y_dc_scale_table[32]={ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + 0, 8, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 +}; +static UINT8 wmv1_c_dc_scale_table[32]={ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 +}; + +static UINT8 old_ff_y_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 +}; +static UINT8 old_ff_c_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 +}; + + +#define WMV1_SCANTABLE_COUNT 4 + +static UINT8 wmv1_scantable00[64]= { +0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, +0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, +0x30, 0x38, 0x29, 0x21, 0x1A, 0x13, 0x0C, 0x05, +0x06, 0x0D, 0x14, 0x1B, 0x22, 0x31, 0x39, 0x3A, +0x32, 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, +0x16, 0x1D, 0x24, 0x2B, 0x33, 0x3B, 0x3C, 0x34, +0x2C, 0x25, 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x35, +0x3D, 0x3E, 0x36, 0x2E, 0x27, 0x2F, 0x37, 0x3F, +}; +static UINT8 wmv1_scantable01[64]= { +0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, +0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, +0x21, 0x30, 0x1A, 0x13, 0x0C, 0x05, 0x06, 0x0D, +0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, 0x2A, +0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, 0x16, 0x1D, +0x24, 0x2B, 0x32, 0x3A, 0x33, 0x3B, 0x2C, 0x25, +0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3C, 0x35, +0x3D, 0x2E, 0x27, 0x2F, 0x36, 0x3E, 0x37, 0x3F, +}; +static UINT8 wmv1_scantable02[64]= { +0x00, 0x01, 0x08, 0x02, 0x03, 0x09, 0x10, 0x18, +0x11, 0x0A, 0x04, 0x05, 0x0B, 0x12, 0x19, 0x20, +0x28, 0x30, 0x21, 0x1A, 0x13, 0x0C, 0x06, 0x07, +0x0D, 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, +0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x0F, 0x16, 0x1D, +0x24, 0x2B, 0x32, 0x3A, 0x33, 0x2C, 0x25, 0x1E, +0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x3C, 0x35, +0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, +}; +static UINT8 wmv1_scantable03[64]= { +0x00, 0x08, 0x10, 0x01, 0x18, 0x20, 0x28, 0x09, +0x02, 0x03, 0x0A, 0x11, 0x19, 0x30, 0x38, 0x29, +0x21, 0x1A, 0x12, 0x0B, 0x04, 0x05, 0x0C, 0x13, +0x1B, 0x22, 0x31, 0x39, 0x32, 0x2A, 0x23, 0x1C, +0x14, 0x0D, 0x06, 0x07, 0x0E, 0x15, 0x1D, 0x24, +0x2B, 0x33, 0x3A, 0x3B, 0x34, 0x2C, 0x25, 0x1E, +0x16, 0x0F, 0x17, 0x1F, 0x26, 0x2D, 0x3C, 0x35, +0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, +}; + +static UINT8 *wmv1_scantable[WMV1_SCANTABLE_COUNT+1]={ + wmv1_scantable00, + wmv1_scantable01, + wmv1_scantable02, + wmv1_scantable03, +}; + |