[xiph-commits] r17416 - in experimental/derf/theora-ptalarbvorm/lib: . c64x x86 x86_vc

tterribe at svn.xiph.org tterribe at svn.xiph.org
Tue Sep 21 23:46:13 PDT 2010


Author: tterribe
Date: 2010-09-21 23:46:13 -0700 (Tue, 21 Sep 2010)
New Revision: 17416

Modified:
   experimental/derf/theora-ptalarbvorm/lib/analyze.c
   experimental/derf/theora-ptalarbvorm/lib/c64x/c64xfrag.c
   experimental/derf/theora-ptalarbvorm/lib/decode.c
   experimental/derf/theora-ptalarbvorm/lib/encode.c
   experimental/derf/theora-ptalarbvorm/lib/mcenc.c
   experimental/derf/theora-ptalarbvorm/lib/state.c
   experimental/derf/theora-ptalarbvorm/lib/state.h
   experimental/derf/theora-ptalarbvorm/lib/x86/mmxstate.c
   experimental/derf/theora-ptalarbvorm/lib/x86_vc/mmxstate.c
Log:
Replace the oc_mv typedef with an ogg_int16_t instead of a signed char[2].

Packing and unpacking of individual components is done manually.
This lets us copy and initialize MVs without using memcpy or memset, which gcc
 completely fails to inline on ARM.
This is good for a 0.5-1.5% speed-up in the decoder.


Modified: experimental/derf/theora-ptalarbvorm/lib/analyze.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/analyze.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/analyze.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -734,8 +734,8 @@
     default:{
       const oc_mv *frag_mvs;
       frag_mvs=(const oc_mv *)_enc->state.frag_mvs;
-      nmv_offs=oc_state_get_mv_offsets(&_enc->state,mv_offs,_pli,
-       frag_mvs[_fragi][0],frag_mvs[_fragi][1]);
+      nmv_offs=oc_state_get_mv_offsets(&_enc->state,mv_offs,
+       _pli,frag_mvs[_fragi]);
       if(nmv_offs>1){
         oc_enc_frag_copy2(_enc,dst,
          ref+mv_offs[0],ref+mv_offs[1],ystride);
@@ -1973,7 +1973,7 @@
        against the prior frame, penalize skipping.
       TODO: The factor of two here is a kludge, but it tested out better than a
        hard limit.*/
-    if(mvs[bi][0]!=0||mvs[bi][1]!=0)uncoded_ssd*=2;
+    if(mvs[bi]!=0)uncoded_ssd*=2;
     _pipe->skip_ssd[0][fragi-_pipe->froffset[0]]=_ssd[bi]=uncoded_ssd;
   }
   mb_map=(const oc_mb_map_plane *)_enc->state.mb_maps[_mbi];
@@ -2003,7 +2003,7 @@
          against the prior frame, penalize skipping.
         TODO: The factor of two here is a kludge, but it tested out better than
          a hard limit*/
-      if(mvs[OC_FRAME_PREV][0]!=0||mvs[OC_FRAME_PREV][1]!=0)uncoded_ssd*=2;
+      if(mvs[OC_FRAME_PREV]!=0)uncoded_ssd*=2;
       _pipe->skip_ssd[pli][fragi-_pipe->froffset[pli]]=_ssd[mapii]=uncoded_ssd;
     }
     map_nidxs=(map_nidxs-4<<1)+4;
