From 0151a6f546121a5cd932fcaeef78e8f9f6f7582c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 18 Jun 2002 00:50:20 +0000 Subject: [PATCH] wmv1 support Originally committed as revision 697 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/allcodecs.c | 3 ++ libavcodec/avcodec.h | 3 ++ libavcodec/mpegvideo.h | 34 +++++++++++----- libavcodec/msmpeg4data.h | 85 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 11 deletions(-) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 7ffddb534e..7a6a31566f 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -48,6 +48,8 @@ void avcodec_register_all(void) register_avcodec(&msmpeg4v1_encoder); register_avcodec(&msmpeg4v2_encoder); register_avcodec(&msmpeg4v3_encoder); + register_avcodec(&wmv1_encoder); + register_avcodec(&wmv2_encoder); #endif /* CONFIG_ENCODERS */ register_avcodec(&rawvideo_codec); @@ -59,6 +61,7 @@ void avcodec_register_all(void) register_avcodec(&msmpeg4v2_decoder); register_avcodec(&msmpeg4v3_decoder); register_avcodec(&wmv1_decoder); + register_avcodec(&wmv2_decoder); register_avcodec(&mpeg_decoder); register_avcodec(&h263i_decoder); register_avcodec(&rv10_decoder); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 367268c2b5..d9775db527 100644 --- a/libavcodec/avcodec.h +++ b/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; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 2e957451b8..f25f5dcb38 100644 --- a/libavcodec/mpegvideo.h +++ b/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/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h index 66e0a3d895..9d728ef2e1 100644 --- a/libavcodec/msmpeg4data.h +++ b/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, +}; +