diff mpegvideo.c @ 936:caa77cd960c0 libavcodec

qpel encoding 4mv+b frames encoding finally fixed chroma ME 5 comparission functions for ME b frame encoding speedup wmv2 codec (unfinished) user specified diamond size for EPZS
author michaelni
date Fri, 27 Dec 2002 23:51:46 +0000
parents 6bcb214d6a17
children 463f7260b155
line wrap: on
line diff
--- a/mpegvideo.c	Sun Dec 22 22:34:42 2002 +0000
+++ b/mpegvideo.c	Fri Dec 27 23:51:46 2002 +0000
@@ -43,8 +43,6 @@
 static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
 
 void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edges_c;
-static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, 
-                                    int src_x, int src_y, int w, int h);
 
 
 /* enable all paranoid tests for rounding, overflows, etc... */
@@ -64,8 +62,8 @@
     19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
     16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
     12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
-    8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
-    4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
+    8867 , 12299, 11585, 10426,  8867,  6967,  4799,  2446,
+    4520 ,  6270,  5906,  5315,  4520,  3552,  2446,  1247
 };
 
 /* Input permutation for the simple_idct_mmx */
@@ -87,9 +85,6 @@
 static UINT16 (*default_mv_penalty)[MAX_MV*2+1]=NULL;
 static UINT8 default_fcode_tab[MAX_MV*2+1];
 
-/* default motion estimation */
-int motion_estimation_method = ME_EPZS;
-
 static void convert_matrix(MpegEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[64], uint16_t (*qmat16_bias)[64],
                            const UINT16 *quant_matrix, int bias, int qmin, int qmax)
 {
@@ -394,15 +389,13 @@
         CHECKED_ALLOCZ(s->b_back_mv_table       , mv_table_size * 2 * sizeof(INT16))
         CHECKED_ALLOCZ(s->b_bidir_forw_mv_table , mv_table_size * 2 * sizeof(INT16))
         CHECKED_ALLOCZ(s->b_bidir_back_mv_table , mv_table_size * 2 * sizeof(INT16))
-        CHECKED_ALLOCZ(s->b_direct_forw_mv_table, mv_table_size * 2 * sizeof(INT16))
-        CHECKED_ALLOCZ(s->b_direct_back_mv_table, mv_table_size * 2 * sizeof(INT16))
         CHECKED_ALLOCZ(s->b_direct_mv_table     , mv_table_size * 2 * sizeof(INT16))
 
         //FIXME should be linesize instead of s->width*2 but that isnt known before get_buffer()
-        CHECKED_ALLOCZ(s->me_scratchpad,  s->width*2*16*3*sizeof(uint8_t)) 
+        CHECKED_ALLOCZ(s->me.scratchpad,  s->width*2*16*3*sizeof(uint8_t)) 
         
-        CHECKED_ALLOCZ(s->me_map      , ME_MAP_SIZE*sizeof(uint32_t))
-        CHECKED_ALLOCZ(s->me_score_map, ME_MAP_SIZE*sizeof(uint16_t))
+        CHECKED_ALLOCZ(s->me.map      , ME_MAP_SIZE*sizeof(uint32_t))
+        CHECKED_ALLOCZ(s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t))
 
         if(s->codec_id==CODEC_ID_MPEG4){
             CHECKED_ALLOCZ(s->tex_pb_buffer, PB_BUFFER_SIZE);
@@ -498,8 +491,6 @@
     av_freep(&s->b_back_mv_table);
     av_freep(&s->b_bidir_forw_mv_table);
     av_freep(&s->b_bidir_back_mv_table);
-    av_freep(&s->b_direct_forw_mv_table);
-    av_freep(&s->b_direct_back_mv_table);
     av_freep(&s->b_direct_mv_table);
     av_freep(&s->motion_val);
     av_freep(&s->dc_val[0]);
@@ -508,9 +499,9 @@
     av_freep(&s->mbintra_table);
     av_freep(&s->cbp_table);
     av_freep(&s->pred_dir_table);
-    av_freep(&s->me_scratchpad);
-    av_freep(&s->me_map);
-    av_freep(&s->me_score_map);
+    av_freep(&s->me.scratchpad);
+    av_freep(&s->me.map);
+    av_freep(&s->me.score_map);
     
     av_freep(&s->mbskip_table);
     av_freep(&s->bitstream_buffer);
@@ -566,6 +557,7 @@
     s->chroma_elim_threshold= avctx->chroma_elim_threshold;
     s->strict_std_compliance= avctx->strict_std_compliance;
     s->data_partitioning= avctx->flags & CODEC_FLAG_PART;
+    s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;
     s->mpeg_quant= avctx->mpeg_quant;
 
     if (s->gop_size <= 1) {
@@ -575,12 +567,7 @@
         s->intra_only = 0;
     }
 
-    /* ME algorithm */
-    if (avctx->me_method == 0)
-        /* For compatibility */
-        s->me_method = motion_estimation_method;
-    else
-        s->me_method = avctx->me_method;
+    s->me_method = avctx->me_method;
 
     /* Fixed QSCALE */
     s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE);
