stats_tools.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. /*Daala video codec
  2. Copyright (c) 2013 Daala project contributors. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. - Redistributions of source code must retain the above copyright notice, this
  6. list of conditions and the following disclaimer.
  7. - Redistributions in binary form must reproduce the above copyright notice,
  8. this list of conditions and the following disclaimer in the documentation
  9. and/or other materials provided with the distribution.
  10. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
  11. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  13. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  14. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  15. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  16. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  18. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  19. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "stats_tools.h"
  26. #include "od_defs.h"
  27. #include "od_filter.h"
  28. #include "od_intra.h"
  29. #include "../src/dct.h"
  30. #include "../src/intra.h"
  31. #define PRINT_SCALE (0)
  32. void mode_data_init(mode_data *_md,int _b_sz){
  33. int i;
  34. _md->n=0;
  35. _md->mean=0;
  36. _md->var=0;
  37. for(i=0;i<B_SZ_MAX*B_SZ_MAX;i++){
  38. _md->satd_avg[i]=0;
  39. }
  40. od_covmat_init(&_md->ref,_b_sz*_b_sz);
  41. od_covmat_init(&_md->res,_b_sz*_b_sz);
  42. }
  43. void mode_data_clear(mode_data *_md){
  44. od_covmat_clear(&_md->ref);
  45. od_covmat_clear(&_md->res);
  46. }
  47. void mode_data_reset(mode_data *_md){
  48. int i;
  49. _md->n=0;
  50. _md->mean=0;
  51. _md->var=0;
  52. for(i=0;i<B_SZ_MAX*B_SZ_MAX;i++){
  53. _md->satd_avg[i]=0;
  54. }
  55. od_covmat_reset(&_md->ref);
  56. od_covmat_reset(&_md->res);
  57. }
  58. /* update the input mean and variance */
  59. void mode_data_add_input(mode_data *_md,const unsigned char *_data,int _stride,
  60. int _b_sz){
  61. int n;
  62. int i;
  63. int j;
  64. n=_md->n*_b_sz*_b_sz;
  65. for(j=0;j<_b_sz;j++){
  66. for(i=0;i<_b_sz;i++){
  67. double delta;
  68. double s;
  69. n++;
  70. s=1.0/n;
  71. delta=_data[_stride*j+i]*INPUT_SCALE-_md->mean;
  72. _md->mean+=delta*s;
  73. _md->var+=delta*delta*(n-1)*s;
  74. }
  75. }
  76. _md->n++;
  77. }
  78. void mode_data_add_block(mode_data *_md,const od_coeff *_block,int _stride,
  79. int _ref){
  80. int j;
  81. int i;
  82. double buf[B_SZ*B_SZ];
  83. for(j=0;j<B_SZ;j++){
  84. for(i=0;i<B_SZ;i++){
  85. buf[B_SZ*j+i]=_block[_stride*j+i];
  86. }
  87. }
  88. if(_ref){
  89. od_covmat_add(&_md->ref,buf,1);
  90. }
  91. else{
  92. od_covmat_add(&_md->res,buf,1);
  93. }
  94. }
  95. void mode_data_combine(mode_data *_a,const mode_data *_b){
  96. double s;
  97. double delta;
  98. int i;
  99. if(_b->n==0){
  100. return;
  101. }
  102. s=((double)_b->n)/(_a->n+_b->n);
  103. delta=_b->mean-_a->mean;
  104. _a->mean+=delta*s;
  105. for(i=0;i<B_SZ_MAX*B_SZ_MAX;i++){
  106. _a->satd_avg[i]+=(_b->satd_avg[i]-_a->satd_avg[i])*s;
  107. }
  108. s*=_a->n;
  109. _a->var+=_b->var+delta*s;
  110. od_covmat_combine(&_a->ref,&_b->ref);
  111. od_covmat_combine(&_a->res,&_b->res);
  112. _a->n+=_b->n;
  113. }
  114. void mode_data_correct(mode_data *_md,int _b_sz){
  115. _md->var/=_md->n*_b_sz*_b_sz;
  116. od_covmat_correct(&_md->ref);
  117. od_covmat_correct(&_md->res);
  118. }
  119. void mode_data_print(mode_data *_md,const char *_label,double *_scale,
  120. int _b_sz){
  121. double cg_ref;
  122. double cg_res;
  123. int v;
  124. int u;
  125. double satd_avg;
  126. double bits_avg;
  127. cg_ref=10*log10(_md->var);
  128. cg_res=10*log10(_md->var);
  129. satd_avg=0;
  130. bits_avg=0;
  131. for(v=0;v<_b_sz;v++){
  132. for(u=0;u<_b_sz;u++){
  133. int i;
  134. int ii;
  135. double b;
  136. i=_b_sz*v+u;
  137. ii=_b_sz*_b_sz*i+i;
  138. cg_ref-=10*log10(_md->ref.cov[ii]*_scale[v]*_scale[u])/(_b_sz*_b_sz);
  139. cg_res-=10*log10(_md->res.cov[ii]*_scale[v]*_scale[u])/(_b_sz*_b_sz);
  140. satd_avg+=sqrt(_scale[v]*_scale[u])*_md->satd_avg[i];
  141. b=sqrt(_scale[v]*_scale[u]*_md->res.cov[ii]/2);
  142. bits_avg+=1+OD_LOG2(b)+M_LOG2E/b*_md->satd_avg[i];
  143. }
  144. }
  145. printf("%s Blocks %5i SATD %G Bits %G Mean %G Var %G CgRef %G CgRes %G Pg %G\n",
  146. _label,_md->n,satd_avg,bits_avg,_md->mean,_md->var,cg_ref,cg_res,cg_res-cg_ref);
  147. }
  148. void mode_data_params(mode_data *_this,double _b[B_SZ*B_SZ],double *_scale){
  149. int v;
  150. int u;
  151. int i;
  152. int ii;
  153. for(v=0;v<B_SZ;v++){
  154. for(u=0;u<B_SZ;u++){
  155. i=(v*B_SZ+u);
  156. ii=B_SZ*B_SZ*i+i;
  157. _b[i]=sqrt(_scale[v]*_scale[u]*_this->res.cov[ii]/2);
  158. }
  159. }
  160. }
  161. void intra_stats_init(intra_stats *_this,int _b_sz_log){
  162. int mode;
  163. _this->b_sz_log=_b_sz_log;
  164. mode_data_init(&_this->fr,1<<_b_sz_log);
  165. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  166. mode_data_init(&_this->md[mode],1<<_b_sz_log);
  167. }
  168. }
  169. void intra_stats_clear(intra_stats *_this){
  170. int i;
  171. mode_data_clear(&_this->fr);
  172. for(i=0;i<OD_INTRA_NMODES;i++){
  173. mode_data_clear(&_this->md[i]);
  174. }
  175. }
  176. void intra_stats_reset(intra_stats *_this){
  177. int i;
  178. mode_data_reset(&_this->fr);
  179. for(i=0;i<OD_INTRA_NMODES;i++){
  180. mode_data_reset(&_this->md[i]);
  181. }
  182. }
  183. void intra_stats_update(intra_stats *_this,const unsigned char *_data,
  184. int _stride,int _mode,const od_coeff *_ref,int _ref_stride,
  185. const double *_res,int _res_stride){
  186. int b_sz;
  187. mode_data *fr;
  188. mode_data *md;
  189. int j;
  190. int i;
  191. double buf[B_SZ_MAX*B_SZ_MAX];
  192. b_sz=1<<_this->b_sz_log;
  193. fr=&_this->fr;
  194. md=&_this->md[_mode];
  195. /* Update the input mean and variance. */
  196. mode_data_add_input(fr,_data,_stride,b_sz);
  197. mode_data_add_input(md,_data,_stride,b_sz);
  198. /* Update the reference mean and covariance. */
  199. for(j=0;j<b_sz;j++){
  200. for(i=0;i<b_sz;i++){
  201. buf[b_sz*j+i]=_ref[_ref_stride*j+i];
  202. }
  203. }
  204. od_covmat_add(&fr->ref,buf,1);
  205. od_covmat_add(&md->ref,buf,1);
  206. /* Update the residual mean and covariance. */
  207. for(j=0;j<b_sz;j++){
  208. for(i=0;i<b_sz;i++){
  209. buf[b_sz*j+i]=_res[_res_stride*j+i];
  210. }
  211. }
  212. od_covmat_add(&fr->res,buf,1);
  213. od_covmat_add(&md->res,buf,1);
  214. /* Update the average SATD. */
  215. for(j=0;j<b_sz;j++){
  216. for(i=0;i<b_sz;i++){
  217. double satd;
  218. satd=abs(buf[b_sz*j+i]);
  219. fr->satd_avg[b_sz*j+i]+=(satd-fr->satd_avg[b_sz*j+i])/fr->n;
  220. md->satd_avg[b_sz*j+i]+=(satd-md->satd_avg[b_sz*j+i])/md->n;
  221. }
  222. }
  223. }
  224. void intra_stats_correct(intra_stats *_this){
  225. int mode;
  226. mode_data_correct(&_this->fr,1<<_this->b_sz_log);
  227. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  228. mode_data_correct(&_this->md[mode],1<<_this->b_sz_log);
  229. }
  230. }
  231. void intra_stats_print(intra_stats *_this,const char *_label,
  232. double *_scale){
  233. int mode;
  234. printf("%s\n",_label);
  235. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  236. char label[16];
  237. sprintf(label,"Mode %i",mode);
  238. mode_data_print(&_this->md[mode],label,_scale,1<<_this->b_sz_log);
  239. }
  240. mode_data_print(&_this->fr,"Pooled",_scale,1<<_this->b_sz_log);
  241. }
  242. void intra_stats_combine(intra_stats *_this,const intra_stats *_that){
  243. int mode;
  244. mode_data_combine(&_this->fr,&_that->fr);
  245. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  246. mode_data_combine(&_this->md[mode],&_that->md[mode]);
  247. }
  248. }
  249. /* compute the scale factors for the DCT and TDLT transforms */
  250. double VP8_SCALE[OD_NBSIZES][B_SZ_MAX];
  251. double OD_SCALE[OD_NBSIZES][B_SZ_MAX];
  252. #define SCALE_BITS (14)
  253. void vp8_scale_init(double *_vp8_scale,int _b_sz_log){
  254. int b_sz;
  255. int j;
  256. int i;
  257. od_coeff buf[B_SZ_MAX];
  258. b_sz=1<<_b_sz_log;
  259. for(i=0;i<b_sz;i++){
  260. for(j=0;j<b_sz;j++){
  261. buf[j]=i!=j?0:(1<<SCALE_BITS);
  262. }
  263. (*OD_IDCT_1D[_b_sz_log-OD_LOG_BSIZE0])(buf,1,buf);
  264. _vp8_scale[i]=0;
  265. for(j=0;j<b_sz;j++){
  266. double c=((double)buf[j])/(1<<SCALE_BITS);
  267. _vp8_scale[i]+=c*c;
  268. }
  269. #if PRINT_SCALE
  270. printf("%s%- 24.18G",i==0?"":" ",_vp8_scale[i]);
  271. #endif
  272. }
  273. #if PRINT_SCALE
  274. printf("\n");
  275. #endif
  276. }
  277. #define APPLY_PREFILTER (1)
  278. #define APPLY_POSTFILTER (1)
  279. void od_scale_init(double *_od_scale,int _b_sz_log){
  280. int b_sz;
  281. int i;
  282. int j;
  283. od_coeff buf[2*B_SZ_MAX];
  284. b_sz=1<<_b_sz_log;
  285. for(i=0;i<b_sz;i++){
  286. for(j=0;j<2*b_sz;j++){
  287. buf[j]=(b_sz>>1)+i!=j?0:(1<<SCALE_BITS);
  288. }
  289. (*OD_IDCT_1D[_b_sz_log-OD_LOG_BSIZE0])(&buf[b_sz>>1],1,&buf[b_sz>>1]);
  290. #if APPLY_POSTFILTER
  291. (*NE_POST_FILTER[_b_sz_log-OD_LOG_BSIZE0])(buf,buf);
  292. (*NE_POST_FILTER[_b_sz_log-OD_LOG_BSIZE0])(&buf[b_sz],&buf[b_sz]);
  293. #endif
  294. _od_scale[i]=0;
  295. for(j=0;j<2*b_sz;j++){
  296. double c=((double)buf[j])/(1<<SCALE_BITS);
  297. _od_scale[i]+=c*c;
  298. }
  299. #if PRINT_SCALE
  300. printf("%s%- 24.18G",i==0?"":" ",_od_scale[i]);
  301. #endif
  302. }
  303. #if PRINT_SCALE
  304. printf("\n");
  305. #endif
  306. }
  307. #define SCALE_SATD (1)
  308. /* find the best vp8 mode */
  309. int vp8_select_mode(const unsigned char *_data,int _stride,double *_weight){
  310. int best_mode;
  311. double best_satd;
  312. double next_best_satd;
  313. double *vp8_scale;
  314. int mode;
  315. best_mode=0;
  316. best_satd=UINT_MAX;
  317. next_best_satd=best_satd;
  318. vp8_scale=VP8_SCALE[B_SZ_LOG-OD_LOG_BSIZE0];
  319. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  320. unsigned char block[B_SZ*B_SZ];
  321. od_coeff buf[B_SZ*B_SZ];
  322. int j;
  323. int i;
  324. double satd;
  325. memset(block,0,B_SZ*B_SZ);
  326. vp8_intra_predict(block,B_SZ,_data,_stride,mode);
  327. for(j=0;j<B_SZ;j++){
  328. for(i=0;i<B_SZ;i++){
  329. buf[B_SZ*j+i]=block[B_SZ*j+i]-_data[_stride*j+i];
  330. }
  331. }
  332. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  333. (*OD_FDCT_2D[B_SZ_LOG-OD_LOG_BSIZE0])(buf,B_SZ,buf,B_SZ);
  334. #else
  335. # error "Need an fDCT implementation for this block size."
  336. #endif
  337. satd=0;
  338. for(j=0;j<B_SZ;j++){
  339. for(i=0;i<B_SZ;i++){
  340. #if SCALE_SATD
  341. satd+=sqrt(vp8_scale[j]*vp8_scale[i])*abs(buf[B_SZ*j+i]);
  342. #else
  343. satd+=abs(buf[B_SZ*j+i]);
  344. #endif
  345. }
  346. }
  347. if(satd<best_satd){
  348. next_best_satd=best_satd;
  349. best_satd=satd;
  350. best_mode=mode;
  351. }
  352. else{
  353. if(satd<next_best_satd){
  354. next_best_satd=satd;
  355. }
  356. }
  357. }
  358. if(_weight!=NULL){
  359. *_weight=best_mode!=0?next_best_satd-best_satd:1;
  360. }
  361. return best_mode;
  362. }
  363. int od_select_mode_bits(const od_coeff *_block,double *_weight,
  364. double _b[OD_INTRA_NMODES][B_SZ*B_SZ]){
  365. const od_coeff *c;
  366. int best_mode;
  367. double best_bits;
  368. double next_best_bits;
  369. double *od_scale;
  370. int mode;
  371. c=_block+4*B_SZ*B_SZ;
  372. best_mode=0;
  373. best_bits=UINT_MAX;
  374. next_best_bits=best_bits;
  375. od_scale=OD_SCALE[B_SZ_LOG-OD_LOG_BSIZE0];
  376. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  377. double p[B_SZ*B_SZ];
  378. double bits;
  379. int j;
  380. int i;
  381. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  382. #if 0
  383. (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,_block,_stride,mode);
  384. #else
  385. (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,B_SZ,_block,mode);
  386. #endif
  387. #else
  388. # error "Need a predictor implementation for this block size."
  389. #endif
  390. bits=0;
  391. for(j=0;j<B_SZ;j++){
  392. for(i=0;i<B_SZ;i++){
  393. double res;
  394. res=sqrt(od_scale[j]*od_scale[i])*
  395. abs(c[B_SZ*j+i]-(od_coeff)floor(p[B_SZ*j+i]+0.5));
  396. bits+=1+OD_LOG2(_b[mode][j*B_SZ+i])+M_LOG2E/_b[mode][j*B_SZ+i]*res;
  397. }
  398. }
  399. if(bits<best_bits){
  400. next_best_bits=best_bits;
  401. best_bits=bits;
  402. best_mode=mode;
  403. }
  404. else{
  405. if(bits<next_best_bits){
  406. next_best_bits=bits;
  407. }
  408. }
  409. }
  410. if(_weight!=NULL){
  411. *_weight=best_mode!=0?next_best_bits-best_bits:1;
  412. }
  413. return best_mode;
  414. }
  415. int od_select_mode_satd(const od_coeff *_block,double *_weight,int _b_sz_log){
  416. int b_sz;
  417. const od_coeff *c;
  418. int best_mode;
  419. double best_satd;
  420. double next_best_satd;
  421. double *od_scale;
  422. int mode;
  423. b_sz=1<<_b_sz_log;
  424. c=_block+4*b_sz*b_sz;
  425. best_mode=0;
  426. best_satd=UINT_MAX;
  427. next_best_satd=best_satd;
  428. od_scale=OD_SCALE[_b_sz_log-OD_LOG_BSIZE0];
  429. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  430. double p[B_SZ_MAX*B_SZ_MAX];
  431. double satd;
  432. int j;
  433. int i;
  434. (*NE_INTRA_MULT[_b_sz_log-OD_LOG_BSIZE0])(p,b_sz,_block,mode);
  435. satd=0;
  436. for(j=0;j<b_sz;j++){
  437. for(i=0;i<b_sz;i++){
  438. #if SCALE_SATD
  439. satd+=sqrt(od_scale[j]*od_scale[i])*
  440. abs(c[b_sz*j+i]-(od_coeff)floor(p[b_sz*j+i]+0.5));
  441. #else
  442. satd+=abs(c[b_sz*j+i]-(od_coeff)floor(p[b_sz*j+i]+0.5));
  443. #endif
  444. }
  445. }
  446. if(satd<best_satd){
  447. next_best_satd=best_satd;
  448. best_mode=mode;
  449. best_satd=satd;
  450. }
  451. else{
  452. if(satd<next_best_satd){
  453. next_best_satd=satd;
  454. }
  455. }
  456. }
  457. if(_weight!=NULL){
  458. *_weight=best_mode!=0?next_best_satd-best_satd:1;
  459. }
  460. return best_mode;
  461. }
  462. int ne_apply_to_blocks(void *_ctx,int _ctx_sz,int _plmask,int _padding,
  463. plane_start_func _start,int _nfuncs,const block_func *_funcs,
  464. plane_finish_func _finish,int _argc,const char *_argv[]){
  465. int ai;
  466. #pragma omp parallel for schedule(dynamic)
  467. for(ai=1;ai<_argc;ai++){
  468. FILE *fin;
  469. video_input vid;
  470. video_input_info info;
  471. video_input_ycbcr ycbcr;
  472. int pli;
  473. int tid;
  474. unsigned char *ctx;
  475. fin=fopen(_argv[ai],"rb");
  476. if(fin==NULL){
  477. fprintf(stderr,"Could not open '%s' for reading.\n",_argv[ai]);
  478. continue;
  479. }
  480. if(video_input_open(&vid,fin)<0){
  481. fprintf(stderr,"Error reading video info from '%s'.\n",_argv[ai]);
  482. continue;
  483. }
  484. video_input_get_info(&vid,&info);
  485. if(video_input_fetch_frame(&vid,ycbcr,NULL)<0){
  486. fprintf(stderr,"Error reading first frame from '%s'.\n",_argv[ai]);
  487. continue;
  488. }
  489. tid=OD_OMP_GET_THREAD;
  490. ctx=((unsigned char *)_ctx)+tid*_ctx_sz;
  491. for(pli=0;pli<3;pli++){
  492. if(_plmask&1<<pli){
  493. int x0;
  494. int y0;
  495. int nxblocks;
  496. int nyblocks;
  497. get_intra_dims(&info,pli,_padding,&x0,&y0,&nxblocks,&nyblocks);
  498. if(_start!=NULL){
  499. (*_start)(ctx,_argv[ai],&info,pli,nxblocks,nyblocks);
  500. }
  501. if(_funcs!=NULL){
  502. int f;
  503. for(f=0;f<_nfuncs;f++){
  504. if(_funcs[f]!=NULL){
  505. const unsigned char *data;
  506. int stride;
  507. int bj;
  508. int bi;
  509. data=ycbcr[pli].data;
  510. stride=ycbcr[pli].stride;
  511. for(bj=0;bj<nyblocks;bj++){
  512. int y;
  513. y=y0+B_SZ*bj;
  514. for(bi=0;bi<nxblocks;bi++){
  515. int x;
  516. x=x0+B_SZ*bi;
  517. (*_funcs[f])(ctx,&data[stride*y+x],stride,bi,bj);
  518. }
  519. }
  520. }
  521. }
  522. }
  523. if(_finish!=NULL){
  524. (*_finish)(ctx);
  525. }
  526. }
  527. }
  528. video_input_close(&vid);
  529. }
  530. return EXIT_SUCCESS;
  531. }