mcenc.c 28 KB

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