@@ -2024,9 +2024,9 @@
 }
 
 static void oc_cost_inter(oc_enc_ctx *_enc,oc_mode_choice *_modec,
- unsigned _mbi,int _mb_mode,const signed char *_mv,
- const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12],
- const unsigned _rd_scale[5]){
+ unsigned _mbi,int _mb_mode,oc_mv _mv,
+ const oc_fr_state *_fr,const oc_qii_state *_qs,
+ const unsigned _skip_ssd[12],const unsigned _rd_scale[5]){
   unsigned               frag_satd[12];
   const unsigned char   *src;
   const unsigned char   *ref;
@@ -2039,8 +2039,6 @@
   int                    mapii;
   int                    mapi;
   int                    mv_offs[2];
-  int                    dx;
-  int                    dy;
   int                    pli;
   int                    bi;
   ptrdiff_t              fragi;
@@ -2052,10 +2050,8 @@
   ystride=_enc->state.ref_ystride[0];
   frag_buf_offs=_enc->state.frag_buf_offs;
   sb_map=_enc->state.sb_maps[_mbi>>2][_mbi&3];
-  dx=_mv[0];
-  dy=_mv[1];
   _modec->rate=_modec->ssd=0;
-  if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,dx,dy)>1){
+  if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,_mv)>1){
     for(bi=0;bi<4;bi++){
       fragi=sb_map[bi];
       frag_offs=frag_buf_offs[fragi];
@@ -2078,7 +2074,7 @@
   map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt];
   /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/
   ystride=_enc->state.ref_ystride[1];
-  if(oc_state_get_mv_offsets(&_enc->state,mv_offs,1,dx,dy)>1){
+  if(oc_state_get_mv_offsets(&_enc->state,mv_offs,1,_mv)>1){
     for(mapii=4;mapii<map_nidxs;mapii++){
       mapi=map_idxs[mapii];
       pli=mapi>>2;
@@ -2113,18 +2109,16 @@
 static void oc_cost_inter_nomv(oc_enc_ctx *_enc,oc_mode_choice *_modec,
  unsigned _mbi,int _mb_mode,const oc_fr_state *_fr,const oc_qii_state *_qs,
  const unsigned _skip_ssd[12],const unsigned _rd_scale[4]){
-  static const oc_mv OC_MV_ZERO;
-  oc_cost_inter(_enc,_modec,_mbi,_mb_mode,OC_MV_ZERO,
-   _fr,_qs,_skip_ssd,_rd_scale);
+  oc_cost_inter(_enc,_modec,_mbi,_mb_mode,0,_fr,_qs,_skip_ssd,_rd_scale);
 }
 
 static int oc_cost_inter1mv(oc_enc_ctx *_enc,oc_mode_choice *_modec,
- unsigned _mbi,int _mb_mode,const signed char *_mv,
+ unsigned _mbi,int _mb_mode,oc_mv _mv,
  const oc_fr_state *_fr,const oc_qii_state *_qs,const unsigned _skip_ssd[12],
  const unsigned _rd_scale[4]){
   int bits0;
   oc_cost_inter(_enc,_modec,_mbi,_mb_mode,_mv,_fr,_qs,_skip_ssd,_rd_scale);
-  bits0=OC_MV_BITS[0][_mv[0]+31]+OC_MV_BITS[0][_mv[1]+31];
+  bits0=OC_MV_BITS[0][OC_MV_X(_mv)+31]+OC_MV_BITS[0][OC_MV_Y(_mv)+31];
   _modec->overhead+=OC_MINI(_enc->mv_bits[0]+bits0,_enc->mv_bits[1]+12)
    -OC_MINI(_enc->mv_bits[0],_enc->mv_bits[1])<<OC_BIT_SCALE;
   oc_mode_set_cost(_modec,_enc->lambda);
@@ -2154,8 +2148,6 @@
   int                    mapii;
   int                    mapi;
   int                    mv_offs[2];
-  int                    dx;
-  int                    dy;
   int                    pli;
   int                    bi;
   ptrdiff_t              fragi;
@@ -2173,14 +2165,11 @@
   _modec->rate=_modec->ssd=0;
   for(bi=0;bi<4;bi++){
     fragi=mb_map[0][bi];
-    dx=_mv[bi][0];
-    dy=_mv[bi][1];
     /*Save the block MVs as the current ones while we're here; we'll replace
        them if we don't ultimately choose 4MV mode.*/
-    frag_mvs[fragi][0]=(signed char)dx;
-    frag_mvs[fragi][1]=(signed char)dy;
+    frag_mvs[fragi]=_mv[bi];
     frag_offs=frag_buf_offs[fragi];
-    if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,dx,dy)>1){
+    if(oc_state_get_mv_offsets(&_enc->state,mv_offs,0,_mv[bi])>1){
       satd=oc_enc_frag_satd2(_enc,&dc,src+frag_offs,
        ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride);
     }
@@ -2197,17 +2186,15 @@
   bits1=0;
   nqis=_enc->state.nqis;
   for(bi=0;bi<4;bi++){
-    if(_modec->qii[OC_MB_PHASE[_mbi&3][bi]]>=nqis){
-      memset(lbmvs+bi,0,sizeof(*lbmvs));
-    }
+    if(_modec->qii[OC_MB_PHASE[_mbi&3][bi]]>=nqis)lbmvs[bi]=0;
     else{
-      memcpy(lbmvs+bi,_mv+bi,sizeof(*lbmvs));
-      bits0+=OC_MV_BITS[0][_mv[bi][0]+31]+OC_MV_BITS[0][_mv[bi][1]+31];
+      lbmvs[bi]=_mv[bi];
+      bits0+=OC_MV_BITS[0][OC_MV_X(_mv[bi])+31]
+       +OC_MV_BITS[0][OC_MV_Y(_mv[bi])+31];
       bits1+=12;
     }
   }
-  (*OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt])(cbmvs,
-   (const oc_mv *)lbmvs);
+  (*OC_SET_CHROMA_MVS_TABLE[_enc->state.info.pixel_fmt])(cbmvs,lbmvs);
   map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt];
   map_nidxs=OC_MB_MAP_NIDXS[_enc->state.info.pixel_fmt];
   /*Note: This assumes ref_ystride[1]==ref_ystride[2].*/
@@ -2217,12 +2204,10 @@
     pli=mapi>>2;
     bi=mapi&3;
     fragi=mb_map[pli][bi];
-    dx=cbmvs[bi][0];
-    dy=cbmvs[bi][1];
     frag_offs=frag_buf_offs[fragi];
     /*TODO: We could save half these calls by re-using the results for the Cb
        and Cr planes; is it worth it?*/
-    if(oc_state_get_mv_offsets(&_enc->state,mv_offs,pli,dx,dy)>1){
+    if(oc_state_get_mv_offsets(&_enc->state,mv_offs,pli,cbmvs[bi])>1){
       satd=oc_enc_frag_satd2(_enc,&dc,src+frag_offs,
        ref+frag_offs+mv_offs[0],ref+frag_offs+mv_offs[1],ystride);
     }
@@ -2293,7 +2278,7 @@
   chroma_rd_scale=_enc->chroma_rd_scale[OC_INTER_FRAME][_enc->state.qis[0]];
   mcu_rd_scale=_enc->mcu_rd_scale;
   mcu_rd_iscale=_enc->mcu_rd_iscale;
-  last_mv[0]=last_mv[1]=prior_mv[0]=prior_mv[1]=0;
+  last_mv=prior_mv=0;
   /*Choose MVs and MB modes and quantize and code luma.
     Must be done in Hilbert order.*/
   map_idxs=OC_MB_MAP_IDXS[_enc->state.info.pixel_fmt];
@@ -2335,8 +2320,7 @@
         int            mb_gmv_bits_0;
         int            inter_mv_pref;
         int            mb_mode;
-        int            dx;
-        int            dy;
+        int            mv;
         unsigned       mbi;
         int            mapii;
         int            mapi;
@@ -2358,7 +2342,7 @@
           We always do a basic 1MV search for all macroblocks, coded or not,
            keyframe or not.*/
         if(!_recode&&sp_level<OC_SP_LEVEL_NOMC)oc_mcenc_search(_enc,mbi);
-        dx=dy=0;
+        mv=0;
         /*Find the block choice with the lowest estimated coding cost.
           If a Cb or Cr block is coded but no Y' block from a macro block then
            the mode MUST be OC_MODE_INTER_NOMV.
@@ -2367,8 +2351,10 @@
         /*Block coding cost is estimated from correlated SATD metrics.*/
         /*At this point, all blocks that are in frame are still marked coded.*/
         if(!_recode){
-          memcpy(embs[mbi].unref_mv,
-           embs[mbi].analysis_mv[0],sizeof(embs[mbi].unref_mv));
+          embs[mbi].unref_mv[OC_FRAME_GOLD]=
+           embs[mbi].analysis_mv[0][OC_FRAME_GOLD];
+          embs[mbi].unref_mv[OC_FRAME_PREV]=
+           embs[mbi].analysis_mv[0][OC_FRAME_PREV];
           embs[mbi].refined=0;
         }
         /*Estimate the cost of coding this MB in a keyframe.*/
@@ -2497,26 +2483,17 @@
         if(mb_mode!=OC_MODE_INTER_MV_FOUR){
           switch(mb_mode){
             case OC_MODE_INTER_MV:{
-              dx=embs[mbi].analysis_mv[0][OC_FRAME_PREV][0];
-              dy=embs[mbi].analysis_mv[0][OC_FRAME_PREV][1];
+              mv=embs[mbi].analysis_mv[0][OC_FRAME_PREV];
             }break;
-            case OC_MODE_INTER_MV_LAST:{
-              dx=last_mv[0];
-              dy=last_mv[1];
-            }break;
-            case OC_MODE_INTER_MV_LAST2:{
-              dx=prior_mv[0];
-              dy=prior_mv[1];
-            }break;
+            case OC_MODE_INTER_MV_LAST:mv=last_mv;break;
+            case OC_MODE_INTER_MV_LAST2:mv=prior_mv;break;
             case OC_MODE_GOLDEN_MV:{
-              dx=embs[mbi].analysis_mv[0][OC_FRAME_GOLD][0];
-              dy=embs[mbi].analysis_mv[0][OC_FRAME_GOLD][1];
+              mv=embs[mbi].analysis_mv[0][OC_FRAME_GOLD];
             }break;
           }
           for(bi=0;bi<4;bi++){
             fragi=mb_maps[mbi][0][bi];
-            frag_mvs[fragi][0]=(signed char)dx;
-            frag_mvs[fragi][1]=(signed char)dy;
+            frag_mvs[fragi]=mv;
           }
         }
         for(bi=0;bi<4;bi++){
@@ -2530,34 +2507,30 @@
           mb_mode=mb_modes[mbi];
           switch(mb_mode){
             case OC_MODE_INTER_MV:{
-              memcpy(prior_mv,last_mv,sizeof(prior_mv));
+              prior_mv=last_mv;
               /*If we're backing out from 4MV, find the MV we're actually
                  using.*/
               if(orig_mb_mode==OC_MODE_INTER_MV_FOUR){
                 for(bi=0;;bi++){
                   fragi=mb_maps[mbi][0][bi];
                   if(frags[fragi].coded){
-                    memcpy(last_mv,frag_mvs[fragi],sizeof(last_mv));
-                    dx=frag_mvs[fragi][0];
-                    dy=frag_mvs[fragi][1];
+                    mv=last_mv=frag_mvs[fragi];
                     break;
                   }
                 }
-                mb_mv_bits_0=OC_MV_BITS[0][dx+31]+OC_MV_BITS[0][dy+31];
+                mb_mv_bits_0=OC_MV_BITS[0][OC_MV_X(mv)+31]
+                 +OC_MV_BITS[0][OC_MV_Y(mv)+31];
               }
               /*Otherwise we used the original analysis MV.*/
-              else{
-                memcpy(last_mv,
-                 embs[mbi].analysis_mv[0][OC_FRAME_PREV],sizeof(last_mv));
-              }
+              else last_mv=embs[mbi].analysis_mv[0][OC_FRAME_PREV];
               _enc->mv_bits[0]+=mb_mv_bits_0;
               _enc->mv_bits[1]+=12;
             }break;
             case OC_MODE_INTER_MV_LAST2:{
               oc_mv tmp_mv;
-              memcpy(tmp_mv,prior_mv,sizeof(tmp_mv));
-              memcpy(prior_mv,last_mv,sizeof(prior_mv));
-              memcpy(last_mv,tmp_mv,sizeof(last_mv));
+              tmp_mv=prior_mv;
+              prior_mv=last_mv;
+              last_mv=tmp_mv;
             }break;
             case OC_MODE_GOLDEN_MV:{
               _enc->mv_bits[0]+=mb_gmv_bits_0;
@@ -2566,20 +2539,19 @@
             case OC_MODE_INTER_MV_FOUR:{
               oc_mv lbmvs[4];
               oc_mv cbmvs[4];
-              memcpy(prior_mv,last_mv,sizeof(prior_mv));
+              prior_mv=last_mv;
               for(bi=0;bi<4;bi++){
                 fragi=mb_maps[mbi][0][bi];
                 if(frags[fragi].coded){
-                  memcpy(last_mv,frag_mvs[fragi],sizeof(last_mv));
-                  memcpy(lbmvs[bi],frag_mvs[fragi],sizeof(lbmvs[bi]));
-                  _enc->mv_bits[0]+=OC_MV_BITS[0][frag_mvs[fragi][0]+31]
-                   +OC_MV_BITS[0][frag_mvs[fragi][1]+31];
+                  lbmvs[bi]=last_mv=frag_mvs[fragi];
+                  _enc->mv_bits[0]+=OC_MV_BITS[0][OC_MV_X(last_mv)+31]
+                   +OC_MV_BITS[0][OC_MV_Y(last_mv)+31];
                   _enc->mv_bits[1]+=12;
                 }
                 /*Replace the block MVs for not-coded blocks with (0,0).*/
-                else memset(lbmvs[bi],0,sizeof(lbmvs[bi]));
+                else lbmvs[bi]=0;
               }
-              (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
+              (*set_chroma_mvs)(cbmvs,lbmvs);
               for(mapii=4;mapii<nmap_idxs;mapii++){
                 mapi=map_idxs[mapii];
                 pli=mapi>>2;
@@ -2587,7 +2559,7 @@
                 fragi=mb_maps[mbi][pli][bi];
                 frags[fragi].mb_mode=mb_mode;
                 frags[fragi].qii=modes[OC_MODE_INTER_MV_FOUR].qii[mapii];
-                memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(frag_mvs[fragi]));
+                frag_mvs[fragi]=cbmvs[bi];
               }
             }break;
           }
@@ -2598,7 +2570,7 @@
         else{
           *(uncoded_mbis-++nuncoded_mbis)=mbi;
           mb_mode=OC_MODE_INTER_NOMV;
-          dx=dy=0;
+          mv=0;
         }
         /*Propagate final MB mode and MVs to the chroma blocks.
           This has already been done for 4MV mode, since it requires individual
@@ -2614,8 +2586,7 @@
                values won't have been chosen with the right MV, but it's
                probaby not worth re-estimating them.*/
             frags[fragi].qii=modes[mb_mode].qii[mapii];
-            frag_mvs[fragi][0]=(signed char)dx;
-            frag_mvs[fragi][1]=(signed char)dy;
+            frag_mvs[fragi]=mv;
           }
         }
         /*Save masking scale factors for chroma blocks.*/

Modified: experimental/derf/theora-ptalarbvorm/lib/c64x/c64xfrag.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/c64x/c64xfrag.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/c64x/c64xfrag.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -201,7 +201,7 @@
      _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]]
      +frag_buf_off;
     if(oc_state_get_mv_offsets(_state,mvoffsets,_pli,
-     _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){
+     _state->frag_mvs[_fragi])>1){
       oc_frag_recon_inter2_c64x(dst,ref+mvoffsets[0],ref+mvoffsets[1],
        ystride,_dct_coeffs+64);
     }

Modified: experimental/derf/theora-ptalarbvorm/lib/decode.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/decode.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/decode.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -795,9 +795,12 @@
 };
 
 
-static void oc_mv_unpack(oc_pack_buf *_opb,const ogg_int16_t *_tree,oc_mv _mv){
-  _mv[0]=(signed char)(oc_huff_token_decode(_opb,_tree)-32);
-  _mv[1]=(signed char)(oc_huff_token_decode(_opb,_tree)-32);
+static oc_mv oc_mv_unpack(oc_pack_buf *_opb,const ogg_int16_t *_tree){
+  int dx;
+  int dy;
+  dx=oc_huff_token_decode(_opb,_tree)-32;
+  dy=oc_huff_token_decode(_opb,_tree)-32;
+  return OC_MV(dx,dy);
 }
 
 /*Unpacks the list of motion vectors for INTER frames, and propagtes the macro
@@ -811,7 +814,8 @@
   oc_mv                  *frag_mvs;
   const unsigned char    *map_idxs;
   int                     map_nidxs;
-  oc_mv                   last_mv[2];
+  oc_mv                   last_mv;
+  oc_mv                   prior_mv;
   oc_mv                   cbmvs[4];
   size_t                  nmbs;
   size_t                  mbi;
@@ -821,7 +825,7 @@
   mv_comp_tree=val?OC_CLC_MV_COMP_TREE:OC_VLC_MV_COMP_TREE;
   map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt];
   map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt];
-  memset(last_mv,0,sizeof(last_mv));
+  prior_mv=last_mv=0;
   frags=_dec->state.frags;
   frag_mvs=_dec->state.frag_mvs;
   mb_maps=(const oc_mb_map *)_dec->state.mb_maps;
@@ -858,41 +862,40 @@
               codedi++;
               fragi=mb_maps[mbi][0][bi];
               frags[fragi].mb_mode=mb_mode;
-              oc_mv_unpack(&_dec->opb,mv_comp_tree,lbmvs[bi]);
-              memcpy(frag_mvs[fragi],lbmvs[bi],sizeof(lbmvs[bi]));
+              lbmvs[bi]=oc_mv_unpack(&_dec->opb,mv_comp_tree);
+              frag_mvs[fragi]=lbmvs[bi];
             }
-            else lbmvs[bi][0]=lbmvs[bi][1]=0;
+            else lbmvs[bi]=0;
           }
           if(codedi>0){
-            memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1]));
-            memcpy(last_mv[0],lbmvs[coded[codedi-1]],sizeof(last_mv[0]));
+            prior_mv=last_mv;
+            last_mv=lbmvs[coded[codedi-1]];
           }
           if(codedi<ncoded){
-            (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
+            (*set_chroma_mvs)(cbmvs,lbmvs);
             for(;codedi<ncoded;codedi++){
               mapi=coded[codedi];
               bi=mapi&3;
               fragi=mb_maps[mbi][mapi>>2][bi];
               frags[fragi].mb_mode=mb_mode;
-              memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(cbmvs[bi]));
+              frag_mvs[fragi]=cbmvs[bi];
             }
           }
         }break;
         case OC_MODE_INTER_MV:{
-          memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1]));
-          oc_mv_unpack(&_dec->opb,mv_comp_tree,mbmv);
-          memcpy(last_mv[0],mbmv,sizeof(last_mv[0]));
+          prior_mv=last_mv;
+          last_mv=mbmv=oc_mv_unpack(&_dec->opb,mv_comp_tree);
         }break;
-        case OC_MODE_INTER_MV_LAST:memcpy(mbmv,last_mv[0],sizeof(mbmv));break;
+        case OC_MODE_INTER_MV_LAST:mbmv=last_mv;break;
         case OC_MODE_INTER_MV_LAST2:{
-          memcpy(mbmv,last_mv[1],sizeof(mbmv));
-          memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1]));
-          memcpy(last_mv[0],mbmv,sizeof(last_mv[0]));
+          mbmv=prior_mv;
+          prior_mv=last_mv;
+          last_mv=mbmv;
         }break;
         case OC_MODE_GOLDEN_MV:{
-          oc_mv_unpack(&_dec->opb,mv_comp_tree,mbmv);
+          mbmv=oc_mv_unpack(&_dec->opb,mv_comp_tree);
         }break;
-        default:memset(mbmv,0,sizeof(mbmv));break;
+        default:mbmv=0;break;
       }
       /*4MV mode fills in the fragments itself.
         For all other modes we can use this common code.*/
@@ -901,7 +904,7 @@
           mapi=coded[codedi];
           fragi=mb_maps[mbi][mapi>>2][mapi&3];
           frags[fragi].mb_mode=mb_mode;
-          memcpy(frag_mvs[fragi],mbmv,sizeof(mbmv));
+          frag_mvs[fragi]=mbmv;
         }
       }
     }
