dump_psnr.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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 and contributors http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: example dumpvid application; dumps Theora streams
  13. last mod: $Id$
  14. ********************************************************************/
  15. #if !defined(_GNU_SOURCE)
  16. #define _GNU_SOURCE
  17. #endif
  18. #if !defined(_LARGEFILE_SOURCE)
  19. #define _LARGEFILE_SOURCE
  20. #endif
  21. #if !defined(_LARGEFILE64_SOURCE)
  22. #define _LARGEFILE64_SOURCE
  23. #endif
  24. #if !defined(_FILE_OFFSET_BITS)
  25. #define _FILE_OFFSET_BITS 64
  26. #endif
  27. #include <stdio.h>
  28. #if !defined(_WIN32)
  29. #include <getopt.h>
  30. #include <unistd.h>
  31. #else
  32. #include "getopt.h"
  33. #endif
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <sys/timeb.h>
  37. #include <sys/types.h>
  38. #include <sys/stat.h>
  39. /*Yes, yes, we're going to hell.*/
  40. #if defined(_WIN32)
  41. #include <io.h>
  42. #endif
  43. #include <fcntl.h>
  44. #include <math.h>
  45. #include <signal.h>
  46. #include "vidinput.h"
  47. #include <ogg/os_types.h>
  48. const char *optstring = "fsy";
  49. struct option options [] = {
  50. {"frame-type",no_argument,NULL,'f'},
  51. {"summary",no_argument,NULL,'s'},
  52. {"luma-only",no_argument,NULL,'y'},
  53. {NULL,0,NULL,0}
  54. };
  55. static int show_frame_type;
  56. static int summary_only;
  57. static int luma_only;
  58. static void usage(char *_argv[]){
  59. fprintf(stderr,"Usage: %s [options] <video1> <video2>\n"
  60. " <video1> and <video2> may be either YUV4MPEG or Ogg Theora files.\n\n"
  61. " Options:\n\n"
  62. " -f --frame-type Show frame type and QI value for each Theora frame.\n"
  63. " -s --summary Only output the summary line.\n"
  64. " -y --luma-only Only output values for the luma channel.\n",_argv[0]);
  65. }
  66. int main(int _argc,char *_argv[]){
  67. video_input vid1;
  68. video_input_info info1;
  69. video_input vid2;
  70. video_input_info info2;
  71. ogg_int64_t gsqerr;
  72. ogg_int64_t gnpixels;
  73. ogg_int64_t gplsqerr[3];
  74. ogg_int64_t gplnpixels[3];
  75. int frameno;
  76. FILE *fin;
  77. int long_option_index;
  78. int c;
  79. #ifdef _WIN32
  80. /*We need to set stdin/stdout to binary mode on windows.
  81. Beware the evil ifdef.
  82. We avoid these where we can, but this one we cannot.
  83. Don't add any more, you'll probably go to hell if you do.*/
  84. _setmode(_fileno(stdin),_O_BINARY);
  85. #endif
  86. /*Process option arguments.*/
  87. while((c=getopt_long(_argc,_argv,optstring,options,&long_option_index))!=EOF){
  88. switch(c){
  89. case 'f':show_frame_type=1;break;
  90. case 's':summary_only=1;break;
  91. case 'y':luma_only=1;break;
  92. default:usage(_argv);break;
  93. }
  94. }
  95. if(optind+2!=_argc){
  96. usage(_argv);
  97. exit(1);
  98. }
  99. fin=strcmp(_argv[optind],"-")==0?stdin:fopen(_argv[optind],"rb");
  100. if(fin==NULL){
  101. fprintf(stderr,"Unable to open '%s' for extraction.\n",_argv[optind]);
  102. exit(1);
  103. }
  104. fprintf(stderr,"Opening %s...\n",_argv[optind]);
  105. if(video_input_open(&vid1,fin)<0)exit(1);
  106. video_input_get_info(&vid1,&info1);
  107. fin=strcmp(_argv[optind+1],"-")==0?stdin:fopen(_argv[optind+1],"rb");
  108. if(fin==NULL){
  109. fprintf(stderr,"Unable to open '%s' for extraction.\n",_argv[optind+1]);
  110. exit(1);
  111. }
  112. fprintf(stderr,"Opening %s...\n",_argv[optind+1]);
  113. if(video_input_open(&vid2,fin)<0)exit(1);
  114. video_input_get_info(&vid2,&info2);
  115. /*Check to make sure these videos are compatible.*/
  116. if(info1.pic_w!=info2.pic_w||info1.pic_h!=info2.pic_h){
  117. fprintf(stderr,"Video resolution does not match.\n");
  118. exit(1);
  119. }
  120. if(info1.pixel_fmt!=info2.pixel_fmt){
  121. fprintf(stderr,"Pixel formats do not match.\n");
  122. exit(1);
  123. }
  124. if((info1.pic_x&!(info1.pixel_fmt&1))!=(info2.pic_x&!(info2.pixel_fmt&1))||
  125. (info1.pic_y&!(info1.pixel_fmt&2))!=(info2.pic_y&!(info2.pixel_fmt&2))){
  126. fprintf(stderr,"Chroma subsampling offsets do not match.\n");
  127. exit(1);
  128. }
  129. if(info1.fps_n*(ogg_int64_t)info2.fps_d!=
  130. info2.fps_n*(ogg_int64_t)info1.fps_d){
  131. fprintf(stderr,"Warning: framerates do not match.\n");
  132. }
  133. if(info1.par_n*(ogg_int64_t)info2.par_d!=
  134. info2.par_n*(ogg_int64_t)info1.par_d){
  135. fprintf(stderr,"Warning: aspect ratios do not match.\n");
  136. }
  137. gsqerr=gplsqerr[0]=gplsqerr[1]=gplsqerr[2]=0;
  138. gnpixels=gplnpixels[0]=gplnpixels[1]=gplnpixels[2]=0;
  139. for(frameno=0;;frameno++){
  140. video_input_ycbcr f1;
  141. video_input_ycbcr f2;
  142. ogg_int64_t plsqerr[3];
  143. long plnpixels[3];
  144. ogg_int64_t sqerr;
  145. long npixels;
  146. int ret1;
  147. int ret2;
  148. int pli;
  149. ret1=video_input_fetch_frame(&vid1,f1,NULL);
  150. ret2=video_input_fetch_frame(&vid2,f2,NULL);
  151. if(ret1==0&&ret2==0)break;
  152. else if(ret1<0||ret2<0)break;
  153. else if(ret1==0){
  154. fprintf(stderr,"%s ended before %s.\n",
  155. _argv[optind],_argv[optind+1]);
  156. break;
  157. }
  158. else if(ret2==0){
  159. fprintf(stderr,"%s ended before %s.\n",
  160. _argv[optind+1],_argv[optind]);
  161. break;
  162. }
  163. /*Okay, we got one frame from each.*/
  164. sqerr=0;
  165. npixels=0;
  166. for(pli=0;pli<3;pli++){
  167. int xdec;
  168. int ydec;
  169. int y1;
  170. int y2;
  171. xdec=pli&&!(info1.pixel_fmt&1);
  172. ydec=pli&&!(info1.pixel_fmt&2);
  173. plsqerr[pli]=0;
  174. plnpixels[pli]=0;
  175. for(y1=info1.pic_y>>ydec,y2=info2.pic_y>>ydec;
  176. y1<info1.pic_y+info1.pic_h+ydec>>ydec;y1++,y2++){
  177. int x1;
  178. int x2;
  179. for(x1=info1.pic_x>>xdec,x2=info2.pic_x>>xdec;
  180. x1<info1.pic_x+info1.pic_w+xdec>>xdec;x1++,x2++){
  181. int d;
  182. d=*(f1[pli].data+y1*f1[pli].stride+x1)-
  183. *(f2[pli].data+y2*f2[pli].stride+x2);
  184. plsqerr[pli]+=d*d;
  185. plnpixels[pli]++;
  186. }
  187. }
  188. sqerr+=plsqerr[pli];
  189. gplsqerr[pli]+=plsqerr[pli];
  190. npixels+=plnpixels[pli];
  191. gplnpixels[pli]+=plnpixels[pli];
  192. }
  193. if(!summary_only){
  194. if(!luma_only){
  195. printf("%08i: %-7G (Y': %-7G Cb: %-7G Cr: %-7G)\n",frameno,
  196. 10*(log10(255*255)+log10(npixels)-log10(sqerr)),
  197. 10*(log10(255*255)+log10(plnpixels[0])-log10(plsqerr[0])),
  198. 10*(log10(255*255)+log10(plnpixels[1])-log10(plsqerr[1])),
  199. 10*(log10(255*255)+log10(plnpixels[2])-log10(plsqerr[2])));
  200. }
  201. else{
  202. printf("%08i: %-7G\n",frameno,
  203. 10*(log10(255*255)+log10(plnpixels[0])-log10(plsqerr[0])));
  204. }
  205. }
  206. gsqerr+=sqerr;
  207. gnpixels+=npixels;
  208. }
  209. if(!luma_only){
  210. printf("Total: %-7G (Y': %-7G Cb: %-7G Cr: %-7G)\n",
  211. 10*(log10(255*255)+log10(gnpixels)-log10(gsqerr)),
  212. 10*(log10(255*255)+log10(gplnpixels[0])-log10(gplsqerr[0])),
  213. 10*(log10(255*255)+log10(gplnpixels[1])-log10(gplsqerr[1])),
  214. 10*(log10(255*255)+log10(gplnpixels[2])-log10(gplsqerr[2])));
  215. }
  216. else{
  217. printf("Total: %-7G\n",
  218. 10*(log10(255*255)+log10(gplnpixels[0])-log10(gplsqerr[0])));
  219. }
  220. video_input_close(&vid1);
  221. video_input_close(&vid2);
  222. return 0;
  223. }