@@ -713,13 +700,14 @@
             }
         }
     }
-    s->mv_penalty= default_mv_penalty;
+    s->me.mv_penalty= default_mv_penalty;
     s->fcode_tab= default_fcode_tab;
     s->y_dc_scale_table=
     s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
  
     /* 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;
+    //FIXME remove after fixing / removing old ME
+    if (s->me_method < ME_EPZS) s->me.mv_penalty = default_mv_penalty;
 
     s->encoding = 1;
 
@@ -727,6 +715,8 @@
     if (MPV_common_init(s) < 0)
         return -1;
     
+    ff_init_me(s);
+
 #ifdef CONFIG_ENCODERS
     if (s->out_format == FMT_H263)
         h263_encode_init(s);
@@ -947,6 +937,18 @@
         if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/)
             s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);
     }
+    if(s->avctx->debug&FF_DEBUG_SKIP){
+        int x,y;        
+        for(y=0; y<s->mb_height; y++){
+            for(x=0; x<s->mb_width; x++){
+                int count= s->mbskip_table[x + y*s->mb_width];
+                if(count>9) count=9;
+                printf(" %1d", count);
+            }
+            printf("\n");
+        }
+        printf("pict type: %d\n", s->pict_type);
+    }
 }
 
 static int get_sae(uint8_t *src, int ref, int stride){
@@ -1284,7 +1286,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->h_edge_pos
                               || src_y + (motion_y&15) + 16 > s->v_edge_pos){
-            emulated_edge_mc(s, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+            ff_emulated_edge_mc(s, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer;
             emu=1;
         }
@@ -1322,14 +1324,14 @@
     offset = (src_y * uvlinesize) + src_x + (src_offset>>1);
     ptr = ref_picture[1] + offset;
     if(emu){
-        emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+        ff_emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
     }
     s->dsp.gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
     
     ptr = ref_picture[2] + offset;
     if(emu){
-        emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+        ff_emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer;
     }
     s->dsp.gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
@@ -1401,7 +1403,7 @@
 }
 
 
-static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, 
+void ff_emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, 
                                     int src_x, int src_y, int w, int h){
     int x, y;
     int start_y, start_x, end_y, end_x;
@@ -1501,7 +1503,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 16 > s->h_edge_pos
                               || src_y + (motion_y&1) + h  > v_edge_pos){
-            emulated_edge_mc(s, ptr - src_offset, s->linesize, 17, 17+field_based, 
+            ff_emulated_edge_mc(s, ptr - src_offset, s->linesize, 17, 17+field_based, 
                              src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer + src_offset;
             emu=1;
@@ -1538,7 +1540,7 @@
     offset = (src_y * uvlinesize) + src_x + (src_offset >> 1);
     ptr = ref_picture[1] + offset;
     if(emu){
-        emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9+field_based, 
+        ff_emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9+field_based, 
                          src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer + (src_offset >> 1);
     }
@@ -1546,7 +1548,7 @@
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9+field_based, 
+        ff_emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9+field_based, 
                          src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer + (src_offset >> 1);
     }
@@ -1586,7 +1588,7 @@
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(src_x<0 || src_y<0 || src_x + (motion_x&3) + 16 > s->h_edge_pos
                               || src_y + (motion_y&3) + h  > v_edge_pos){
-            emulated_edge_mc(s, ptr - src_offset, s->linesize, 17, 17+field_based, 
+            ff_emulated_edge_mc(s, ptr - src_offset, s->linesize, 17, 17+field_based, 
                              src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer + src_offset;
             emu=1;
@@ -1631,7 +1633,7 @@
     offset = (src_y * uvlinesize) + src_x + (src_offset >> 1);
     ptr = ref_picture[1] + offset;
     if(emu){
-        emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9 + field_based, 
+        ff_emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9 + field_based, 
                          src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer + (src_offset >> 1);
     }
@@ -1639,7 +1641,7 @@
     
     ptr = ref_picture[2] + offset;
     if(emu){
-        emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9 + field_based, 
+        ff_emulated_edge_mc(s, ptr - (src_offset >> 1), s->uvlinesize, 9, 9 + field_based, 
                          src_x, src_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1);
         ptr= s->edge_emu_buffer + (src_offset >> 1);
     }
@@ -1675,6 +1677,10 @@
                         ref_picture, 0,
                         0, pix_op, qpix_op,
                         s->mv[dir][0][0], s->mv[dir][0][1], 16);
+        }else if(s->mspel){
+            ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
+                        ref_picture, pix_op,
+                        s->mv[dir][0][0], s->mv[dir][0][1], 16);
         }else{
             mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
                         ref_picture, 0,
@@ -1706,7 +1712,7 @@
                 if(s->flags&CODEC_FLAG_EMU_EDGE){
                     if(src_x<0 || src_y<0 || src_x + (motion_x&3) + 8 > s->h_edge_pos
                                           || src_y + (motion_y&3) + 8 > s->v_edge_pos){
-                        emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+                        ff_emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
                         ptr= s->edge_emu_buffer;
                     }
                 }
@@ -1737,7 +1743,7 @@
                 if(s->flags&CODEC_FLAG_EMU_EDGE){
                     if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 8 > s->h_edge_pos
                                           || src_y + (motion_y&1) + 8 > s->v_edge_pos){
-                        emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+                        ff_emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
                         ptr= s->edge_emu_buffer;
                     }
                 }
@@ -1784,7 +1790,7 @@
         if(s->flags&CODEC_FLAG_EMU_EDGE){
                 if(src_x<0 || src_y<0 || src_x + (dxy &1) + 8 > s->h_edge_pos>>1
                                       || src_y + (dxy>>1) + 8 > s->v_edge_pos>>1){
-                    emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+                    ff_emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
                     ptr= s->edge_emu_buffer;
                     emu=1;
                 }
@@ -1793,7 +1799,7 @@
 
         ptr = ref_picture[2] + offset;
         if(emu){
-            emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+            ff_emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
             ptr= s->edge_emu_buffer;
         }
         pix_op[1][dxy](dest_cr, ptr, s->uvlinesize, 8);
@@ -1928,7 +1934,7 @@
 
     /* update motion predictor, not for B-frames as they need the motion_val from the last P/S-Frame */
     if (s->out_format == FMT_H263 && s->pict_type!=B_TYPE) { //FIXME move into h263.c if possible, format specific stuff shouldnt be here
-        
+        //FIXME a lot of thet is only needed for !low_delay
         const int wrap = s->block_wrap[0];
         const int xy = s->block_index[0];
         const int mb_index= s->mb_x + s->mb_y*s->mb_width;
@@ -2064,7 +2070,7 @@
                     add_dequant_dct(s, block[4], 4, dest_cb, s->uvlinesize);
                     add_dequant_dct(s, block[5], 5, dest_cr, s->uvlinesize);
                 }