@@ -2442,12 +2445,14 @@
           }
         }
         else{
-          const signed char *frag_mv;
-          ptrdiff_t          fragi;
+          ptrdiff_t fragi;
+          int       frag_mvx;
+          int       frag_mvy;
           for(bi=0;bi<4;bi++){
             fragi=mb_maps[mbi][0][bi];
             if(fragi>=0&&frags[fragi].coded){
-              frag_mv=frag_mvs[fragi];
+              frag_mvx=OC_MV_X(frag_mvs[fragi]);
+              frag_mvy=OC_MV_Y(frag_mvs[fragi]);
               break;
             }
           }
@@ -2478,13 +2483,13 @@
                   cairo_stroke(c);
                 }
                 if(_dec->telemetry_mv&0x04){
-                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+8,y+8);
@@ -2501,13 +2506,13 @@
                   cairo_stroke(c);
                 }
                 if(_dec->telemetry_mv&0x08){
-                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+8,y+8);
@@ -2527,13 +2532,13 @@
                   cairo_stroke(c);
                 }
                 if(_dec->telemetry_mv&0x10){
-                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+8,y+8);
@@ -2556,13 +2561,13 @@
                   cairo_stroke(c);
                 }
                 if(_dec->telemetry_mv&0x40){
-                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_move_to(c,x+8+frag_mvx,y+8-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+8,y+8);
@@ -2581,14 +2586,15 @@
                 /*4mv is odd, coded in raster order.*/
                 fragi=mb_maps[mbi][0][0];
                 if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
-                  frag_mv=frag_mvs[fragi];
-                  cairo_move_to(c,x+4+frag_mv[0],y+12-frag_mv[1]);
+                  frag_mvx=OC_MV_X(frag_mvs[fragi]);
+                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                  cairo_move_to(c,x+4+frag_mvx,y+12-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+4+frag_mv[0]*.66,y+12-frag_mv[1]*.66);
+                  cairo_line_to(c,x+4+frag_mvx*.66,y+12-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+4+frag_mv[0]*.33,y+12-frag_mv[1]*.33);
+                  cairo_line_to(c,x+4+frag_mvx*.33,y+12-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+4,y+12);
@@ -2596,14 +2602,15 @@
                 }
                 fragi=mb_maps[mbi][0][1];
                 if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
