block_size_analysis.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. /*Daala video codec
  2. Copyright (c) 2002-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 <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include "../src/odintrin.h"
  27. #include "vidinput.h"
  28. #include "../src/filter.h"
  29. #include "../src/dct.h"
  30. #include "../src/pvq.h"
  31. #if defined(_WIN32)
  32. #include <io.h>
  33. #include <fcntl.h>
  34. #endif
  35. #include "getopt.h"
  36. #include "../src/block_size.h"
  37. #include "../src/block_size_enc.h"
  38. #include <math.h>
  39. static void usage(char **_argv){
  40. fprintf(stderr,"Usage: %s [options] <input> <output>\n"
  41. " <reference> and <input> may be either YUV4MPEG or Ogg Theora files.\n\n"
  42. " Options:\n"
  43. " --intra Intraframes only.\n"
  44. " --limit N Only read N frames from input.\n"
  45. " --ext N Encode the final frame N more times.\n"
  46. " --fps N Override output fps.\n"
  47. " --ref N Reference stream.\n"
  48. " --pvqk N PVQ K parameter.\n",_argv[0]);
  49. }
  50. static const char *CHROMA_TAGS[4]={" C420jpeg",""," C422jpeg"," C444"};
  51. /* Warning, this will fail for images larger than 2024 x 2024 */
  52. #define MAX_VAR_BLOCKS 1024
  53. #define SQUARE(x) ((int)(x)*(int)(x))
  54. /* Actual 2D coding gains of lapped transforms (the 32x32 one is made-up). We divide by 6 to get bits. */
  55. #define CG4 (15.943/6)
  56. #define CG8 (16.7836/6)
  57. #define CG16 (16.9986/6)
  58. #define CG32 (17.1/6)
  59. #define OFF8 (1)
  60. #define OFF16 (2)
  61. #define OFF16_8 (1)
  62. #define OFF32_8 (1)
  63. #define COUNT16_8 (3+2*OFF16_8)
  64. #define COUNT32_8 (7+2*OFF32_8)
  65. #define PSY_LAMBDA .65
  66. int switch_decision(unsigned char *img, int w, int h, int stride, int ow, int oh)
  67. {
  68. int i,j;
  69. int h8,w8,h32,w32;
  70. static unsigned char dec8[MAX_VAR_BLOCKS>>2][MAX_VAR_BLOCKS>>2];
  71. #if 0
  72. int h4,w4,h16,w16;
  73. static int Sx[MAX_VAR_BLOCKS][MAX_VAR_BLOCKS];
  74. static int Sxx[MAX_VAR_BLOCKS][MAX_VAR_BLOCKS];
  75. static int Sx4[MAX_VAR_BLOCKS>>1][MAX_VAR_BLOCKS>>1];
  76. static int Sxx4[MAX_VAR_BLOCKS>>1][MAX_VAR_BLOCKS>>1];
  77. static int var[MAX_VAR_BLOCKS][MAX_VAR_BLOCKS];
  78. static int var_1[MAX_VAR_BLOCKS][MAX_VAR_BLOCKS];
  79. static int var8[MAX_VAR_BLOCKS>>1][MAX_VAR_BLOCKS>>1];
  80. static int var8_1[MAX_VAR_BLOCKS>>1][MAX_VAR_BLOCKS>>1];
  81. static float dummy[MAX_VAR_BLOCKS][MAX_VAR_BLOCKS];
  82. static float dummy8[MAX_VAR_BLOCKS][MAX_VAR_BLOCKS];
  83. static float nmr4[MAX_VAR_BLOCKS>>1][MAX_VAR_BLOCKS>>1];
  84. static float nmr8[MAX_VAR_BLOCKS>>2][MAX_VAR_BLOCKS>>2];
  85. static float cg8[MAX_VAR_BLOCKS>>2][MAX_VAR_BLOCKS>>2];
  86. static float nmr16[MAX_VAR_BLOCKS>>3][MAX_VAR_BLOCKS>>3];
  87. static float cg16[MAX_VAR_BLOCKS>>3][MAX_VAR_BLOCKS>>3];
  88. static float nmr32[MAX_VAR_BLOCKS>>4][MAX_VAR_BLOCKS>>4];
  89. static float cg32[MAX_VAR_BLOCKS>>4][MAX_VAR_BLOCKS>>4];
  90. const unsigned char *x;
  91. #endif
  92. (void)ow;
  93. (void)oh;
  94. w>>=1;
  95. h>>=1;
  96. w8 = w>>2;
  97. h8 = h>>2;
  98. w32 = w>>4;
  99. h32 = h>>4;
  100. #if 0
  101. w4 = w>>1;
  102. h4 = h>>1;
  103. w16 = w>>3;
  104. h16 = h>>3;
  105. x = img;
  106. for(i=0;i<h;i++){
  107. for(j=0;j<w;j++){
  108. Sx[i][j]=x[2*j]+x[2*j+1]+x[stride+2*j]+x[stride+2*j+1];
  109. Sxx[i][j]=SQUARE(x[2*j])+SQUARE(x[2*j+1])+SQUARE(x[stride+2*j])+SQUARE(x[stride+2*j+1]);
  110. }
  111. x+=2*stride;
  112. }
  113. for(i=0;i<h4;i++){
  114. for(j=0;j<w4;j++){
  115. Sxx4[i][j] = Sxx[2*i][2*j] + Sxx[2*i][2*j+1] + Sxx[2*i+1][2*j] + Sxx[2*i+1][2*j+1];
  116. Sx4[i][j] = Sx [2*i][2*j] + Sx [2*i][2*j+1] + Sx [2*i+1][2*j] + Sx [2*i+1][2*j+1];
  117. }
  118. }
  119. for(i=0;i<h-1;i++){
  120. for(j=0;j<w-1;j++){
  121. int sum_x;
  122. int sum_xx;
  123. int var_floor;
  124. sum_x=Sx[i][j]+Sx[i][j+1]+Sx[i+1][j]+Sx[i+1][j+1];
  125. sum_xx=Sxx[i][j]+Sxx[i][j+1]+Sxx[i+1][j]+Sxx[i+1][j+1];
  126. var[i][j]=(sum_xx-(SQUARE(sum_x)>>4))>>5;
  127. var_floor = 4+(sum_x>>8);
  128. if (var[i][j]<var_floor)var[i][j]=var_floor;
  129. /*printf("%d ", var[i][j]);*/
  130. var_1[i][j] = 16384/var[i][j];
  131. }
  132. /*printf("\n");*/
  133. }
  134. for(i=0;i<h4-1;i++){
  135. for(j=0;j<w4-1;j++){
  136. int sum_x;
  137. int sum_xx;
  138. int var_floor;
  139. sum_x =Sx4 [i][j]+Sx4 [i][j+1]+Sx4 [i+1][j]+Sx4 [i+1][j+1];
  140. sum_xx=Sxx4[i][j]+Sxx4[i][j+1]+Sxx4[i+1][j]+Sxx4[i+1][j+1];
  141. var8[i][j]=(sum_xx-(SQUARE(sum_x)>>6))>>5;
  142. var_floor = 4+(sum_x>>8);
  143. if (var8[i][j]<var_floor)var8[i][j]=var_floor;
  144. /*printf("%d ", var8[i][j]);*/
  145. var8_1[i][j] = 16384/var8[i][j];
  146. }
  147. /*printf("\n");*/
  148. }
  149. for(i=1;i<h4-1;i++){
  150. for(j=1;j<w4-1;j++){
  151. int k,m;
  152. int sum_var=0;
  153. int sum_var_1=0;
  154. float psy=0;
  155. float noise;
  156. for(k=0;k<3;k++){
  157. for(m=0;m<3;m++){
  158. sum_var+=var[2*i-1+k][2*j-1+m];
  159. }
  160. }
  161. noise = sum_var/(3*3);
  162. for(k=0;k<3;k++){
  163. for(m=0;m<3;m++){
  164. psy += OD_LOG2(1+noise*var_1[2*i-1+k][2*j-1+m]/16384.);
  165. }
  166. }
  167. psy /= (3*3);
  168. psy -= 1;
  169. nmr4[i][j] = psy;
  170. /*printf("%f ", nmr4[i][j]);*/
  171. }
  172. /*printf("\n");*/
  173. }
  174. for(i=1;i<h8-1;i++){
  175. for(j=1;j<w8-1;j++){
  176. int k,m;
  177. int sum_var=0;
  178. int sum_var_1=0;
  179. float nmr4_avg;
  180. float cgl, cgs;
  181. float noise;
  182. float psy;
  183. for(k=0;k<COUNT8;k++){
  184. for(m=0;m<COUNT8;m++){
  185. sum_var +=var[4*i-OFF8+k][4*j-OFF8+m];
  186. }
  187. }
  188. noise = sum_var/(COUNT8*COUNT8);
  189. psy=0;
  190. for(k=0;k<COUNT8;k++){
  191. for(m=0;m<COUNT8;m++){
  192. psy += OD_LOG2(1+noise*var_1[4*i-OFF8+k][4*j-OFF8+m]/16384.);
  193. }
  194. }
  195. psy /= (COUNT8*COUNT8);
  196. psy -= 1;
  197. nmr8[i][j] = psy;
  198. nmr4_avg = .25f*(nmr4[2*i][2*j]+nmr4[2*i][2*j+1]+nmr4[2*i+1][2*j]+nmr4[2*i+1][2*j+1]);
  199. cgs = CG4 - PSY_LAMBDA*(nmr4_avg);
  200. cgl = CG8 - PSY_LAMBDA*(nmr8[i][j]);
  201. if (cgl>=cgs)
  202. {
  203. dec8[i][j] = 1;
  204. cg8[i][j] = CG8;
  205. } else {
  206. nmr8[i][j] = nmr4_avg;
  207. dec8[i][j] = 0;
  208. cg8[i][j] = CG4;
  209. }
  210. /*printf("%d ", dec8[i][j]);*/
  211. }
  212. /*printf("\n");*/
  213. }
  214. for(i=1;i<h16-1;i++){
  215. for(j=1;j<w16-1;j++){
  216. int k,m;
  217. int sum_var=0;
  218. int sum_var8=0;
  219. int sum_var_1=0;
  220. float nmr8_avg;
  221. float cgl,cgs;
  222. float noise;
  223. float noise8;
  224. float psy;
  225. float psy8;
  226. for(k=0;k<COUNT16;k++){
  227. for(m=0;m<COUNT16;m++){
  228. sum_var+=var[8*i-OFF16+k][8*j-OFF16+m];
  229. }
  230. }
  231. noise = sum_var/(float)(COUNT16*COUNT16);
  232. for(k=0;k<COUNT16_8;k++){
  233. for(m=0;m<COUNT16_8;m++){
  234. sum_var8+=var8[4*i-OFF16_8+k][4*j-OFF16_8+m];
  235. }
  236. }
  237. noise8 = sum_var8/(float)(COUNT16_8*COUNT16_8);
  238. psy=0;
  239. for(k=0;k<COUNT16;k++){
  240. for(m=0;m<COUNT16;m++){
  241. psy += OD_LOG2(1+noise*var_1[8*i-OFF16+k][8*j-OFF16+m]/16384.);
  242. }
  243. }
  244. psy /= (COUNT16*COUNT16);
  245. psy -= 1;
  246. psy8=0;
  247. for(k=0;k<COUNT16_8;k++){
  248. for(m=0;m<COUNT16_8;m++){
  249. psy8 += OD_LOG2(1+noise8*var8_1[4*i-OFF16_8+k][4*j-OFF16_8+m]/16384.);
  250. }
  251. }
  252. psy8 /= (COUNT16_8*COUNT16_8);
  253. psy8 -= 1;
  254. psy = OD_MAXF(psy, .25*psy8);
  255. /*psy = .5*(psy+psy8);*/
  256. nmr16[i][j] = psy;
  257. nmr8_avg = .25f*(nmr8[2*i][2*j]+nmr8[2*i][2*j+1]+nmr8[2*i+1][2*j]+nmr8[2*i+1][2*j+1]);
  258. cg16[i][j] = .25*(cg8[2*i][2*j] + cg8[2*i][2*j+1] + cg8[2*i+1][2*j] + cg8[2*i+1][2*j+1]);
  259. cgs = cg16[i][j] - PSY_LAMBDA*(nmr8_avg);
  260. cgl = CG16 - PSY_LAMBDA*(nmr16[i][j]);
  261. /*printf("%f ", psy);*/
  262. if (cgl>=cgs)
  263. {
  264. dec8[2*i][2*j] = 2;
  265. dec8[2*i][2*j+1] = 2;
  266. dec8[2*i+1][2*j] = 2;
  267. dec8[2*i+1][2*j+1] = 2;
  268. cg16[i][j] = CG16;
  269. } else {
  270. nmr16[i][j] = nmr8_avg;
  271. }
  272. }
  273. /*printf("\n");*/
  274. }
  275. #if 1
  276. for(i=1;i<h32-1;i++){
  277. for(j=1;j<w32-1;j++){
  278. int k,m;
  279. int sum_var=0;
  280. int sum_var_1=0;
  281. int sum_var8=0;
  282. float nmr16_avg;
  283. float cgl,cgs;
  284. float noise, psy;
  285. float noise8, psy8;
  286. for(k=0;k<COUNT32;k++){
  287. for(m=0;m<COUNT32;m++){
  288. sum_var +=var[16*i-OFF32+k][16*j-OFF32+m];
  289. }
  290. }
  291. noise = sum_var/(float)(COUNT32*COUNT32);
  292. for(k=0;k<COUNT32_8;k++){
  293. for(m=0;m<COUNT32_8;m++){
  294. sum_var8+=var8[8*i-OFF32_8+k][8*j-OFF32_8+m];
  295. }
  296. }
  297. noise8 = sum_var8/(float)(COUNT32_8*COUNT32_8);
  298. psy=0;
  299. for(k=0;k<COUNT32;k++){
  300. for(m=0;m<COUNT32;m++){
  301. psy += OD_LOG2(1.+noise*var_1[16*i-OFF32+k][16*j-OFF32+m]/16384.);
  302. }
  303. }
  304. psy /= (COUNT32*COUNT32);
  305. psy -= 1;
  306. psy8=0;
  307. for(k=0;k<COUNT32_8;k++){
  308. for(m=0;m<COUNT32_8;m++){
  309. psy8 += OD_LOG2(1+noise8*var8_1[8*i-OFF32_8+k][8*j-OFF32_8+m]/16384.);
  310. }
  311. }
  312. psy8 /= (COUNT32_8*COUNT32_8);
  313. psy8 -= 1;
  314. psy = OD_MAXF(psy, .25*psy8);
  315. /*psy = .5*(psy+psy8);*/
  316. /*psy += psy8;*/
  317. nmr32[i][j] = psy;
  318. nmr16_avg = .25f*(nmr16[2*i][2*j]+nmr16[2*i][2*j+1]+nmr16[2*i+1][2*j]+nmr16[2*i+1][2*j+1]);
  319. cg32[i][j] = .25*(cg16[2*i][2*j] + cg16[2*i][2*j+1] + cg16[2*i+1][2*j] + cg16[2*i+1][2*j+1]);
  320. cgs = cg32[i][j] - PSY_LAMBDA*(nmr16_avg);
  321. cgl = CG32 - PSY_LAMBDA*(nmr32[i][j]);
  322. /*printf("%f ", psy8);*/
  323. if (cgl>=cgs)
  324. {
  325. for(k=0;k<4;k++){
  326. for(m=0;m<4;m++){
  327. dec8[4*i+k][4*j+m]=3;
  328. }
  329. }
  330. cg32[i][j] = CG32;
  331. } else {
  332. nmr32[i][j] = nmr16_avg;
  333. }
  334. }
  335. /*printf("\n");*/
  336. }
  337. #endif
  338. #endif
  339. /* Replace decision with the one from `od_split_superblock` */
  340. if (1)
  341. {
  342. od_block_size_comp bs;
  343. for(i=1;i<h32-1;i++){
  344. for(j=1;j<w32-1;j++){
  345. int k,m;
  346. int dec[4][4];
  347. od_split_superblock(&bs, img+32*stride*i+32*j, stride, NULL, 0,
  348. dec, 21 << OD_COEFF_SHIFT);
  349. for(k=0;k<4;k++)
  350. for(m=0;m<4;m++)
  351. dec8[4*i+k][4*j+m]=dec[k][m];
  352. #if 0
  353. for(k=0;k<16;k++)
  354. {
  355. for(m=0;m<16;m++)
  356. {
  357. var[16*i+k][16*j+m]=bs.img_stats.Var4[k+3][m+3];
  358. var_1[16*i+k][16*j+m]=bs.img_stats.invVar4[k+3][m+3];
  359. }
  360. }
  361. for(k=0;k<8;k++)
  362. {
  363. for(m=0;m<8;m++)
  364. {
  365. dummy[8*i+k][8*j+m]=bs.psy4[k][m];
  366. }
  367. }
  368. for(k=0;k<4;k++)
  369. {
  370. for(m=0;m<4;m++)
  371. {
  372. dummy8[4*i+k][4*j+m]=bs.psy8[k][m];
  373. }
  374. }
  375. for(k=0;k<8;k++)
  376. {
  377. for(m=0;m<8;m++)
  378. {
  379. var8[8*i+k][8*j+m]=bs.img_stats.Var8[k+2][m+2];
  380. var8_1[8*i+k][8*j+m]=bs.img_stats.invVar8[k+2][m+2];
  381. }
  382. }
  383. #endif
  384. }
  385. }
  386. }
  387. #if 0
  388. for(i=0;i<h;i++){
  389. for(j=0;j<w;j++){
  390. printf("%d ", var[i][j]);
  391. }
  392. printf("\n");
  393. }
  394. #endif
  395. #if 0
  396. for(i=8;i<h4-8;i++){
  397. for(j=8;j<w4-8;j++){
  398. printf("%f ", dummy[i][j]);
  399. }
  400. printf("\n");
  401. }
  402. #endif
  403. #if 0
  404. for(i=4;i<h8-4;i++){
  405. for(j=4;j<w8-4;j++){
  406. printf("%f ", dummy8[i][j]);
  407. }
  408. printf("\n");
  409. }
  410. #endif
  411. #if 0
  412. for(i=4;i<h8-4;i++){
  413. for(j=4;j<w8-4;j++){
  414. printf("%d ", dec8[i][j]);
  415. }
  416. printf("\n");
  417. }
  418. #endif
  419. #if 0
  420. fprintf(stderr, "size : %dx%d\n", (w<<1), (h<<1));
  421. for(i=0;i<(h<<1);i++){
  422. for(j=0;j<1296;j++){
  423. putc(dec8[i>>3][j>>3], stdout);
  424. }
  425. }
  426. #endif
  427. #if 0
  428. {
  429. /*Raw mode data with offsets to match the 4x8 training tool's padding.*/
  430. int wn=(ow-16)>>2;
  431. int hn=(oh-16)>>2;
  432. fprintf(stderr, "size : %dx%d\n", wn, hn);
  433. for(i=0;i<hn;i++){
  434. for(j=0;j<wn;j++){
  435. int posi=(i>>1)+1;
  436. int posj=(j>>1)+1;
  437. if(posi>=4 && posi<(h8-4) &&posj>=4 && posj<(w8-4))putc(dec8[posi][posj], stdout);
  438. else putc(0, stdout);
  439. }
  440. }
  441. }
  442. #endif
  443. #if 1
  444. for(i=4;i<h8-4;i++){
  445. for(j=4;j<w8-4;j++){
  446. if ((i&3)==0 && (j&3)==0){
  447. int k;
  448. for(k=0;k<32;k++)
  449. img[i*stride*8+j*8+k] = 0;
  450. for(k=0;k<32;k++)
  451. img[(8*i+k)*stride+j*8] = 0;
  452. }
  453. if ((i&1)==0 && (j&1)==0 && dec8[i][j]==2){
  454. int k;
  455. for(k=0;k<16;k++)
  456. img[i*stride*8+j*8+k] = 0;
  457. for(k=0;k<16;k++)
  458. img[(8*i+k)*stride+j*8] = 0;
  459. }
  460. if (dec8[i][j]<=1){
  461. int k;
  462. for(k=0;k<8;k++)
  463. img[i*stride*8+j*8+k] = 0;
  464. for(k=0;k<8;k++)
  465. img[(8*i+k)*stride+j*8] = 0;
  466. if (dec8[i][j]==0){
  467. img[(8*i+4)*stride+j*8+3] = 0;
  468. img[(8*i+4)*stride+j*8+4] = 0;
  469. img[(8*i+4)*stride+j*8+5] = 0;
  470. img[(8*i+3)*stride+j*8+4] = 0;
  471. img[(8*i+5)*stride+j*8+4] = 0;
  472. }
  473. }
  474. }
  475. }
  476. for (i=32;i<(w32-1)*32;i++)
  477. img[(h32-1)*32*stride+i]=0;
  478. for (i=32;i<(h32-1)*32;i++)
  479. img[i*stride+(w32-1)*32]=0;
  480. #endif
  481. #if 0 /* 32x32 decision data */
  482. for(i=2;i<h32-2;i++){
  483. for(j=2;j<w32-2;j++){
  484. int i8, j8;
  485. int k;
  486. i8 = 4*i-1;
  487. j8 = 4*j-1;
  488. for(k=0;k<5;k++)
  489. printf("%d ", dec8[i8+k][j8]);
  490. for(k=1;k<5;k++)
  491. printf("%d ", dec8[i8][j8+k]);
  492. printf("%d\n", dec8[i8+1][j8+1]);
  493. }
  494. }
  495. #endif
  496. #if 0 /* 16x16 decision data */
  497. for(i=4;i<h16-4;i++){
  498. for(j=4;j<w16-4;j++){
  499. int i8, j8;
  500. int k;
  501. i8 = 2*i-1;
  502. j8 = 2*j-1;
  503. if (dec8[i8+1][j8+1]==3)
  504. continue;
  505. if (1)
  506. {
  507. int sum=0;
  508. /*for(k=0;k<3;k++)
  509. printf("%d ", dec8[i8+k][j8]);
  510. for(k=1;k<3;k++)
  511. printf("%d ", dec8[i8][j8+k]);*/
  512. for(k=0;k<3;k++)
  513. sum += dec8[i8+k][j8];
  514. for(k=1;k<3;k++)
  515. sum += dec8[i8][j8+k];
  516. printf("%d ", sum);
  517. } else {
  518. int up, left;
  519. up = (dec8[i8][j8+1]>=2) ? 2+dec8[i8][j8+1] : dec8[i8][j8+1]*2+dec8[i8][j8+2];
  520. left = (dec8[i8+1][j8]>=2) ? 2+dec8[i8+1][j8] : dec8[i8+1][j8]*2+dec8[i8+2][j8];
  521. printf("%d ", dec8[i8][j8]*36+up*6+left);
  522. }
  523. if (dec8[i8+1][j8+1]==2)
  524. printf("16\n");
  525. else
  526. printf("%d\n", 8*dec8[i8+1][j8+1]+4*dec8[i8+1][j8+2]+2*dec8[i8+2][j8+1]+dec8[i8+2][j8+2]);
  527. }
  528. printf("\n");
  529. }
  530. #endif
  531. #if 0 /* 8x8 decision data */
  532. for(i=8;i<h8-8;i++){
  533. for(j=8;j<w8-8;j++){
  534. if (dec8[i][j]<=1)
  535. {
  536. printf("%d %d %d %d\n", dec8[i-1][j-1], dec8[i-1][j], dec8[i][j-1], dec8[i][j]);
  537. }
  538. }
  539. }
  540. #endif
  541. return 0;
  542. }
  543. /*Applies vert then horiz prefilters of size _n.*/
  544. void prefilter_image(od_coeff *_img, int _w, int _h, int _n){
  545. int x,y,j;
  546. /*Pre-filter*/
  547. switch(_n){
  548. case 4:
  549. for(y=0;y<_h;y++){
  550. for(x=2;x<_w-2;x+=4){
  551. od_pre_filter4(&_img[y*_w+x],&_img[y*_w+x]);
  552. }
  553. }
  554. for(y=2;y<_h-2;y+=4){
  555. for(x=0;x<_w;x++){
  556. od_coeff tmp[4];
  557. for(j=0;j<4;j++)tmp[j]=_img[(y+j)*_w+x];
  558. od_pre_filter4(tmp,tmp);
  559. for(j=0;j<4;j++)_img[(y+j)*_w+x]=tmp[j];
  560. }
  561. }
  562. break;
  563. case 8:
  564. for(y=0;y<_h;y++){
  565. for(x=4;x<_w-4;x+=8){
  566. od_pre_filter8(&_img[y*_w+x],&_img[y*_w+x]);
  567. }
  568. }
  569. for(y=4;y<_h-4;y+=8){
  570. for(x=0;x<_w;x++){
  571. od_coeff tmp[16];
  572. for(j=0;j<8;j++)tmp[j]=_img[(y+j)*_w+x];
  573. od_pre_filter8(tmp,tmp);
  574. for(j=0;j<8;j++)_img[(y+j)*_w+x]=tmp[j];
  575. }
  576. }
  577. break;
  578. case 16:
  579. for(y=0;y<_h;y++){
  580. for(x=8;x<_w-8;x+=16){
  581. od_pre_filter16(&_img[y*_w+x],&_img[y*_w+x]);
  582. }
  583. }
  584. for(y=8;y<_h-8;y+=16){
  585. for(x=0;x<_w;x++){
  586. od_coeff tmp[16];
  587. for(j=0;j<16;j++)tmp[j]=_img[(y+j)*_w+x];
  588. od_pre_filter16(tmp,tmp);
  589. for(j=0;j<16;j++)_img[(y+j)*_w+x]=tmp[j];
  590. }
  591. }
  592. break;
  593. default:
  594. break;
  595. }
  596. }
  597. /*Applies horiz then vert postfilters of size _n.*/
  598. void postfilter_image(od_coeff *_img, int _w, int _h, int _n){
  599. int x,y,j;
  600. /*Pre-filter*/
  601. switch(_n){
  602. case 4:
  603. for(y=2;y<_h-2;y+=4){
  604. for(x=0;x<_w;x++){
  605. od_coeff tmp[4];
  606. for(j=0;j<4;j++)tmp[j]=_img[(y+j)*_w+x];
  607. od_post_filter4(tmp,tmp);
  608. for(j=0;j<4;j++)_img[(y+j)*_w+x]=tmp[j];
  609. }
  610. }
  611. for(y=0;y<_h;y++){
  612. for(x=2;x<_w-2;x+=4){
  613. od_post_filter4(&_img[y*_w+x],&_img[y*_w+x]);
  614. }
  615. }
  616. break;
  617. case 8:
  618. for(y=4;y<_h-4;y+=8){
  619. for(x=0;x<_w;x++){
  620. od_coeff tmp[16];
  621. for(j=0;j<8;j++)tmp[j]=_img[(y+j)*_w+x];
  622. od_post_filter8(tmp,tmp);
  623. for(j=0;j<8;j++)_img[(y+j)*_w+x]=tmp[j];
  624. }
  625. }
  626. for(y=0;y<_h;y++){
  627. for(x=4;x<_w-4;x+=8){
  628. od_post_filter8(&_img[y*_w+x],&_img[y*_w+x]);
  629. }
  630. }
  631. break;
  632. case 16:
  633. for(y=8;y<_h-8;y+=16){
  634. for(x=0;x<_w;x++){
  635. od_coeff tmp[16];
  636. for(j=0;j<16;j++)tmp[j]=_img[(y+j)*_w+x];
  637. od_post_filter16(tmp,tmp);
  638. for(j=0;j<16;j++)_img[(y+j)*_w+x]=tmp[j];
  639. }
  640. }
  641. for(y=0;y<_h;y++){
  642. for(x=8;x<_w-8;x+=16){
  643. od_post_filter16(&_img[y*_w+x],&_img[y*_w+x]);
  644. }
  645. }
  646. break;
  647. default:
  648. break;
  649. }
  650. }
  651. /*static const int fzig16[256] = {0,16,1,2,17,32,48,33,18,3,4,19,34,49,64,80,65,50,35,20,5,6,21,36,51,66,81,96,112,97,82,67,52,37,22,7,8,23,38,53,68,83,98,113,128,144,129,114,99,84,69,54,39,24,9,10,25,40,55,70,85,100,115,130,145,160,176,161,146,131,116,101,86,71,56,41,26,11,12,27,42,57,72,87,102,117,132,147,162,177,192,208,193,178,163,148,133,118,103,88,73,58,43,28,13,14,29,44,59,74,89,104,119,134,149,164,179,194,209,224,240,225,210,195,180,165,150,135,120,105,90,75,60,45,30,15,31,46,61,76,91,106,121,136,151,166,181,196,211,226,241,242,227,212,197,182,167,152,137,122,107,92,77,62,47,63,78,93,108,123,138,153,168,183,198,213,228,243,244,229,214,199,184,169,154,139,124,109,94,79,95,110,125,140,155,170,185,200,215,230,245,246,231,216,201,186,171,156,141,126,111,127,142,157,172,187,202,217,232,247,248,233,218,203,188,173,158,143,159,174,189,204,219,234,249,250,235,220,205,190,175,191,206,221,236,251,252,237,222,207,223,238,253,254,239,255};
  652. static const int izig16[256] = {0,2,3,9,10,20,21,35,36,54,55,77,78,104,105,135,1,4,8,11,19,22,34,37,53,56,76,79,103,106,134,136,5,7,12,18,23,33,38,52,57,75,80,102,107,133,137,164,6,13,17,24,32,39,51,58,74,81,101,108,132,138,163,165,14,16,25,31,40,50,59,73,82,100,109,131,139,162,166,189,15,26,30,41,49,60,72,83,99,110,130,140,161,167,188,190,27,29,42,48,61,71,84,98,111,129,141,160,168,187,191,210,28,43,47,62,70,85,97,112,128,142,159,169,186,192,209,211,44,46,63,69,86,96,113,127,143,158,170,185,193,208,212,227,45,64,68,87,95,114,126,144,157,171,184,194,207,213,226,228,65,67,88,94,115,125,145,156,172,183,195,206,214,225,229,240,66,89,93,116,124,146,155,173,182,196,205,215,224,230,239,241,90,92,117,123,147,154,174,181,197,204,216,223,231,238,242,249,91,118,122,148,153,175,180,198,203,217,222,232,237,243,248,250,119,121,149,152,176,179,199,202,218,221,233,236,244,247,251,254,120,150,151,177,178,200,201,219,220,234,235,245,246,252,253,255};
  653. */
  654. #define ROUNDUP_32(x) (((x)+31)&~31)
  655. #define MAXB 16
  656. #define SQUARE(x) ((int)(x)*(int)(x))
  657. int oc_ilog32(unsigned _v){
  658. int ret;
  659. static const unsigned char OC_DEBRUIJN_IDX32[32]={
  660. 0, 1,28, 2,29,14,24, 3,30,22,20,15,25,17, 4, 8,
  661. 31,27,13,23,21,19,16, 7,26,12,18, 6,11, 5,10, 9};
  662. _v|=_v>>1;
  663. _v|=_v>>2;
  664. _v|=_v>>4;
  665. _v|=_v>>8;
  666. _v|=_v>>16;
  667. ret=_v&1;
  668. _v=(_v>>1)+1;
  669. ret+=OC_DEBRUIJN_IDX32[_v*0x77CB531U>>27&0x1F];
  670. return ret;
  671. }
  672. void quant_scalar_gain(ogg_int32_t *_x,ogg_int16_t *_scale,int *y,int N,int Q){
  673. float gain0, gain1;
  674. float Q_1;
  675. int i;
  676. (void)_scale;
  677. Q*=15;
  678. Q_1 = 1.f/Q;
  679. gain0=0;
  680. gain1=0;
  681. for (i=0;i<N;i++)
  682. {
  683. int qx;
  684. float s = _x[i]*Q_1;
  685. float bias = s>0?-.49:.49;
  686. gain0 += s*s;
  687. qx = (int)floor(.5+s+bias);
  688. y[i] = qx;
  689. gain1 += qx*qx;
  690. _x[i] = Q*qx;
  691. }
  692. gain0 = sqrt(gain0/(1e-15+gain1));
  693. for (i=0;i<N;i++)
  694. _x[i] *= gain0;
  695. }
  696. static void process_plane(od_coeff *_img, od_coeff *_refi, int _w, int _h, int _pli, int _pvq_k){
  697. int x;
  698. int y;
  699. int j;
  700. int i;
  701. int free_ref;
  702. static int count=0;
  703. (void)_pvq_k;
  704. _w = ROUNDUP_32(_w);
  705. _h = ROUNDUP_32(_h);
  706. if(!_refi){
  707. _refi = (od_coeff *)calloc(ROUNDUP_32(_w)*ROUNDUP_32(_h),sizeof(*_refi));
  708. free_ref=1;
  709. }else free_ref=0;
  710. prefilter_image(_img,_w,_h,16);
  711. /*for (i=0;i<1000000;i++){
  712. int tmp[16];
  713. for(j=0;j<16;j++)
  714. tmp[j] = rand()%255-127;
  715. od_bin_idct16(tmp, tmp);
  716. for(j=0;j<16;j++)printf("%d ", tmp[j]);
  717. printf("\n");
  718. }
  719. exit(0);*/
  720. /*Block processing.*/
  721. for(y=0;y<_h;y+=16){
  722. for(x=0;x<_w;x+=16){
  723. od_coeff coeffs[256];
  724. ogg_int32_t zi[256];
  725. /* int out[256];*/
  726. /* ogg_int16_t scale[256];*/
  727. /* for(j=0;j<256;j++)scale[j]=1;*/
  728. od_bin_fdct16x16(coeffs,16,&_img[(y)*_w+x],_w);
  729. for(i=0;i<16;i++){
  730. for(j=0;j<16;j++){
  731. zi[16*i+j]=floor(.5+coeffs[16*i+j]);
  732. }
  733. }
  734. if (_pli==-1){
  735. #if 0
  736. int foo[256];
  737. ogg_int32_t x[256];
  738. /*quant_scalar_gain(&zi[1],NULL,foo,255,200);*/
  739. extract(&zi[4], x, 2, 4, 16);
  740. quant_scalar_gain(x,NULL,foo,8,200);
  741. interleave(x, &zi[4], 2, 4, 16);
  742. extract(&zi[64], x, 4, 2, 16);
  743. quant_scalar_gain(x,NULL,foo,8,200);
  744. interleave(x, &zi[64], 4, 2, 16);
  745. extract(&zi[64+2], x, 4, 6, 16);
  746. extract(&zi[32+4], x+24, 2, 4, 16);
  747. quant_scalar_gain(x,NULL,foo,32,600);
  748. interleave(x, &zi[64+2], 4, 6, 16);
  749. interleave(x+24, &zi[32+4], 2, 4, 16);
  750. #endif
  751. #if 0
  752. extract(&zi[8], x, 4, 8, 16);
  753. /*quant_pvq(x, r, scale, out, 32, 1200./f, &qg);*/
  754. quant_scalar_gain(x,NULL,foo,32,600);
  755. interleave(x, &zi[8], 4, 8, 16);
  756. extract(&zi[128], x, 8, 4, 16);
  757. /*quant_pvq(x, r, scale, out, 32, 1200./f, &qg);*/
  758. quant_scalar_gain(x,NULL,foo,32,600);
  759. interleave(x, &zi[128], 8, 4, 16);
  760. extract(&zi[128+4], x, 8, 12, 16);
  761. extract(&zi[64+8], x+96, 4, 8, 16);
  762. /*quant_pvq(x, r, scale, out, 128, 1200./f, &qg);*/
  763. quant_scalar_gain(x,NULL,foo,128,1200);
  764. interleave(x, &zi[128+4], 8, 12, 16);
  765. interleave(x+96, &zi[64+8], 4, 8, 16);
  766. #endif
  767. }
  768. /*for(j=0;j<256;j++)coeffs[j]=zi[j];*/
  769. for(i=0;i<16;i++){
  770. for(j=0;j<16;j++){
  771. coeffs[16*i+j]=floor(.5+zi[16*i+j]);
  772. }
  773. }
  774. od_bin_idct16x16(&_img[(y)*_w+x],_w,coeffs,16);
  775. }
  776. /*printf("\n");*/
  777. }
  778. postfilter_image(_img,_w,_h,16);
  779. if(free_ref)free(_refi);
  780. count++;
  781. }
  782. int main(int _argc,char **_argv){
  783. const char *optstring = "hv?";
  784. const struct option long_options[]={
  785. {"ref",required_argument,NULL,0},
  786. {"limit",required_argument,NULL,0},
  787. {"fps",required_argument,NULL,0},
  788. {"ext",required_argument,NULL,0},
  789. {"pvqk",required_argument,NULL,0},
  790. {"intra",no_argument,NULL,0},
  791. {NULL,0,NULL,0}
  792. };
  793. FILE *fin;
  794. FILE *fout;
  795. video_input vid1;
  796. video_input_info info1;
  797. video_input vid2;
  798. video_input_info info2;
  799. int frameno;
  800. int pli;
  801. unsigned char *outline;
  802. od_coeff *refi[3];
  803. od_coeff *iimg[3];
  804. int xdec[3];
  805. int ydec[3];
  806. int w[3];
  807. int h[3];
  808. int pvq_k;
  809. int fps;
  810. int extend;
  811. int limit;
  812. int intra;
  813. char refname[1024];
  814. int ref_in;
  815. int long_option_index;
  816. int c;
  817. pvq_k=32;
  818. fps=-1;
  819. ref_in=0;
  820. limit=0;
  821. extend=0;
  822. intra=0;
  823. while((c=getopt_long(_argc,_argv,optstring,long_options,&long_option_index))!=EOF){
  824. switch(c){
  825. case 0:
  826. if(strcmp(long_options[long_option_index].name,"ref")==0){
  827. ref_in=1;
  828. strncpy(refname,optarg,1023);
  829. } else if (strcmp(long_options[long_option_index].name,"pvqk")==0){
  830. pvq_k=atoi(optarg);
  831. } else if (strcmp(long_options[long_option_index].name,"limit")==0){
  832. limit=atoi(optarg);
  833. } else if (strcmp(long_options[long_option_index].name,"ext")==0){
  834. extend=atoi(optarg);
  835. } else if (strcmp(long_options[long_option_index].name,"intra")==0){
  836. intra=1;
  837. } else if (strcmp(long_options[long_option_index].name,"fps")==0){
  838. fps=atoi(optarg);
  839. }
  840. break;
  841. case 'v':
  842. case '?':
  843. case 'h':
  844. default:{
  845. usage(_argv);
  846. exit(EXIT_FAILURE);
  847. }break;
  848. }
  849. }
  850. if(optind+2!=_argc){
  851. usage(_argv);
  852. exit(EXIT_FAILURE);
  853. }
  854. fin=strcmp(_argv[optind],"-")==0?stdin:fopen(_argv[optind],"rb");
  855. if(fin==NULL){
  856. fprintf(stderr,"Unable to open '%s' for extraction.\n",_argv[optind]);
  857. exit(EXIT_FAILURE);
  858. }
  859. fprintf(stderr,"Opening %s as input%s...\n",_argv[optind],ref_in?"":" and reference");
  860. if(video_input_open(&vid1,fin)<0)exit(EXIT_FAILURE);
  861. video_input_get_info(&vid1,&info1);
  862. if(ref_in){
  863. fin=fopen(refname,"rb");
  864. if(fin==NULL){
  865. fprintf(stderr,"Unable to open '%s' for extraction.\n",refname);
  866. exit(EXIT_FAILURE);
  867. }
  868. fprintf(stderr,"Opening %s as reference...\n",refname);
  869. if(video_input_open(&vid2,fin)<0)exit(EXIT_FAILURE);
  870. video_input_get_info(&vid2,&info2);
  871. /*Check to make sure these videos are compatible.*/
  872. if(info1.pic_w!=info2.pic_w||info1.pic_h!=info2.pic_h){
  873. fprintf(stderr,"Video resolution does not match.\n");
  874. exit(EXIT_FAILURE);
  875. }
  876. if(info1.pixel_fmt!=info2.pixel_fmt){
  877. fprintf(stderr,"Pixel formats do not match.\n");
  878. exit(EXIT_FAILURE);
  879. }
  880. if((info1.pic_x&!(info1.pixel_fmt&1))!=(info2.pic_x&!(info2.pixel_fmt&1))||
  881. (info1.pic_y&!(info1.pixel_fmt&2))!=(info2.pic_y&!(info2.pixel_fmt&2))){
  882. fprintf(stderr,"Chroma subsampling offsets do not match.\n");
  883. exit(EXIT_FAILURE);
  884. }
  885. if(info1.fps_n*(ogg_int64_t)info2.fps_d!=
  886. info2.fps_n*(ogg_int64_t)info1.fps_d){
  887. fprintf(stderr,"Warning: framerates do not match.\n");
  888. }
  889. if(info1.par_n*(ogg_int64_t)info2.par_d!=
  890. info2.par_n*(ogg_int64_t)info1.par_d){
  891. fprintf(stderr,"Warning: aspect ratios do not match.\n");
  892. }
  893. }
  894. for(pli=0;pli<3;pli++){
  895. /*Planes padded up to a multiple of 32px*/
  896. xdec[pli]=pli&&!(info1.pixel_fmt&1);
  897. ydec[pli]=pli&&!(info1.pixel_fmt&2);
  898. h[pli]=ROUNDUP_32(info1.pic_h>>ydec[pli]);
  899. w[pli]=ROUNDUP_32(info1.pic_w>>xdec[pli]);
  900. refi[pli] = (od_coeff *)malloc(w[pli]*h[pli]*sizeof(*refi[pli]));
  901. iimg[pli] = (od_coeff *)malloc(w[pli]*h[pli]*sizeof(*iimg[pli]));
  902. }
  903. outline = (unsigned char *)malloc(sizeof(*outline)*info1.pic_w);
  904. fout=strcmp(_argv[optind+1],"-")==0?stdout:fopen(_argv[optind+1],"wb");
  905. if(fout==NULL){
  906. fprintf(stderr,"Error opening output file \"%s\".\n",_argv[optind+1]);
  907. return 1;
  908. }
  909. fprintf(fout,"YUV4MPEG2 W%i H%i F%i:%i Ip A%i:%i%s\n",
  910. info1.pic_w,info1.pic_h, fps > 0 ? (unsigned) fps : (unsigned) info1.fps_n,
  911. fps > 0 ? 1U : (unsigned) info1.fps_d, info1.par_n, info1.par_d,
  912. CHROMA_TAGS[ydec[1] ? xdec[1] ? 0 : 2 : 3]);
  913. for(frameno=0;;frameno++){
  914. video_input_ycbcr in;
  915. video_input_ycbcr ref;
  916. int ret1=0;
  917. int ret2=0;
  918. char tag1[5];
  919. char tag2[5];
  920. if(!limit||frameno<limit){
  921. ret1=video_input_fetch_frame(&vid1,in,tag1);
  922. if(ref_in)ret2=video_input_fetch_frame(&vid2,ref,tag2);
  923. }
  924. if(ret1==0){
  925. if(extend<1)break;
  926. extend--;
  927. /*If we're extending, keep feeding back the output to the reference input.*/
  928. for(pli=0;pli<3;pli++){
  929. int x;
  930. int y;
  931. for(y=0;y<h[pli];y++){
  932. for(x=0;x<w[pli];x++){
  933. refi[pli][y*w[pli]+x]=iimg[pli][y*w[pli]+x];
  934. }
  935. }
  936. }
  937. }
  938. if(ref_in&&ret1!=0&&ret2==0){
  939. fprintf(stderr,"Warning: Reference ended before input!\n");
  940. break;
  941. }
  942. for(pli=0;pli<3;pli++){
  943. int x;
  944. int y;
  945. if (pli==0)
  946. switch_decision(in[pli].data, w[pli], h[pli], in[pli].stride, info1.pic_w, info1.pic_h);
  947. for(y=0;y<h[pli];y++){
  948. for(x=0;x<w[pli];x++){
  949. int cy=OD_MINI(y+(int)(info1.pic_y>>ydec[pli]),(int)info1.pic_h>>ydec[pli]);
  950. int cx=OD_MINI(x+(int)(info1.pic_x>>xdec[pli]),(int)info1.pic_w>>xdec[pli]);
  951. iimg[pli][y*w[pli]+x]=128*(in[pli].data[cy*in[pli].stride+cx]-128);
  952. }
  953. }
  954. if(ref_in&&ret2!=0){
  955. for(y=0;y<h[pli];y++){
  956. for(x=0;x<w[pli];x++){
  957. int cy=OD_MINI(y+(int)(info1.pic_y>>ydec[pli]),(int)info1.pic_h>>ydec[pli]);
  958. int cx=OD_MINI(x+(int)(info1.pic_x>>xdec[pli]),(int)info1.pic_w>>xdec[pli]);
  959. refi[pli][y*w[pli]+x]=128*(ref[pli].data[cy*in[pli].stride+cx]-128);
  960. }
  961. }
  962. }
  963. process_plane(iimg[pli],(ref_in||frameno>0)&&!intra?refi[pli]:NULL,info1.pic_w>>xdec[pli],info1.pic_h>>ydec[pli],pli,pvq_k);
  964. if(!ref_in){
  965. for(y=0;y<h[pli];y++){
  966. for(x=0;x<w[pli];x++){
  967. refi[pli][y*w[pli]+x]=iimg[pli][y*w[pli]+x];
  968. }
  969. }
  970. }
  971. }
  972. fprintf(fout,"FRAME\n");
  973. for(pli=0;pli<3;pli++){
  974. int x;
  975. int y;
  976. for(y=0;y<(int)info1.pic_h>>ydec[pli];y++){
  977. for(x=0;x<(int)info1.pic_w>>xdec[pli];x++)outline[x]=OD_CLAMP255((int)floor(.5+(1./128)*iimg[pli][y*w[pli]+x])+128);
  978. if(fwrite(outline,
  979. (info1.pic_w>>xdec[pli]),1,fout)<1){
  980. fprintf(stderr,"Error writing to output.\n");
  981. return EXIT_FAILURE;
  982. }
  983. }
  984. }
  985. fprintf(stderr, "Completed frame %d.\n",frameno);
  986. }
  987. video_input_close(&vid1);
  988. if(ref_in)video_input_close(&vid2);
  989. if(fout!=stdout)fclose(fout);
  990. free(outline);
  991. for(pli=0;pli<3;pli++)free(refi[pli]);
  992. for(pli=0;pli<3;pli++)free(iimg[pli]);
  993. return EXIT_SUCCESS;
  994. }