-            } else {
+            } else if(s->codec_id != CODEC_ID_WMV2){
                 add_dct(s, block[0], 0, dest_y, dct_linesize);
                 add_dct(s, block[1], 1, dest_y + 8, dct_linesize);
                 add_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);
@@ -2074,6 +2080,8 @@
                     add_dct(s, block[4], 4, dest_cb, s->uvlinesize);
                     add_dct(s, block[5], 5, dest_cr, s->uvlinesize);
                 }
+            } else{
+                ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr);
             }
         } else {
             /* dct only in intra block */
@@ -2376,7 +2384,7 @@
         ptr = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
 
         if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
-            emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
+            ff_emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
             ptr= s->edge_emu_buffer;
             emu=1;
         }
@@ -2408,14 +2416,14 @@
             int wrap_c = s->uvlinesize;
             ptr = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
             if(emu){
-                emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
+                ff_emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
                 ptr= s->edge_emu_buffer;
             }
 	    s->dsp.get_pixels(s->block[4], ptr, wrap_c);
 
             ptr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
             if(emu){
-                emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
+                ff_emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
                 ptr= s->edge_emu_buffer;
             }
             s->dsp.get_pixels(s->block[5], ptr, wrap_c);
@@ -2455,7 +2463,7 @@
         }
 
         if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