-                  frag_mv=frag_mvs[fragi];
-                  cairo_move_to(c,x+12+frag_mv[0],y+12-frag_mv[1]);
+                  frag_mvx=OC_MV_X(frag_mvs[fragi]);
+                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                  cairo_move_to(c,x+12+frag_mvx,y+12-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+12+frag_mv[0]*.66,y+12-frag_mv[1]*.66);
+                  cairo_line_to(c,x+12+frag_mvx*.66,y+12-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+12+frag_mv[0]*.33,y+12-frag_mv[1]*.33);
+                  cairo_line_to(c,x+12+frag_mvx*.33,y+12-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+12,y+12);
@@ -2611,14 +2618,15 @@
                 }
                 fragi=mb_maps[mbi][0][2];
                 if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
-                  frag_mv=frag_mvs[fragi];
-                  cairo_move_to(c,x+4+frag_mv[0],y+4-frag_mv[1]);
+                  frag_mvx=OC_MV_X(frag_mvs[fragi]);
+                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                  cairo_move_to(c,x+4+frag_mvx,y+4-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+4+frag_mv[0]*.66,y+4-frag_mv[1]*.66);
+                  cairo_line_to(c,x+4+frag_mvx*.66,y+4-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+4+frag_mv[0]*.33,y+4-frag_mv[1]*.33);
+                  cairo_line_to(c,x+4+frag_mvx*.33,y+4-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+4,y+4);
@@ -2626,14 +2634,15 @@
                 }
                 fragi=mb_maps[mbi][0][3];
                 if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
