Main Page | Class List | File List | Class Members | File Members

vid_main.c

Go to the documentation of this file.
00001 /************************************************************************
00002  *
00003  *  vid_main.c, main module of tmn (TMN encoder).
00004  *  tmn is an H.263 encoder somewhat based on the Test Model Near-term
00005  *  (TMN5) in the ITU-T LBC Experts Group.
00006  *
00007  *  Copyright (C) 1995, 1996  Telenor R&D, Norway
00008  *        Karl Olav Lillevold <Karl.Lillevold@nta.no>
00009  *  
00010  *  Contacts: 
00011  *  Karl Olav Lillevold               <Karl.Lillevold@nta.no>, or
00012  *  Robert Danielsen                  <Robert.Danielsen@nta.no>
00013  *
00014  *  Telenor Research and Development  http://www.nta.no/brukere/DVC/
00015  *  P.O.Box 83                        tel.:   +47 63 84 84 00
00016  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
00017  *  
00018  ************************************************************************/
00019 
00020 /*
00021  * Disclaimer of Warranty
00022  *
00023  * These software programs are available to the user without any
00024  * license fee or royalty on an "as is" basis.  Telenor Research and
00025  * Development disclaims any and all warranties, whether express,
00026  * implied, or statuary, including any implied warranties or
00027  * merchantability or of fitness for a particular purpose.  In no
00028  * event shall the copyright-holder be liable for any incidental,
00029  * punitive, or consequential damages of any kind whatsoever arising
00030  * from the use of these programs.
00031  *
00032  * This disclaimer of warranty extends to the user of these programs
00033  * and user's customers, employees, agents, transferees, successors,
00034  * and assigns.
00035  *
00036  * Telenor Research and Development does not represent or warrant that
00037  * the programs furnished hereunder are free of infringement of any
00038  * third-party patents.
00039  *
00040  * Commercial implementations of H.263, including shareware, are
00041  * subject to royalty fees to patent holders.  Many of these patents
00042  * are general enough such that they are unavoidable regardless of
00043  * implementation design.
00044  * */
00045 
00046 
00047 #include "vid_sim.h"
00048 #include "video_codec.h"
00049 
00050 extern video_codec *VidSt;
00051 
00052 FILE *streamfile;
00053 
00054 /**********************************************************************
00055  *
00056  *      Name:        NextTwoPB
00057  *      Description:    Decides whether or not to code the next
00058  *                      two images as PB
00059  *      Speed:          This is not a very smart solution considering
00060  *                      the encoding speed, since motion vectors
00061  *                      have to be calculation several times. It 
00062  *                      can be done together with the normal
00063  *                      motion vector search, or a tree search 
00064  *                      instead of a full search can be used.
00065  *      
00066  *      Input:          pointers to previous image, potential B- 
00067  *                      and P-image, frame distances
00068  *      Returns:        1 for yes, 0 otherwise
00069  *      Side effects:
00070  *
00071  *      Date: 950824    Author: Karl.Lillevold@nta.no
00072  *
00073  ***********************************************************************/
00074 
00075 int NextTwoPB(PictImage *next2, PictImage *next1, PictImage *prev, 
00076               int bskip, int pskip, int seek_dist)
00077 {
00078   int adv_is_on = 0, mof_is_on = 0, lv_is_on = 0;
00079   int psad1, psad2, bsad, psad;
00080   MotionVector *MV[6][MBR+1][MBC+2];
00081   MotionVector *mvp, *mvbf, *mvbb;
00082   int x,y;
00083   int i,j,k,tmp;
00084 
00085   /* Temporarily disable some options to simplify motion estimation */
00086   if ((VidSt->advanced)) {
00087     (VidSt->advanced) = OFF;
00088     adv_is_on = ON;
00089   }
00090   if ((VidSt->mv_outside_frame)) {
00091     (VidSt->mv_outside_frame) = OFF;
00092     mof_is_on = ON;
00093   }
00094   if ((VidSt->long_vectors)) {
00095     (VidSt->long_vectors) = OFF;
00096     lv_is_on = ON;
00097   }
00098 
00099   for (j = 1; j <= ((VidSt->lines)>>4); j++) 
00100     for (i = 1; i <= ((VidSt->pels)>>4); i++) 
00101       for (k = 0; k < 3; k++) {
00102         MV[k][j][i] = (MotionVector *)calloc(1,sizeof(MotionVector));
00103         /* calloc to avoid Checker warnings about reading of
00104            unitizalized memory in the memcpy's below */
00105       }
00106 
00107   mvbf = (MotionVector *)malloc(sizeof(MotionVector));
00108   mvbb = (MotionVector *)malloc(sizeof(MotionVector));
00109 
00110   psad = 0;
00111   psad1 = 0;
00112   psad2 = 0;
00113   bsad = 0;
00114 
00115   /* Integer motion estimation */
00116   for ( j = 1; j < (VidSt->lines)/MB_SIZE - 1; j++) {
00117     for ( i = 1; i < (VidSt->pels)/MB_SIZE - 1 ; i++) {
00118       x = i*MB_SIZE;
00119       y = j*MB_SIZE;
00120 
00121       /* picture order: prev -> next1 -> next2 */
00122       /* next1 and next2 can be coded as PB or PP */
00123       /* prev is the previous encoded picture */
00124 
00125       /* computes vectors (prev <- next2) */
00126       MotionEstimation(next2->lum,prev->lum,x,y,0,0,seek_dist,MV,&tmp);
00127       if (MV[0][j+1][i+1]->x == 0 && MV[0][j+1][i+1]->y == 0)
00128         MV[0][j+1][i+1]->min_error += PREF_NULL_VEC;
00129       /* not necessary to prefer zero vector here */
00130       memcpy(MV[2][j+1][i+1],MV[0][j+1][i+1],sizeof(MotionVector));
00131 
00132       /* computes sad(prev <- next1) */
00133       MotionEstimation(next1->lum,prev->lum,x,y,0,0,seek_dist,MV,&tmp);
00134       if (MV[0][j+1][i+1]->x == 0 && MV[0][j+1][i+1]->y == 0)
00135         MV[0][j+1][i+1]->min_error += PREF_NULL_VEC;
00136       memcpy(MV[1][j+1][i+1],MV[0][j+1][i+1],sizeof(MotionVector));
00137 
00138       /* computes vectors for (next1 <- next2) */
00139       MotionEstimation(next2->lum,next1->lum,x,y,0,0,seek_dist,MV,&tmp);
00140       if (MV[0][j+1][i+1]->x == 0 && MV[0][j+1][i+1]->y == 0)
00141         MV[0][j+1][i+1]->min_error += PREF_NULL_VEC;
00142 
00143       /* scales vectors for (prev <- next2 ) */
00144       mvp = MV[2][j+1][i+1];
00145       mvbf->x =   bskip * mvp->x / (bskip + pskip);
00146       mvbb->x = - pskip * mvp->x / (bskip + pskip);
00147       mvbf->y =   bskip * mvp->y / (bskip + pskip);
00148       mvbb->y = - pskip * mvp->y / (bskip + pskip);
00149 
00150       psad1 += MV[0][j+1][i+1]->min_error;
00151       psad2 += MV[1][j+1][i+1]->min_error;
00152       psad +=  mvp->min_error;
00153 
00154       /* computes sad(prev <- next1 -> next2) */
00155       bsad += SAD_MB_Bidir(next1->lum + x + y*(VidSt->pels),
00156            next2->lum + x + mvbb->x + (y + mvbb->y)*(VidSt->pels),
00157            prev->lum + x + mvbf->x + (y + mvbf->y)*(VidSt->pels),
00158            (VidSt->pels), INT_MAX);
00159     }
00160   }
00161 
00162   for (j = 1; j <= ((VidSt->lines)>>4); j++) 
00163     for (i = 1; i <= ((VidSt->pels)>>4); i++) 
00164       for (k = 0; k < 3; k++) 
00165         free(MV[k][j][i]);
00166   free(mvbf);
00167   free(mvbb);
00168 
00169   /* restore advanced parameters */
00170   (VidSt->advanced) = adv_is_on;
00171   (VidSt->mv_outside_frame) = mof_is_on;
00172   (VidSt->long_vectors) = lv_is_on;
00173 
00174   /* do the decision */
00175   if (bsad < (psad1+psad2)/2)
00176     fprintf(stdout,"Chose PB - bsad %d, psad %d\n", 
00177             bsad, (psad1+psad2)/2);
00178   else
00179     fprintf(stdout,"Chose PP  - bsad %d, psad %d\n", 
00180             bsad, (psad1+psad2)/2);
00181 
00182   if (bsad < (psad1 + psad2)/2)
00183     return 1;
00184   else 
00185     return 0;
00186 }
00187 
00188 
00189 /**********************************************************************
00190  *
00191  *      Name:        PrintResult
00192  *      Description:    add bits and prints results
00193  *      
00194  *      Input:        Bits struct
00195  *        
00196  *      Returns:        
00197  *      Side effects:   
00198  *
00199  *      Date: 940116    Author: Karl.Lillevold@nta.no
00200  *
00201  ***********************************************************************/
00202 
00203 
00204 void PrintResult(Bits *bits,int num_units, int num)
00205 {
00206   fprintf(stdout,"# intra   : %d\n", bits->no_intra/num_units);
00207   fprintf(stdout,"# inter   : %d\n", bits->no_inter/num_units);
00208   fprintf(stdout,"# inter4v : %d\n", bits->no_inter4v/num_units);
00209   fprintf(stdout,"--------------\n");
00210   fprintf(stdout,"Coeff_Y: %d\n", bits->Y/num);
00211   fprintf(stdout,"Coeff_C: %d\n", bits->C/num);
00212   fprintf(stdout,"Vectors: %d\n", bits->vec/num);
00213   fprintf(stdout,"CBPY   : %d\n", bits->CBPY/num);
00214   fprintf(stdout,"MCBPC  : %d\n", bits->CBPCM/num);
00215   fprintf(stdout,"MODB   : %d\n", bits->MODB/num);
00216   fprintf(stdout,"CBPB   : %d\n", bits->CBPB/num);
00217   fprintf(stdout,"COD    : %d\n", bits->COD/num);
00218   fprintf(stdout,"DQUANT : %d\n", bits->DQUANT/num);
00219   fprintf(stdout,"header : %d\n", bits->header/num);
00220   fprintf(stdout,"==============\n");
00221   fprintf(stdout,"Total  : %d\n", bits->total/num);
00222   fprintf(stdout,"\n");
00223   return;
00224 }
00225 
00226 void PrintSNR(Results *res, int num)
00227 {
00228   FILE *fp = fopen("snr.dat","a");
00229   assert(fp!=NULL);
00230   fprintf(fp,"%.2f %.2f %.2f\n",res->SNR_l/num,res->SNR_Cb/num,res->SNR_Cr/num);
00231   fclose(fp);
00232   fprintf(stdout,"SNR_Y  : %.2f\n", res->SNR_l/num);
00233   fprintf(stdout,"SNR_Cb : %.2f\n", res->SNR_Cb/num);
00234   fprintf(stdout,"SNR_Cr : %.2f\n", res->SNR_Cr/num);
00235   fprintf(stdout,"--------------\n");
00236 
00237   return;
00238 }
00239 

Generated on Sun Jul 16 16:27:45 2006 by  doxygen 1.3.9.1