-            emulated_edge_mc(s, ptr_y, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
+            ff_emulated_edge_mc(s, ptr_y, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
             ptr_y= s->edge_emu_buffer;
             emu=1;
         }
@@ -2487,12 +2495,12 @@
             skip_dct[5]= 1;
         }else{
             if(emu){
-                emulated_edge_mc(s, ptr_cb, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
+                ff_emulated_edge_mc(s, ptr_cb, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
                 ptr_cb= s->edge_emu_buffer;
             }
             s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c);
             if(emu){
-                emulated_edge_mc(s, ptr_cr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
+                ff_emulated_edge_mc(s, ptr_cr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
                 ptr_cr= s->edge_emu_buffer;
             }
             s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
@@ -2574,21 +2582,25 @@
 
 #ifdef CONFIG_ENCODERS
     /* huffman encode */
-    switch(s->out_format) {
-    case FMT_MPEG1:
-        mpeg1_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case FMT_H263:
-        if (s->h263_msmpeg4)
-            msmpeg4_encode_mb(s, s->block, motion_x, motion_y);
-        else if(s->h263_pred)
-            mpeg4_encode_mb(s, s->block, motion_x, motion_y);
-        else
-            h263_encode_mb(s, s->block, motion_x, motion_y);
-        break;
-    case FMT_MJPEG:
-        mjpeg_encode_mb(s, s->block);
-        break;
+    switch(s->codec_id){ //FIXME funct ptr could be slightly faster
+    case CODEC_ID_MPEG1VIDEO:
+        mpeg1_encode_mb(s, s->block, motion_x, motion_y); break;
+    case CODEC_ID_MPEG4:
+        mpeg4_encode_mb(s, s->block, motion_x, motion_y); break;
+    case CODEC_ID_MSMPEG4V2:
+    case CODEC_ID_MSMPEG4V3:
+    case CODEC_ID_WMV1:
+        msmpeg4_encode_mb(s, s->block, motion_x, motion_y); break;
+    case CODEC_ID_WMV2:
+         ff_wmv2_encode_mb(s, s->block, motion_x, motion_y); break;
+    case CODEC_ID_MJPEG:
+        mjpeg_encode_mb(s, s->block); break;
+    case CODEC_ID_H263:
+    case CODEC_ID_H263P:
+    case CODEC_ID_RV10:
+        h263_encode_mb(s, s->block, motion_x, motion_y); break;
+    default:
+        assert(0);
     }
 #endif
 }
@@ -2704,13 +2716,18 @@
     int x,y;
     
     if(w==16 && h==16) 
-        return s->dsp.pix_norm(src1, src2, stride);
+        return s->dsp.sse[0](NULL, src1, src2, stride);
+    else if(w==8 && h==8)
+        return s->dsp.sse[1](NULL, src1, src2, stride);
     
     for(y=0; y<h; y++){
         for(x=0; x<w; x++){
             acc+= sq[src1[x + y*stride] - src2[x + y*stride]];
         } 
     }
+    
+    assert(acc>=0);
+    
     return acc;
 }
 
@@ -2751,6 +2768,18 @@
     s->scene_change_score=0;
     
     s->qscale= (int)(s->frame_qscale + 0.5); //FIXME qscale / ... stuff for ME ratedistoration
+    
+    if(s->msmpeg4_version){
+        if(s->pict_type==I_TYPE)
+            s->no_rounding=1;
+        else if(s->flipflop_rounding)
+            s->no_rounding ^= 1;          
+    }else{
+        if(s->pict_type==I_TYPE)
+            s->no_rounding=0;
+        else if(s->pict_type!=B_TYPE)
+            s->no_rounding ^= 1;          
+    }
 
     /* Estimate motion for every MB */
     if(s->pict_type != I_TYPE){
@@ -2772,7 +2801,6 @@
                     ff_estimate_b_frame_motion(s, mb_x, mb_y);
                 else
                     ff_estimate_p_frame_motion(s, mb_x, mb_y);
-//                s->mb_type[mb_y*s->mb_width + mb_x]=MB_TYPE_INTER;
             }
         }
     }else /* if(s->pict_type == I_TYPE) */{
@@ -2867,7 +2895,9 @@
         mjpeg_picture_header(s);
         break;
     case FMT_H263:
-        if (s->h263_msmpeg4) 
+        if (s->codec_id == CODEC_ID_WMV2) 
+            ff_wmv2_encode_picture_header(s, picture_number);
+        else if (s->h263_msmpeg4) 
             msmpeg4_encode_picture_header(s, picture_number);
         else if (s->h263_pred)
             mpeg4_encode_picture_header(s, picture_number);
@@ -3049,15 +3079,14 @@
                                  &dmin, &next_block, 0, 0);
                 }
                 if(mb_type&MB_TYPE_DIRECT){
+                    int mx= s->b_direct_mv_table[xy][0];
+                    int my= s->b_direct_mv_table[xy][1];
+                    
                     s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
-                    s->mv_type = MV_TYPE_16X16; //FIXME
                     s->mb_intra= 0;
-                    s->mv[0][0][0] = s->b_direct_forw_mv_table[xy][0];
-                    s->mv[0][0][1] = s->b_direct_forw_mv_table[xy][1];
-                    s->mv[1][0][0] = s->b_direct_back_mv_table[xy][0];
-                    s->mv[1][0][1] = s->b_direct_back_mv_table[xy][1];
+                    ff_mpeg4_set_direct_mv(s, mx, my);
                     encode_mb_hq(s, &backup_s, &best_s, MB_TYPE_DIRECT, pb, pb2, tex_pb, 
-                                 &dmin, &next_block, s->b_direct_mv_table[xy][0], s->b_direct_mv_table[xy][1]);
+                                 &dmin, &next_block, mx, my);
                 }
                 if(mb_type&MB_TYPE_INTRA){
                     s->mv_dir = MV_DIR_FORWARD;
@@ -3122,10 +3151,7 @@
                     s->mb_intra= 0;
                     motion_x=s->b_direct_mv_table[xy][0];
                     motion_y=s->b_direct_mv_table[xy][1];
-                    s->mv[0][0][0] = s->b_direct_forw_mv_table[xy][0];
-                    s->mv[0][0][1] = s->b_direct_forw_mv_table[xy][1];
-                    s->mv[1][0][0] = s->b_direct_back_mv_table[xy][0];
-                    s->mv[1][0][1] = s->b_direct_back_mv_table[xy][1];
+                    ff_mpeg4_set_direct_mv(s, motion_x, motion_y);
                     break;
                 case MB_TYPE_BIDIR:
                     s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
@@ -3170,7 +3196,7 @@
 
                 if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
                 if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;
-                
+
                 s->current_picture.error[0] += sse(
                     s,
                     s->new_picture    .data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
@@ -3471,6 +3497,7 @@
     case P_TYPE: return 'P'; 
     case B_TYPE: return 'B'; 
     case S_TYPE: return 'S'; 
+    default:     return '?';
     }
 }
 
@@ -3574,12 +3601,3 @@
     MPV_encode_end,
 };
 
-AVCodec wmv2_encoder = {
-    "wmv2",
-    CODEC_TYPE_VIDEO,
-    CODEC_ID_WMV2,
-    sizeof(MpegEncContext),
-    MPV_encode_init,
-    MPV_encode_picture,
-    MPV_encode_end,
-};