-                  frag_mv=frag_mvs[fragi];
-                  cairo_move_to(c,x+12+frag_mv[0],y+4-frag_mv[1]);
+                  frag_mvx=OC_MV_X(frag_mvs[fragi]);
+                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                  cairo_move_to(c,x+12+frag_mvx,y+4-frag_mvy);
                   cairo_set_source_rgba(c,1.,1.,1.,.9);
                   cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+12+frag_mv[0]*.66,y+4-frag_mv[1]*.66);
+                  cairo_line_to(c,x+12+frag_mvx*.66,y+4-frag_mvy*.66);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+12+frag_mv[0]*.33,y+4-frag_mv[1]*.33);
+                  cairo_line_to(c,x+12+frag_mvx*.33,y+4-frag_mvy*.33);
                   cairo_stroke_preserve(c);
                   cairo_set_line_width(c,1.);
                   cairo_line_to(c,x+12,y+4);

Modified: experimental/derf/theora-ptalarbvorm/lib/encode.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/encode.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/encode.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -621,11 +621,15 @@
   }
 }
 
-static void oc_enc_mv_pack(oc_enc_ctx *_enc,int _mv_scheme,int _dx,int _dy){
+static void oc_enc_mv_pack(oc_enc_ctx *_enc,int _mv_scheme,oc_mv _mv){
+  int dx;
+  int dy;
+  dx=OC_MV_X(_mv);
+  dy=OC_MV_Y(_mv);
   oggpackB_write(&_enc->opb,
-   OC_MV_CODES[_mv_scheme][_dx+31],OC_MV_BITS[_mv_scheme][_dx+31]);
+   OC_MV_CODES[_mv_scheme][dx+31],OC_MV_BITS[_mv_scheme][dx+31]);
   oggpackB_write(&_enc->opb,
-   OC_MV_CODES[_mv_scheme][_dy+31],OC_MV_BITS[_mv_scheme][_dy+31]);
+   OC_MV_CODES[_mv_scheme][dy+31],OC_MV_BITS[_mv_scheme][dy+31]);
 }
 
 static void oc_enc_mvs_pack(oc_enc_ctx *_enc){
@@ -648,7 +652,7 @@
   mb_modes=_enc->state.mb_modes;
   mb_maps=(const oc_mb_map *)_enc->state.mb_maps;
   frags=_enc->state.frags;
-  frag_mvs=(const oc_mv *)_enc->state.frag_mvs;
+  frag_mvs=_enc->state.frag_mvs;
   for(mbii=0;mbii<ncoded_mbis;mbii++){
     ptrdiff_t fragi;
     unsigned  mbi;
@@ -660,8 +664,7 @@
         for(bi=0;;bi++){
           fragi=mb_maps[mbi][0][bi];
           if(frags[fragi].coded){
-            oc_enc_mv_pack(_enc,mv_scheme,
-             frag_mvs[fragi][0],frag_mvs[fragi][1]);
+            oc_enc_mv_pack(_enc,mv_scheme,frag_mvs[fragi]);
             /*Only code a single MV for this macro block.*/
             break;
           }
@@ -671,8 +674,7 @@
         for(bi=0;bi<4;bi++){
           fragi=mb_maps[mbi][0][bi];
           if(frags[fragi].coded){
-            oc_enc_mv_pack(_enc,mv_scheme,
-             frag_mvs[fragi][0],frag_mvs[fragi][1]);
+            oc_enc_mv_pack(_enc,mv_scheme,frag_mvs[fragi]);
             /*Keep coding all the MVs for this macro block.*/
           }
         }

Modified: experimental/derf/theora-ptalarbvorm/lib/mcenc.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/mcenc.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/mcenc.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -89,8 +89,10 @@
 
 
 static void oc_mcenc_find_candidates(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc,
- int _accum[2],int _mbi,int _frame){
+ oc_mv _accum,int _mbi,int _frame){
   oc_mb_enc_info *embs;
+  int             accum_x;
+  int             accum_y;
   int             a[3][2];
   int             ncandidates;
   unsigned        nmbi;
@@ -102,20 +104,24 @@
     /*Fill in the first part of set A: the vectors from adjacent blocks.*/
     for(i=0;i<embs[_mbi].ncneighbors;i++){
       nmbi=embs[_mbi].cneighbors[i];
-      _mcenc->candidates[ncandidates][0]=embs[nmbi].analysis_mv[0][_frame][0];
-      _mcenc->candidates[ncandidates][1]=embs[nmbi].analysis_mv[0][_frame][1];
+      _mcenc->candidates[ncandidates][0]=
+       OC_MV_X(embs[nmbi].analysis_mv[0][_frame]);
+      _mcenc->candidates[ncandidates][1]=
+       OC_MV_Y(embs[nmbi].analysis_mv[0][_frame]);
       ncandidates++;
     }
   }
+  accum_x=OC_MV_X(_accum);
+  accum_y=OC_MV_Y(_accum);
   /*Add a few additional vectors to set A: the vectors used in the previous
      frames and the (0,0) vector.*/
-  _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,_accum[0],31);
-  _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,_accum[1],31);
+  _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,accum_x,31);
+  _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,accum_y,31);
   ncandidates++;
   _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,
