1ac9de401b19359b9d639e9c7c2c7050ffdf71ec
[theora.git] / lib / mcenc.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12
13   function:
14   last mod: $Id$
15
16  ********************************************************************/
17 #include <stdlib.h>
18 #include <limits.h>
19 #include <string.h>
20 #include "encint.h"
21
22
23
24 typedef struct oc_mcenc_ctx           oc_mcenc_ctx;
25
26
27
28 /*Temporary state used for motion estimation.*/
29 struct oc_mcenc_ctx{
30   /*The candidate motion vectors.*/
31   int                candidates[13][2];
32   /*The start of the Set B candidates.*/
33   int                setb0;
34   /*The total number of candidates.*/
35   int                ncandidates;
36 };
37
38
39
40 /*The maximum Y plane SAD value for accepting the median predictor.*/
41 #define OC_YSAD_THRESH1            (256)
42 /*The amount to right shift the minimum error by when inflating it for
43    computing the second maximum Y plane SAD threshold.*/
44 #define OC_YSAD_THRESH2_SCALE_BITS (4)
45 /*The amount to add to the second maximum Y plane threshold when inflating
46    it.*/
47 #define OC_YSAD_THRESH2_OFFSET     (64)
48
49 /*The vector offsets in the X direction for each search site in the square
50    pattern.*/
51 static const int OC_SQUARE_DX[9]={-1,0,1,-1,0,1,-1,0,1};
52 /*The vector offsets in the Y direction for each search site in the square
53    pattern.*/
54 static const int OC_SQUARE_DY[9]={-1,-1,-1,0,0,0,1,1,1};
55 /*The number of sites to search for each boundary condition in the square
56    pattern.
57   Bit flags for the boundary conditions are as follows:
58   1: -16==dx
59   2:      dx==15(.5)
60   4: -16==dy
61   8:      dy==15(.5)*/
62 static const int OC_SQUARE_NSITES[11]={8,5,5,0,5,3,3,0,5,3,3};
63 /*The list of sites to search for each boundary condition in the square
64    pattern.*/
65 static const int OC_SQUARE_SITES[11][8]={
66   /* -15.5<dx<31,       -15.5<dy<15(.5)*/
67   {0,1,2,3,5,6,7,8},
68   /*-15.5==dx,          -15.5<dy<15(.5)*/
69   {1,2,5,7,8},
70   /*     dx==15(.5),    -15.5<dy<15(.5)*/
71   {0,1,3,6,7},
72   /*-15.5==dx==15(.5),  -15.5<dy<15(.5)*/
73   {-1},
74   /* -15.5<dx<15(.5),  -15.5==dy*/
75   {3,5,6,7,8},
76   /*-15.5==dx,         -15.5==dy*/
77   {5,7,8},
78   /*     dx==15(.5),   -15.5==dy*/
79   {3,6,7},
80   /*-15.5==dx==15(.5), -15.5==dy*/
81   {-1},
82   /*-15.5dx<15(.5),           dy==15(.5)*/
83   {0,1,2,3,5},
84   /*-15.5==dx,                dy==15(.5)*/
85   {1,2,5},
86   /*       dx==15(.5),        dy==15(.5)*/
87   {0,1,3}
88 };
89
90
91 static void oc_mcenc_find_candidates_a(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc,
92  oc_mv _accum,int _mbi,int _frame){
93   oc_mb_enc_info *embs;
94   int             accum_x;
95   int             accum_y;
96   int             a[3][2];
97   int             ncandidates;
98   unsigned        nmbi;
99   int             i;
100   embs=_enc->mb_info;
101   /*Skip a position to store the median predictor in.*/
102   ncandidates=1;
103   if(embs[_mbi].ncneighbors>0){
104     /*Fill in the first part of set A: the vectors from adjacent blocks.*/
105     for(i=0;i<embs[_mbi].ncneighbors;i++){
106       nmbi=embs[_mbi].cneighbors[i];
107       _mcenc->candidates[ncandidates][0]=
108        OC_MV_X(embs[nmbi].analysis_mv[0][_frame]);
109       _mcenc->candidates[ncandidates][1]=
110        OC_MV_Y(embs[nmbi].analysis_mv[0][_frame]);
111       ncandidates++;
112     }
113   }
114   accum_x=OC_MV_X(_accum);
115   accum_y=OC_MV_Y(_accum);
116   /*Add a few additional vectors to set A: the vectors used in the previous
117      frames and the (0,0) vector.*/
118   _mcenc->candidates[ncandidates][0]=accum_x;
119   _mcenc->candidates[ncandidates][1]=accum_y;
120   ncandidates++;
121   _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,
122    OC_MV_X(embs[_mbi].analysis_mv[1][_frame])+accum_x,31);
123   _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,
124    OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])+accum_y,31);
125   ncandidates++;
126   _mcenc->candidates[ncandidates][0]=0;
127   _mcenc->candidates[ncandidates][1]=0;
128   ncandidates++;
129   /*Use the first three vectors of set A to find our best predictor: their
130      median.*/
131   memcpy(a,_mcenc->candidates+1,sizeof(a));
132   OC_SORT2I(a[0][0],a[1][0]);
133   OC_SORT2I(a[0][1],a[1][1]);
134   OC_SORT2I(a[1][0],a[2][0]);
135   OC_SORT2I(a[1][1],a[2][1]);
136   OC_SORT2I(a[0][0],a[1][0]);
137   OC_SORT2I(a[0][1],a[1][1]);
138   _mcenc->candidates[0][0]=a[1][0];
139   _mcenc->candidates[0][1]=a[1][1];
140   _mcenc->setb0=ncandidates;
141 }
142
143 static void oc_mcenc_find_candidates_b(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc,
144  oc_mv _accum,int _mbi,int _frame){
145   oc_mb_enc_info *embs;
146   int             accum_x;
147   int             accum_y;
148   int             ncandidates;
149   embs=_enc->mb_info;
150   accum_x=OC_MV_X(_accum);
151   accum_y=OC_MV_Y(_accum);
152   /*Fill in set B: accelerated predictors for this and adjacent macro blocks.*/
153   ncandidates=_mcenc->setb0;
154   /*Use only the current block. Using more did not appear to be helpful
155     with the current selection logic due to escaping the local search too
156     quickly.*/
157   _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,
158    2*OC_MV_X(embs[_mbi].analysis_mv[1][_frame])
159    -OC_MV_X(embs[_mbi].analysis_mv[2][_frame])+accum_x,31);
160   _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,
161    2*OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])
162    -OC_MV_Y(embs[_mbi].analysis_mv[2][_frame])+accum_y,31);
163   ncandidates++;
164   _mcenc->ncandidates=ncandidates;
165 }
166
167 #if 0
168 static unsigned oc_sad16_halfpel(const oc_enc_ctx *_enc,
169  const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4],
170  int _mvoffset0,int _mvoffset1,const unsigned char *_src,
171  const unsigned char *_ref,int _ystride,unsigned _best_err){
172   unsigned err;
173   int      bi;
174   err=0;
175   for(bi=0;bi<4;bi++){
176     ptrdiff_t frag_offs;
177     frag_offs=_frag_buf_offs[_fragis[bi]];
178     err+=oc_enc_frag_sad2_thresh(_enc,_src+frag_offs,_ref+frag_offs+_mvoffset0,
179      _ref+frag_offs+_mvoffset1,_ystride,_best_err-err);
180   }
181   return err;
182 }
183 #endif
184
185 static unsigned oc_satd16_halfpel(const oc_enc_ctx *_enc,
186  const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4],
187  int _mvoffset0,int _mvoffset1,const unsigned char *_src,
188  const unsigned char *_ref,int _ystride,unsigned _best_err){
189   unsigned err;
190   unsigned dc;
191   int      bi;
192   err=0;
193   for(bi=0;bi<4;bi++){
194     ptrdiff_t frag_offs;
195     frag_offs=_frag_buf_offs[_fragis[bi]];
196     err+=oc_enc_frag_satd2(_enc,&dc,_src+frag_offs,
197      _ref+frag_offs+_mvoffset0,_ref+frag_offs+_mvoffset1,_ystride);
198     err+=dc;
199   }
200   return err;
201 }
202
203 static unsigned oc_mcenc_ysad_check_mbcandidate_fullpel(const oc_enc_ctx *_enc,
204  const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4],int _dx,int _dy,
205  const unsigned char *_src,const unsigned char *_ref,int _ystride,
206  unsigned _block_err[4]){
207   unsigned err;
208   int      mvoffset;
209   int      bi;
210   mvoffset=_dx+_dy*_ystride;
211   err=0;
212   for(bi=0;bi<4;bi++){
213     ptrdiff_t frag_offs;
214     unsigned  block_err;
215     frag_offs=_frag_buf_offs[_fragis[bi]];
216     block_err=oc_enc_frag_sad(_enc,
217      _src+frag_offs,_ref+frag_offs+mvoffset,_ystride);
218     _block_err[bi]=block_err;
219     err+=block_err;
220   }
221   return err;
222 }
223
224 static int oc_mcenc_ysatd_check_mbcandidate_fullpel(const oc_enc_ctx *_enc,
225  const ptrdiff_t *_frag_buf_offs,const ptrdiff_t _fragis[4],int _dx,int _dy,
226  const unsigned char *_src,const unsigned char *_ref,int _ystride){
227   int mvoffset;
228   int err;
229   int bi;
230   mvoffset=_dx+_dy*_ystride;
231   err=0;
232   for(bi=0;bi<4;bi++){
233     ptrdiff_t frag_offs;
234     unsigned  dc;
235     frag_offs=_frag_buf_offs[_fragis[bi]];
236     err+=oc_enc_frag_satd(_enc,&dc,
237      _src+frag_offs,_ref+frag_offs+mvoffset,_ystride);
238     err+=dc;
239   }
240   return err;
241 }
242
243 static unsigned oc_mcenc_ysatd_check_bcandidate_fullpel(const oc_enc_ctx *_enc,
244  ptrdiff_t _frag_offs,int _dx,int _dy,
245  const unsigned char *_src,const unsigned char *_ref,int _ystride){
246   unsigned err;
247   unsigned dc;
248   err=oc_enc_frag_satd(_enc,&dc,
249    _src+_frag_offs,_ref+_frag_offs+_dx+_dy*_ystride,_ystride);
250   return err+dc;
251 }
252
253 /*Perform a motion vector search for this macro block against a single
254    reference frame.
255   As a bonus, individual block motion vectors are computed as well, as much of
256    the work can be shared.
257   The actual motion vector is stored in the appropriate place in the
258    oc_mb_enc_info structure.
259   _accum:      Drop frame/golden MV accumulators.
260   _mbi:        The macro block index.
261   _frame:      The frame to use for SATD calculations and refinement,
262                 either OC_FRAME_PREV or OC_FRAME_GOLD.
263   _frame_full: The frame to perform the 1px search on, one of OC_FRAME_PREV,
264                 OC_FRAME_GOLD, OC_FRAME_PREV_ORIG, or OC_FRAME_GOLD_ORIG.*/
265 void oc_mcenc_search_frame(oc_enc_ctx *_enc,oc_mv _accum,int _mbi,int _frame,
266  int _frame_full){
267   /*Note: Traditionally this search is done using a rate-distortion objective
268      function of the form D+lambda*R.
269     However, xiphmont tested this and found it produced a small degredation,
270      while requiring extra computation.
271     This is most likely due to Theora's peculiar MV encoding scheme: MVs are
272      not coded relative to a predictor, and the only truly cheap way to use a
273      MV is in the LAST or LAST2 MB modes, which are not being considered here.
274     Therefore if we use the MV found here, it's only because both LAST and
275      LAST2 performed poorly, and therefore the MB is not likely to be uniform
276      or suffer from the aperture problem.
277     Furthermore we would like to re-use the MV found here for as many MBs as
278      possible, so picking a slightly sub-optimal vector to save a bit or two
279      may cause increased degredation in many blocks to come.
280     We could artificially reduce lambda to compensate, but it's faster to just
281      disable it entirely, and use D (the distortion) as the sole criterion.*/
282   oc_mcenc_ctx         mcenc;
283   const ptrdiff_t     *frag_buf_offs;
284   const ptrdiff_t     *fragis;
285   const unsigned char *src;
286   const unsigned char *ref;
287   const unsigned char *satd_ref;
288   int                  ystride;
289   oc_mb_enc_info      *embs;
290   ogg_int32_t          hit_cache[31];
291   ogg_int32_t          hitbit;
292   unsigned             best_block_err[4];
293   unsigned             block_err[4];
294   unsigned             best_err;
295   int                  best_vec[2];
296   int                  best_block_vec[4][2];
297   int                  candx;
298   int                  candy;
299   int                  bi;
300   embs=_enc->mb_info;
301   /*Find some candidate motion vectors.*/
302   oc_mcenc_find_candidates_a(_enc,&mcenc,_accum,_mbi,_frame);
303   /*Clear the cache of locations we've examined.*/
304   memset(hit_cache,0,sizeof(hit_cache));
305   /*Start with the median predictor.*/
306   candx=OC_DIV2(mcenc.candidates[0][0]);
307   candy=OC_DIV2(mcenc.candidates[0][1]);
308   hit_cache[candy+15]|=(ogg_int32_t)1<<candx+15;
309   frag_buf_offs=_enc->state.frag_buf_offs;
310   fragis=_enc->state.mb_maps[_mbi][0];
311   src=_enc->state.ref_frame_data[OC_FRAME_IO];
312   ref=_enc->state.ref_frame_data[_frame_full];
313   satd_ref=_enc->state.ref_frame_data[_frame];
314   ystride=_enc->state.ref_ystride[0];
315   /*TODO: customize error function for speed/(quality+size) tradeoff.*/
316   best_err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc,
317    frag_buf_offs,fragis,candx,candy,src,ref,ystride,block_err);
318   best_vec[0]=candx;
319   best_vec[1]=candy;
320   if(_frame==OC_FRAME_PREV){
321     for(bi=0;bi<4;bi++){
322       best_block_err[bi]=block_err[bi];
323       best_block_vec[bi][0]=candx;
324       best_block_vec[bi][1]=candy;
325     }
326   }
327   /*If this predictor fails, move on to set A.*/
328   if(best_err>OC_YSAD_THRESH1){
329     unsigned err;
330     unsigned t2;
331     int      ncs;
332     int      ci;
333     /*Compute the early termination threshold for set A.*/
334     t2=embs[_mbi].error[_frame];
335     ncs=OC_MINI(3,embs[_mbi].ncneighbors);
336     for(ci=0;ci<ncs;ci++){
337       t2=OC_MAXI(t2,embs[embs[_mbi].cneighbors[ci]].error[_frame]);
338     }
339     t2+=(t2>>OC_YSAD_THRESH2_SCALE_BITS)+OC_YSAD_THRESH2_OFFSET;
340     /*Examine the candidates in set A.*/
341     for(ci=1;ci<mcenc.setb0;ci++){
342       candx=OC_DIV2(mcenc.candidates[ci][0]);
343       candy=OC_DIV2(mcenc.candidates[ci][1]);
344       /*If we've already examined this vector, then we would be using it if it
345          was better than what we are using.*/
346       hitbit=(ogg_int32_t)1<<candx+15;
347       if(hit_cache[candy+15]&hitbit)continue;
348       hit_cache[candy+15]|=hitbit;
349       err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc,
350        frag_buf_offs,fragis,candx,candy,src,ref,ystride,block_err);
351       if(err<best_err){
352         best_err=err;
353         best_vec[0]=candx;
354         best_vec[1]=candy;
355       }
356       if(_frame==OC_FRAME_PREV){
357         for(bi=0;bi<4;bi++)if(block_err[bi]<best_block_err[bi]){
358           best_block_err[bi]=block_err[bi];
359           best_block_vec[bi][0]=candx;
360           best_block_vec[bi][1]=candy;
361         }
362       }
363     }
364     if(best_err>t2){
365       oc_mcenc_find_candidates_b(_enc,&mcenc,_accum,_mbi,_frame);
366       /*Examine the candidates in set B.*/
367       for(;ci<mcenc.ncandidates;ci++){
368         candx=OC_DIV2(mcenc.candidates[ci][0]);
369         candy=OC_DIV2(mcenc.candidates[ci][1]);
370         hitbit=(ogg_int32_t)1<<candx+15;
371         if(hit_cache[candy+15]&hitbit)continue;
372         hit_cache[candy+15]|=hitbit;
373         err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc,
374          frag_buf_offs,fragis,candx,candy,src,ref,ystride,block_err);
375         if(err<best_err){
376           best_err=err;
377           best_vec[0]=candx;
378           best_vec[1]=candy;
379         }
380         if(_frame==OC_FRAME_PREV){
381           for(bi=0;bi<4;bi++)if(block_err[bi]<best_block_err[bi]){
382             best_block_err[bi]=block_err[bi];
383             best_block_vec[bi][0]=candx;
384             best_block_vec[bi][1]=candy;
385           }
386         }
387       }
388       /*Use the same threshold for set B as in set A.*/
389       if(best_err>t2){
390         int best_site;
391         int nsites;
392         int sitei;
393         int site;
394         int b;
395         /*Square pattern search.*/
396         for(;;){
397           best_site=4;
398           /*Compose the bit flags for boundary conditions.*/
399           b=OC_DIV16(-best_vec[0]+1)|OC_DIV16(best_vec[0]+1)<<1|
400            OC_DIV16(-best_vec[1]+1)<<2|OC_DIV16(best_vec[1]+1)<<3;
401           nsites=OC_SQUARE_NSITES[b];
402           for(sitei=0;sitei<nsites;sitei++){
403             site=OC_SQUARE_SITES[b][sitei];
404             candx=best_vec[0]+OC_SQUARE_DX[site];
405             candy=best_vec[1]+OC_SQUARE_DY[site];
406             hitbit=(ogg_int32_t)1<<candx+15;
407             if(hit_cache[candy+15]&hitbit)continue;
408             hit_cache[candy+15]|=hitbit;
409             err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc,
410              frag_buf_offs,fragis,candx,candy,src,ref,ystride,block_err);
411             if(err<best_err){
412               best_err=err;
413               best_site=site;
414             }
415             if(_frame==OC_FRAME_PREV){
416               for(bi=0;bi<4;bi++)if(block_err[bi]<best_block_err[bi]){
417                 best_block_err[bi]=block_err[bi];
418                 best_block_vec[bi][0]=candx;
419                 best_block_vec[bi][1]=candy;
420               }
421             }
422           }
423           if(best_site==4)break;
424           best_vec[0]+=OC_SQUARE_DX[best_site];
425           best_vec[1]+=OC_SQUARE_DY[best_site];
426         }
427         /*Final 4-MV search.*/
428         /*Simply use 1/4 of the macro block set A and B threshold as the
429            individual block threshold.*/
430         if(_frame==OC_FRAME_PREV){
431           t2>>=2;
432           for(bi=0;bi<4;bi++){
433             if(best_block_err[bi]>t2){
434               /*Square pattern search.
435                 We do this in a slightly interesting manner.
436                 We continue to check the SAD of all four blocks in the
437                  macro block.
438                 This gives us two things:
439                  1) We can continue to use the hit_cache to avoid duplicate
440                      checks.
441                     Otherwise we could continue to read it, but not write to it
442                      without saving and restoring it for each block.
443                     Note that we could still eliminate a large number of
444                      duplicate checks by taking into account the site we came
445                      from when choosing the site list.
446                     We can still do that to avoid extra hit_cache queries, and
447                      it might even be a speed win.
448                  2) It gives us a slightly better chance of escaping local
449                      minima.
450                     We would not be here if we weren't doing a fairly bad job
451                      in finding a good vector, and checking these vectors can
452                      save us from 100 to several thousand points off our SAD 1
453                      in 15 times.
454                 TODO: Is this a good idea?
455                 Who knows.
456                 It needs more testing.*/
457               for(;;){
458                 int bestx;
459                 int besty;
460                 int bj;
461                 bestx=best_block_vec[bi][0];
462                 besty=best_block_vec[bi][1];
463                 /*Compose the bit flags for boundary conditions.*/
464                 b=OC_DIV16(-bestx+1)|OC_DIV16(bestx+1)<<1|
465                  OC_DIV16(-besty+1)<<2|OC_DIV16(besty+1)<<3;
466                 nsites=OC_SQUARE_NSITES[b];
467                 for(sitei=0;sitei<nsites;sitei++){
468                   site=OC_SQUARE_SITES[b][sitei];
469                   candx=bestx+OC_SQUARE_DX[site];
470                   candy=besty+OC_SQUARE_DY[site];
471                   hitbit=(ogg_int32_t)1<<candx+15;
472                   if(hit_cache[candy+15]&hitbit)continue;
473                   hit_cache[candy+15]|=hitbit;
474                   err=oc_mcenc_ysad_check_mbcandidate_fullpel(_enc,
475                    frag_buf_offs,fragis,candx,candy,src,ref,ystride,block_err);
476                   if(err<best_err){
477                     best_err=err;
478                     best_vec[0]=candx;
479                     best_vec[1]=candy;
480                   }
481                   for(bj=0;bj<4;bj++)if(block_err[bj]<best_block_err[bj]){
482                     best_block_err[bj]=block_err[bj];
483                     best_block_vec[bj][0]=candx;
484                     best_block_vec[bj][1]=candy;
485                   }
486                 }
487                 if(best_block_vec[bi][0]==bestx&&best_block_vec[bi][1]==besty){
488                   break;
489                 }
490               }
491             }
492           }
493         }
494       }
495     }
496   }
497   embs[_mbi].error[_frame]=(ogg_uint16_t)best_err;
498   candx=best_vec[0];
499   candy=best_vec[1];
500   embs[_mbi].satd[_frame]=oc_mcenc_ysatd_check_mbcandidate_fullpel(_enc,
501    frag_buf_offs,fragis,candx,candy,src,satd_ref,ystride);
502   embs[_mbi].analysis_mv[0][_frame]=OC_MV(candx<<1,candy<<1);
503   if(_frame==OC_FRAME_PREV&&_enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){
504     for(bi=0;bi<4;bi++){
505       candx=best_block_vec[bi][0];
506       candy=best_block_vec[bi][1];
507       embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_check_bcandidate_fullpel(_enc,
508        frag_buf_offs[fragis[bi]],candx,candy,src,satd_ref,ystride);
509       embs[_mbi].block_mv[bi]=OC_MV(candx<<1,candy<<1);
510     }
511   }
512 }
513
514 void oc_mcenc_search(oc_enc_ctx *_enc,int _mbi){
515   oc_mv2 *mvs;
516   oc_mv   accum_p;
517   oc_mv   accum_g;
518   oc_mv   mv2_p;
519   mvs=_enc->mb_info[_mbi].analysis_mv;
520   if(_enc->prevframe_dropped)accum_p=mvs[0][OC_FRAME_PREV];
521   else accum_p=0;
522   accum_g=mvs[2][OC_FRAME_GOLD];
523   /*Move the motion vector predictors back a frame.*/
524   mv2_p=mvs[2][OC_FRAME_PREV];
525   mvs[2][OC_FRAME_GOLD]=mvs[1][OC_FRAME_GOLD];
526   mvs[2][OC_FRAME_PREV]=mvs[1][OC_FRAME_PREV];
527   mvs[1][OC_FRAME_GOLD]=mvs[0][OC_FRAME_GOLD];
528   mvs[1][OC_FRAME_PREV]=OC_MV_SUB(mvs[0][OC_FRAME_PREV],mv2_p);
529   /*Search the last frame.*/
530   oc_mcenc_search_frame(_enc,accum_p,_mbi,OC_FRAME_PREV,OC_FRAME_PREV_ORIG);
531   mvs[2][OC_FRAME_PREV]=accum_p;
532   /*GOLDEN MVs are different from PREV MVs in that they're each absolute
533      offsets from some frame in the past rather than relative offsets from the
534      frame before.
535     For predictor calculation to make sense, we need them to be in the same
536      form as PREV MVs.*/
537   mvs[1][OC_FRAME_GOLD]=OC_MV_SUB(mvs[1][OC_FRAME_GOLD],mvs[2][OC_FRAME_GOLD]);
538   mvs[2][OC_FRAME_GOLD]=OC_MV_SUB(mvs[2][OC_FRAME_GOLD],accum_g);
539   /*Search the golden frame.*/
540   oc_mcenc_search_frame(_enc,accum_g,_mbi,OC_FRAME_GOLD,OC_FRAME_GOLD_ORIG);
541   /*Put GOLDEN MVs back into absolute offset form.
542     The newest MV is already an absolute offset.*/
543   mvs[2][OC_FRAME_GOLD]=OC_MV_ADD(mvs[2][OC_FRAME_GOLD],accum_g);
544   mvs[1][OC_FRAME_GOLD]=OC_MV_ADD(mvs[1][OC_FRAME_GOLD],mvs[2][OC_FRAME_GOLD]);
545 }
546
547 #if 0
548 static int oc_mcenc_ysad_halfpel_mbrefine(const oc_enc_ctx *_enc,int _mbi,
549  int _vec[2],int _best_err,int _frame){
550   const unsigned char *src;
551   const unsigned char *ref;
552   const ptrdiff_t     *frag_buf_offs;
553   const ptrdiff_t     *fragis;
554   int                  offset_y[9];
555   int                  ystride;
556   int                  mvoffset_base;
557   int                  best_site;
558   int                  sitei;
559   int                  err;
560   src=_enc->state.ref_frame_data[OC_FRAME_IO];
561   ref=_enc->state.ref_frame_data[_framei];
562   frag_buf_offs=_enc->state.frag_buf_offs;
563   fragis=_enc->state.mb_maps[_mbi][0];
564   ystride=_enc->state.ref_ystride[0];
565   mvoffset_base=_vec[0]+_vec[1]*ystride;
566   offset_y[0]=offset_y[1]=offset_y[2]=-ystride;
567   offset_y[3]=offset_y[5]=0;
568   offset_y[6]=offset_y[7]=offset_y[8]=ystride;
569   best_site=4;
570   for(sitei=0;sitei<8;sitei++){
571     int site;
572     int xmask;
573     int ymask;
574     int dx;
575     int dy;
576     int mvoffset0;
577     int mvoffset1;
578     site=OC_SQUARE_SITES[0][sitei];
579     dx=OC_SQUARE_DX[site];
580     dy=OC_SQUARE_DY[site];
581     /*The following code SHOULD be equivalent to
582         oc_state_get_mv_offsets(&_mcenc->enc.state,&mvoffset0,&mvoffset1,
583          (_vec[0]<<1)+dx,(_vec[1]<<1)+dy,ref_ystride,0);
584       However, it should also be much faster, as it involves no multiplies and
585        doesn't have to handle chroma vectors.*/
586     xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx);
587     ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy);
588     mvoffset0=mvoffset_base+(dx&xmask)+(offset_y[site]&ymask);
589     mvoffset1=mvoffset_base+(dx&~xmask)+(offset_y[site]&~ymask);
590     err=oc_sad16_halfpel(_enc,frag_buf_offs,fragis,
591      mvoffset0,mvoffset1,src,ref,ystride,_best_err);
592     if(err<_best_err){
593       _best_err=err;
594       best_site=site;
595     }
596   }
597   _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site];
598   _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site];
599   return _best_err;
600 }
601 #endif
602
603 static unsigned oc_mcenc_ysatd_halfpel_mbrefine(const oc_enc_ctx *_enc,
604  int _mbi,int _vec[2],unsigned _best_err,int _frame){
605   const unsigned char *src;
606   const unsigned char *ref;
607   const ptrdiff_t     *frag_buf_offs;
608   const ptrdiff_t     *fragis;
609   int                  offset_y[9];
610   int                  ystride;
611   int                  mvoffset_base;
612   int                  best_site;
613   int                  sitei;
614   int                  err;
615   src=_enc->state.ref_frame_data[OC_FRAME_IO];
616   ref=_enc->state.ref_frame_data[_frame];
617   frag_buf_offs=_enc->state.frag_buf_offs;
618   fragis=_enc->state.mb_maps[_mbi][0];
619   ystride=_enc->state.ref_ystride[0];
620   mvoffset_base=_vec[0]+_vec[1]*ystride;
621   offset_y[0]=offset_y[1]=offset_y[2]=-ystride;
622   offset_y[3]=offset_y[5]=0;
623   offset_y[6]=offset_y[7]=offset_y[8]=ystride;
624   best_site=4;
625   for(sitei=0;sitei<8;sitei++){
626     int site;
627     int xmask;
628     int ymask;
629     int dx;
630     int dy;
631     int mvoffset0;
632     int mvoffset1;
633     site=OC_SQUARE_SITES[0][sitei];
634     dx=OC_SQUARE_DX[site];
635     dy=OC_SQUARE_DY[site];
636     /*The following code SHOULD be equivalent to
637         oc_state_get_mv_offsets(&_mcenc->enc.state,&mvoffset0,&mvoffset1,
638          (_vec[0]<<1)+dx,(_vec[1]<<1)+dy,ref_ystride,0);
639       However, it should also be much faster, as it involves no multiplies and
640        doesn't have to handle chroma vectors.*/
641     xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx);
642     ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy);
643     mvoffset0=mvoffset_base+(dx&xmask)+(offset_y[site]&ymask);
644     mvoffset1=mvoffset_base+(dx&~xmask)+(offset_y[site]&~ymask);
645     err=oc_satd16_halfpel(_enc,frag_buf_offs,fragis,
646      mvoffset0,mvoffset1,src,ref,ystride,_best_err);
647     if(err<_best_err){
648       _best_err=err;
649       best_site=site;
650     }
651   }
652   _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site];
653   _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site];
654   return _best_err;
655 }
656
657 void oc_mcenc_refine1mv(oc_enc_ctx *_enc,int _mbi,int _frame){
658   oc_mb_enc_info *embs;
659   int             vec[2];
660   embs=_enc->mb_info;
661   vec[0]=OC_DIV2(OC_MV_X(embs[_mbi].analysis_mv[0][_frame]));
662   vec[1]=OC_DIV2(OC_MV_Y(embs[_mbi].analysis_mv[0][_frame]));
663   embs[_mbi].satd[_frame]=oc_mcenc_ysatd_halfpel_mbrefine(_enc,
664    _mbi,vec,embs[_mbi].satd[_frame],_frame);
665   embs[_mbi].analysis_mv[0][_frame]=OC_MV(vec[0],vec[1]);
666 }
667
668 #if 0
669 static int oc_mcenc_ysad_halfpel_brefine(const oc_enc_ctx *_enc,
670  int _vec[2],const unsigned char *_src,const unsigned char *_ref,int _ystride,
671  int _offset_y[9],unsigned _best_err){
672   int mvoffset_base;
673   int best_site;
674   int sitei;
675   mvoffset_base=_vec[0]+_vec[1]*_ystride;
676   best_site=4;
677   for(sitei=0;sitei<8;sitei++){
678     unsigned err;
679     int      site;
680     int      xmask;
681     int      ymask;
682     int      dx;
683     int      dy;
684     int      mvoffset0;
685     int      mvoffset1;
686     site=OC_SQUARE_SITES[0][sitei];
687     dx=OC_SQUARE_DX[site];
688     dy=OC_SQUARE_DY[site];
689     /*The following code SHOULD be equivalent to
690         oc_state_get_mv_offsets(&_mcenc->enc.state,&mvoffset0,&mvoffset1,
691          (_vec[0]<<1)+dx,(_vec[1]<<1)+dy,ref_ystride,0);
692       However, it should also be much faster, as it involves no multiplies and
693        doesn't have to handle chroma vectors.*/
694     xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx);
695     ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy);
696     mvoffset0=mvoffset_base+(dx&xmask)+(_offset_y[site]&ymask);
697     mvoffset1=mvoffset_base+(dx&~xmask)+(_offset_y[site]&~ymask);
698     err=oc_enc_frag_sad2_thresh(_enc,_src,
699      _ref+mvoffset0,_ref+mvoffset1,ystride,_best_err);
700     if(err<_best_err){
701       _best_err=err;
702       best_site=site;
703     }
704   }
705   _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site];
706   _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site];
707   return _best_err;
708 }
709 #endif
710
711 static unsigned oc_mcenc_ysatd_halfpel_brefine(const oc_enc_ctx *_enc,
712  int _vec[2],const unsigned char *_src,const unsigned char *_ref,int _ystride,
713  int _offset_y[9],unsigned _best_err){
714   int mvoffset_base;
715   int best_site;
716   int sitei;
717   mvoffset_base=_vec[0]+_vec[1]*_ystride;
718   best_site=4;
719   for(sitei=0;sitei<8;sitei++){
720     unsigned err;
721     unsigned dc;
722     int      site;
723     int      xmask;
724     int      ymask;
725     int      dx;
726     int      dy;
727     int      mvoffset0;
728     int      mvoffset1;
729     site=OC_SQUARE_SITES[0][sitei];
730     dx=OC_SQUARE_DX[site];
731     dy=OC_SQUARE_DY[site];
732     /*The following code SHOULD be equivalent to
733         oc_state_get_mv_offsets(&_enc->state,&mvoffsets,0,
734          (_vec[0]<<1)+dx,(_vec[1]<<1)+dy);
735       However, it should also be much faster, as it involves no multiplies and
736        doesn't have to handle chroma vectors.*/
737     xmask=OC_SIGNMASK(((_vec[0]<<1)+dx)^dx);
738     ymask=OC_SIGNMASK(((_vec[1]<<1)+dy)^dy);
739     mvoffset0=mvoffset_base+(dx&xmask)+(_offset_y[site]&ymask);
740     mvoffset1=mvoffset_base+(dx&~xmask)+(_offset_y[site]&~ymask);
741     err=oc_enc_frag_satd2(_enc,&dc,_src,
742      _ref+mvoffset0,_ref+mvoffset1,_ystride);
743     err+=dc;
744     if(err<_best_err){
745       _best_err=err;
746       best_site=site;
747     }
748   }
749   _vec[0]=(_vec[0]<<1)+OC_SQUARE_DX[best_site];
750   _vec[1]=(_vec[1]<<1)+OC_SQUARE_DY[best_site];
751   return _best_err;
752 }
753
754 void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi){
755   oc_mb_enc_info      *embs;
756   const ptrdiff_t     *frag_buf_offs;
757   const ptrdiff_t     *fragis;
758   const unsigned char *src;
759   const unsigned char *ref;
760   int                  offset_y[9];
761   int                  ystride;
762   int                  bi;
763   ystride=_enc->state.ref_ystride[0];
764   frag_buf_offs=_enc->state.frag_buf_offs;
765   fragis=_enc->state.mb_maps[_mbi][0];
766   src=_enc->state.ref_frame_data[OC_FRAME_IO];
767   ref=_enc->state.ref_frame_data[OC_FRAME_PREV];
768   offset_y[0]=offset_y[1]=offset_y[2]=-ystride;
769   offset_y[3]=offset_y[5]=0;
770   offset_y[6]=offset_y[7]=offset_y[8]=ystride;
771   embs=_enc->mb_info;
772   for(bi=0;bi<4;bi++){
773     ptrdiff_t frag_offs;
774     int       vec[2];
775     frag_offs=frag_buf_offs[fragis[bi]];
776     vec[0]=OC_DIV2(OC_MV_X(embs[_mbi].block_mv[bi]));
777     vec[1]=OC_DIV2(OC_MV_Y(embs[_mbi].block_mv[bi]));
778     embs[_mbi].block_satd[bi]=oc_mcenc_ysatd_halfpel_brefine(_enc,vec,
779      src+frag_offs,ref+frag_offs,ystride,offset_y,embs[_mbi].block_satd[bi]);
780     embs[_mbi].ref_mv[bi]=OC_MV(vec[0],vec[1]);
781   }
782 }