-   embs[_mbi].analysis_mv[1][_frame][0]+_accum[0],31);
+   OC_MV_X(embs[_mbi].analysis_mv[1][_frame])+accum_x,31);
   _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,
-   embs[_mbi].analysis_mv[1][_frame][1]+_accum[1],31);
+   OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])+accum_y,31);
   ncandidates++;
   _mcenc->candidates[ncandidates][0]=0;
   _mcenc->candidates[ncandidates][1]=0;
@@ -137,11 +143,11 @@
   nmbi=_mbi;
   for(i=0;;i++){
     _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,
-     2*embs[_mbi].analysis_mv[1][_frame][0]
-     -embs[_mbi].analysis_mv[2][_frame][0]+_accum[0],31);
+     2*OC_MV_X(embs[_mbi].analysis_mv[1][_frame])
+     -OC_MV_X(embs[_mbi].analysis_mv[2][_frame])+accum_x,31);
     _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,
-     2*embs[_mbi].analysis_mv[1][_frame][1]
-     -embs[_mbi].analysis_mv[2][_frame][1]+_accum[1],31);
+     2*OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])
+     -OC_MV_Y(embs[_mbi].analysis_mv[2][_frame])+accum_y,31);
     ncandidates++;
     if(i>=embs[_mbi].npneighbors)break;
     nmbi=embs[_mbi].pneighbors[i];
@@ -252,7 +258,7 @@
                 either OC_FRAME_PREV or OC_FRAME_GOLD.
   _frame_full: The frame to perform the 1px search on, one of OC_FRAME_PREV,
                 OC_FRAME_GOLD, OC_FRAME_PREV_ORIG, or OC_FRAME_GOLD_ORIG.*/
-void oc_mcenc_search_frame(oc_enc_ctx *_enc,int _accum[2],int _mbi,int _frame,
+void oc_mcenc_search_frame(oc_enc_ctx *_enc,oc_mv _accum,int _mbi,int _frame,
  int _frame_full){
   /*Note: Traditionally this search is done using a rate-distortion objective
      function of the form D+lambda*R.
@@ -488,57 +494,49 @@
   candy=best_vec[1];
   embs[_mbi].satd[_frame]=oc_mcenc_ysatd_check_mbcandidate_fullpel(_enc,
    frag_buf_offs,fragis,candx,candy,src,satd_ref,ystride);
-  embs[_mbi].analysis_mv[0][_frame][0]=(signed char)(candx<<1);
-  embs[_mbi].analysis_mv[0][_frame][1]=(signed char)(candy<<1);
+  embs[_mbi].analysis_mv[0][_frame]=OC_MV(candx<<1,candy<<1);
   if(_frame==OC_FRAME_PREV){
     for(bi=0;bi<4;bi++){
       candx=best_block_vec[bi][0];
       candy=best_block_vec[bi][1];
       embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_check_bcandidate_fullpel(_enc,
        frag_buf_offs[fragis[bi]],candx,candy,src,satd_ref,ystride);
-      embs[_mbi].block_mv[bi][0]=(signed char)(candx<<1);
-      embs[_mbi].block_mv[bi][1]=(signed char)(candy<<1);
+      embs[_mbi].block_mv[bi]=OC_MV(candx<<1,candy<<1);
     }
   }
 }
 
 void oc_mcenc_search(oc_enc_ctx *_enc,int _mbi){
-  oc_mv2         *mvs;
-  int             accum_p[2];
-  int             accum_g[2];
+  oc_mv2 *mvs;
+  oc_mv   accum_p;
+  oc_mv   accum_g;
+  oc_mv   mv2_p;
   mvs=_enc->mb_info[_mbi].analysis_mv;
-  if(_enc->prevframe_dropped){
-    accum_p[0]=mvs[0][OC_FRAME_PREV][0];
-    accum_p[1]=mvs[0][OC_FRAME_PREV][1];
-  }
-  else accum_p[1]=accum_p[0]=0;
-  accum_g[0]=mvs[2][OC_FRAME_GOLD][0];
-  accum_g[1]=mvs[2][OC_FRAME_GOLD][1];
-  mvs[0][OC_FRAME_PREV][0]-=mvs[2][OC_FRAME_PREV][0];
-  mvs[0][OC_FRAME_PREV][1]-=mvs[2][OC_FRAME_PREV][1];
+  if(_enc->prevframe_dropped)accum_p=mvs[0][OC_FRAME_PREV];
+  else accum_p=0;
+  accum_g=mvs[2][OC_FRAME_GOLD];
   /*Move the motion vector predictors back a frame.*/
-  memmove(mvs+1,mvs,2*sizeof(*mvs));
+  mv2_p=mvs[2][OC_FRAME_PREV];
+  mvs[2][OC_FRAME_GOLD]=mvs[1][OC_FRAME_GOLD];
+  mvs[2][OC_FRAME_PREV]=mvs[1][OC_FRAME_PREV];
+  mvs[1][OC_FRAME_GOLD]=mvs[0][OC_FRAME_GOLD];
+  mvs[1][OC_FRAME_PREV]=OC_MV_SUB(mvs[0][OC_FRAME_PREV],mv2_p);
   /*Search the last frame.*/
   oc_mcenc_search_frame(_enc,accum_p,_mbi,OC_FRAME_PREV,OC_FRAME_PREV_ORIG);
-  mvs[2][OC_FRAME_PREV][0]=accum_p[0];
-  mvs[2][OC_FRAME_PREV][1]=accum_p[1];
+  mvs[2][OC_FRAME_PREV]=accum_p;
   /*GOLDEN MVs are different from PREV MVs in that they're each absolute
      offsets from some frame in the past rather than relative offsets from the
      frame before.
     For predictor calculation to make sense, we need them to be in the same
      form as PREV MVs.*/
-  mvs[1][OC_FRAME_GOLD][0]-=mvs[2][OC_FRAME_GOLD][0];
-  mvs[1][OC_FRAME_GOLD][1]-=mvs[2][OC_FRAME_GOLD][1];
-  mvs[2][OC_FRAME_GOLD][0]-=accum_g[0];
-  mvs[2][OC_FRAME_GOLD][1]-=accum_g[1];
+  mvs[1][OC_FRAME_GOLD]=OC_MV_SUB(mvs[1][OC_FRAME_GOLD],mvs[2][OC_FRAME_GOLD]);
+  mvs[2][OC_FRAME_GOLD]=OC_MV_SUB(mvs[2][OC_FRAME_GOLD],accum_g);
   /*Search the golden frame.*/
   oc_mcenc_search_frame(_enc,accum_g,_mbi,OC_FRAME_GOLD,OC_FRAME_GOLD_ORIG);
   /*Put GOLDEN MVs back into absolute offset form.
     The newest MV is already an absolute offset.*/
-  mvs[2][OC_FRAME_GOLD][0]+=accum_g[0];
-  mvs[2][OC_FRAME_GOLD][1]+=accum_g[1];
-  mvs[1][OC_FRAME_GOLD][0]+=mvs[2][OC_FRAME_GOLD][0];
-  mvs[1][OC_FRAME_GOLD][1]+=mvs[2][OC_FRAME_GOLD][1];
+  mvs[2][OC_FRAME_GOLD]=OC_MV_ADD(mvs[2][OC_FRAME_GOLD],accum_g);
+  mvs[1][OC_FRAME_GOLD]=OC_MV_ADD(mvs[1][OC_FRAME_GOLD],mvs[2][OC_FRAME_GOLD]);
 }
 
 #if 0
@@ -655,12 +653,11 @@
   oc_mb_enc_info *embs;
   int             vec[2];
   embs=_enc->mb_info;
-  vec[0]=OC_DIV2(embs[_mbi].analysis_mv[0][_frame][0]);
-  vec[1]=OC_DIV2(embs[_mbi].analysis_mv[0][_frame][1]);
+  vec[0]=OC_DIV2(OC_MV_X(embs[_mbi].analysis_mv[0][_frame]));
+  vec[1]=OC_DIV2(OC_MV_Y(embs[_mbi].analysis_mv[0][_frame]));
   embs[_mbi].satd[_frame]=oc_mcenc_ysatd_halfpel_mbrefine(_enc,
    _mbi,vec,embs[_mbi].satd[_frame],_frame);
-  embs[_mbi].analysis_mv[0][_frame][0]=(signed char)vec[0];
-  embs[_mbi].analysis_mv[0][_frame][1]=(signed char)vec[1];
+  embs[_mbi].analysis_mv[0][_frame]=OC_MV(vec[0],vec[1]);
 }
 
 #if 0
@@ -771,11 +768,10 @@
     ptrdiff_t frag_offs;
     int       vec[2];
     frag_offs=frag_buf_offs[fragis[bi]];
-    vec[0]=OC_DIV2(embs[_mbi].block_mv[bi][0]);
-    vec[1]=OC_DIV2(embs[_mbi].block_mv[bi][1]);
+    vec[0]=OC_DIV2(OC_MV_X(embs[_mbi].block_mv[bi]));
+    vec[1]=OC_DIV2(OC_MV_Y(embs[_mbi].block_mv[bi]));
     embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_halfpel_brefine(_enc,vec,
      src+frag_offs,ref+frag_offs,ystride,offset_y,embs[_mbi].block_satd[bi]);
-    embs[_mbi].ref_mv[bi][0]=(signed char)vec[0];
-    embs[_mbi].ref_mv[bi][1]=(signed char)vec[1];
+    embs[_mbi].ref_mv[bi]=OC_MV(vec[0],vec[1]);
   }
 }

Modified: experimental/derf/theora-ptalarbvorm/lib/state.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/state.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/state.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -32,10 +32,11 @@
 static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
   int dx;
   int dy;
-  dx=_lbmvs[0][0]+_lbmvs[1][0]+_lbmvs[2][0]+_lbmvs[3][0];
-  dy=_lbmvs[0][1]+_lbmvs[1][1]+_lbmvs[2][1]+_lbmvs[3][1];
-  _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,2,2);
-  _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,2,2);
+  dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[1])
+   +OC_MV_X(_lbmvs[2])+OC_MV_X(_lbmvs[3]);
+  dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[1])
+   +OC_MV_Y(_lbmvs[2])+OC_MV_Y(_lbmvs[3]);
+  _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,2,2),OC_DIV_ROUND_POW2(dy,2,2));
 }
 
 /*The function used to fill in the chroma plane motion vectors for a macro
@@ -46,14 +47,12 @@
 static void oc_set_chroma_mvs01(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
   int dx;
   int dy;
-  dx=_lbmvs[0][0]+_lbmvs[2][0];
-  dy=_lbmvs[0][1]+_lbmvs[2][1];
-  _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
-  _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
-  dx=_lbmvs[1][0]+_lbmvs[3][0];
-  dy=_lbmvs[1][1]+_lbmvs[3][1];
-  _cbmvs[1][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
-  _cbmvs[1][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
+  dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[2]);
+  dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[2]);
+  _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1));
+  dx=OC_MV_X(_lbmvs[1])+OC_MV_X(_lbmvs[3]);
+  dy=OC_MV_Y(_lbmvs[1])+OC_MV_Y(_lbmvs[3]);
+  _cbmvs[1]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1));
 }
 
 /*The function used to fill in the chroma plane motion vectors for a macro
@@ -64,14 +63,12 @@
 static void oc_set_chroma_mvs10(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
   int dx;
   int dy;
-  dx=_lbmvs[0][0]+_lbmvs[1][0];
-  dy=_lbmvs[0][1]+_lbmvs[1][1];
-  _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
-  _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
-  dx=_lbmvs[2][0]+_lbmvs[3][0];
-  dy=_lbmvs[2][1]+_lbmvs[3][1];
-  _cbmvs[2][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
-  _cbmvs[2][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
+  dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[1]);
+  dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[1]);
+  _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1));
+  dx=OC_MV_X(_lbmvs[2])+OC_MV_X(_lbmvs[3]);
+  dy=OC_MV_Y(_lbmvs[2])+OC_MV_Y(_lbmvs[3]);
+  _cbmvs[2]=OC_MV(OC_DIV_ROUND_POW2(dx,1,1),OC_DIV_ROUND_POW2(dy,1,1));
 }
 
 /*The function used to fill in the chroma plane motion vectors for a macro
@@ -82,7 +79,10 @@
            prediction.
   _lbmvs: The luma block-level motion vectors.*/
 static void oc_set_chroma_mvs11(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
-  memcpy(_cbmvs,_lbmvs,4*sizeof(_lbmvs[0]));
+  _cbmvs[0]=_lbmvs[0];
+  _cbmvs[1]=_lbmvs[1];
+  _cbmvs[2]=_lbmvs[2];
+  _cbmvs[3]=_lbmvs[3];
 }
 
 /*A table of functions used to fill in the chroma plane motion vectors for a
@@ -822,11 +822,10 @@
             _offsets[1] is set if the motion vector has non-zero fractional
              components.
   _pli:     The color plane index.
-  _dx:      The X component of the motion vector.
-  _dy:      The Y component of the motion vector.
+  _mv:      The motion vector.
   Return: The number of offsets returned: 1 or 2.*/
 int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2],
- int _pli,int _dx,int _dy){
+ int _pli,oc_mv _mv){
   /*Here is a brief description of how Theora handles motion vectors:
     Motion vector components are specified to half-pixel accuracy in
      undecimated directions of each plane, and quarter-pixel accuracy in
@@ -849,21 +848,25 @@
   int xfrac;
   int yfrac;
   int offs;
+  int dx;
+  int dy;
   ystride=_state->ref_ystride[_pli];
   /*These two variables decide whether we are in half- or quarter-pixel
      precision in each component.*/
   xprec=1+(_pli!=0&&!(_state->info.pixel_fmt&1));
   yprec=1+(_pli!=0&&!(_state->info.pixel_fmt&2));
+  dx=OC_MV_X(_mv);
+  dy=OC_MV_Y(_mv);
   /*These two variables are either 0 if all the fractional bits are zero or -1
      if any of them are non-zero.*/
-  xfrac=OC_SIGNMASK(-(_dx&(xprec|1)));
-  yfrac=OC_SIGNMASK(-(_dy&(yprec|1)));
-  offs=(_dx>>xprec)+(_dy>>yprec)*ystride;
+  xfrac=OC_SIGNMASK(-(dx&(xprec|1)));
+  yfrac=OC_SIGNMASK(-(dy&(yprec|1)));
+  offs=(dx>>xprec)+(dy>>yprec)*ystride;
   if(xfrac||yfrac){
     int xmask;
     int ymask;
-    xmask=OC_SIGNMASK(_dx);
-    ymask=OC_SIGNMASK(_dy);
+    xmask=OC_SIGNMASK(dx);
+    ymask=OC_SIGNMASK(dy);
     yfrac&=ystride;
     _offsets[0]=offs-(xfrac&xmask)+(yfrac&ymask);
     _offsets[1]=offs-(xfrac&~xmask)+(yfrac&~ymask);
@@ -912,13 +915,17 @@
   int mx2;
   int my2;
   int offs;
+  int dx;
+  int dy;
   ystride=_state->ref_ystride[_pli];
   qpy=_pli!=0&&!(_state->info.pixel_fmt&2);
-  my=OC_MVMAP[qpy][_dy+31];
-  my2=OC_MVMAP2[qpy][_dy+31];
+  dx=OC_MV_X(_mv);
+  dy=OC_MV_Y(_mv);
+  my=OC_MVMAP[qpy][dy+31];
+  my2=OC_MVMAP2[qpy][dy+31];
   qpx=_pli!=0&&!(_state->info.pixel_fmt&1);
-  mx=OC_MVMAP[qpx][_dx+31];
-  mx2=OC_MVMAP2[qpx][_dx+31];
+  mx=OC_MVMAP[qpx][dx+31];
+  mx2=OC_MVMAP2[qpx][dx+31];
   offs=my*ystride+mx;
   if(mx2||my2){
     _offsets[1]=offs+my2*ystride+mx2;
@@ -967,7 +974,7 @@
      _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]]
      +frag_buf_off;
     if(oc_state_get_mv_offsets(_state,mvoffsets,_pli,
-     _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){
+     _state->frag_mvs[_fragi])>1){
       oc_frag_recon_inter2(_state,
        dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride,_dct_coeffs+64);
     }

Modified: experimental/derf/theora-ptalarbvorm/lib/state.h
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/state.h	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/state.h	2010-09-22 06:46:13 UTC (rev 17416)
@@ -31,7 +31,7 @@
 /*A map from a macro block to fragment numbers.*/
 typedef oc_mb_map_plane oc_mb_map[3];
 /*A motion vector.*/
-typedef signed char     oc_mv[2];
+typedef ogg_int16_t     oc_mv;
 
 typedef struct oc_sb_flags              oc_sb_flags;
 typedef struct oc_border_info           oc_border_info;
@@ -227,6 +227,18 @@
 
 
 
+#define OC_MV(_x,_y)         ((oc_mv)((_x)&0xFF|(_y)<<8))
+#define OC_MV_X(_mv)         ((signed char)(_mv))
+#define OC_MV_Y(_mv)         ((_mv)>>8)
+#define OC_MV_ADD(_mv1,_mv2) \
+  OC_MV(OC_MV_X(_mv1)+OC_MV_X(_mv2), \
+   OC_MV_Y(_mv1)+OC_MV_Y(_mv2))
+#define OC_MV_SUB(_mv1,_mv2) \
+  OC_MV(OC_MV_X(_mv1)-OC_MV_X(_mv2), \
+   OC_MV_Y(_mv1)-OC_MV_Y(_mv2))
+
+
+
 /*Super blocks are 32x32 segments of pixels in a single color plane indexed
    in image order.
   Internally, super blocks are broken up into four quadrants, each of which
@@ -478,7 +490,7 @@
  th_ycbcr_buffer _img);
 int oc_state_mbi_for_pos(oc_theora_state *_state,int _mbx,int _mby);
 int oc_state_get_mv_offsets(const oc_theora_state *_state,int _offsets[2],
- int _pli,int _dx,int _dy);
+ int _pli,oc_mv _mv);
 
 void oc_loop_filter_init_c(signed char _bv[256],int _flimit);
 void oc_state_loop_filter(oc_theora_state *_state,int _frame);

Modified: experimental/derf/theora-ptalarbvorm/lib/x86/mmxstate.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/x86/mmxstate.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/x86/mmxstate.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -78,7 +78,7 @@
      _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]]
      +frag_buf_off;
     if(oc_state_get_mv_offsets(_state,mvoffsets,_pli,
-     _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){
+     _state->frag_mvs[_fragi])>1){
       oc_frag_recon_inter2_mmx(dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride,
        _dct_coeffs+64);
     }

Modified: experimental/derf/theora-ptalarbvorm/lib/x86_vc/mmxstate.c
===================================================================
--- experimental/derf/theora-ptalarbvorm/lib/x86_vc/mmxstate.c	2010-09-22 06:42:10 UTC (rev 17415)
+++ experimental/derf/theora-ptalarbvorm/lib/x86_vc/mmxstate.c	2010-09-22 06:46:13 UTC (rev 17416)
@@ -89,7 +89,7 @@
      _state->ref_frame_data[_state->ref_frame_idx[OC_FRAME_FOR_MODE(mb_mode)]]
      +frag_buf_off;
     if(oc_state_get_mv_offsets(_state,mvoffsets,_pli,
-     _state->frag_mvs[_fragi][0],_state->frag_mvs[_fragi][1])>1){
+     _state->frag_mvs[_fragi])>1){
       oc_frag_recon_inter2_mmx(dst,ref+mvoffsets[0],ref+mvoffsets[1],ystride,
        _dct_coeffs+64);
     }



More information about the commits mailing list