h26l.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:56k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*
  33.  * Feb 28, 2002
  34.  * dmackie@cisco.com
  35.  * Restructured version of lencod.c that provides a library API to encoder
  36.  */
  37. /*!
  38.  ***********************************************************************
  39.  *  mainpage
  40.  *     This is the H.26L encoder reference software. For detailed documentation
  41.  *     see the comments in each file.
  42.  *
  43.  *  author
  44.  *     The main contributors are listed in contributors.h
  45.  *
  46.  *  version
  47.  *     TML 9.4
  48.  *
  49.  *  note
  50.  *     tags are used for document system "doxygen"
  51.  *     available at http://www.doxygen.org
  52.  */
  53. /*!
  54.  *  file
  55.  *     lencod.c
  56.  *  brief
  57.  *     TML encoder project main
  58.  *  author
  59.  *   Main contributors (see contributors.h for copyright, address and affiliation details)
  60.  *   - Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com>
  61.  *   - Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
  62.  *   - Stephan Wenger                  <stewe@cs.tu-berlin.de>
  63.  *   - Jani Lainema                    <jani.lainema@nokia.com>
  64.  *   - Byeong-Moon Jeon                <jeonbm@lge.com>
  65.  *   - Yoon-Seong Soh                  <yunsung@lge.com>
  66.  *   - Thomas Stockhammer              <stockhammer@ei.tum.de>
  67.  *   - Detlev Marpe                    <marpe@hhi.de>
  68.  *   - Guido Heising                   <heising@hhi.de>
  69.  *
  70.  ***********************************************************************
  71.  */
  72. #include "contributors.h"
  73. #include <string.h>
  74. #include <math.h>
  75. #include <time.h>
  76. #include <sys/timeb.h>
  77. #include <stdlib.h>
  78. #if defined WIN32
  79.   #include <conio.h>
  80. #endif
  81. #include "global.h"
  82. #include "configfile.h"
  83. #include "leaky_bucket.h"
  84. #define TML     "9"
  85. #define VERSION "9.40"
  86. InputParameters inputs, *input = &inputs;
  87. ImageParameters images, *img   = &images;
  88. StatParameters  stats,  *stat  = &stats;
  89. SNRParameters   snrs,   *snr   = &snrs;
  90. #ifdef H26L_LIB
  91. byte* memout;
  92. int memoutlength;
  93. #endif
  94. #ifdef _ADAPT_LAST_GROUP_
  95. int initial_Bframes = 0;
  96. #endif
  97. int H26L_InUse = 0;
  98. /*!
  99.  ***********************************************************************
  100.  * brief
  101.  *    Main function for encoder.
  102.  * param argc
  103.  *    number of command line arguments
  104.  * param argv
  105.  *    command line arguments
  106.  * return
  107.  *    exit code
  108.  ***********************************************************************
  109.  */
  110. int H26L_Init(char *config)
  111. {
  112.   char* argv[1];
  113.   /* dmackie@cisco.com
  114.    * Since code uses globals everywhere
  115.    * we need to ensure only 1 calling instance
  116.    */
  117.   if (H26L_InUse) {
  118.     return -1;
  119.   }
  120.   H26L_InUse = 1;
  121.   p_dec = p_dec_u = p_dec_v = p_stat = p_log = p_datpart = p_trace = NULL;
  122.   argv[0] = config;
  123.   Configure (1, argv);
  124.   // Initialize Image Parameters
  125.   init_img();
  126.   // Allocate Slice data struct
  127.   malloc_slice();
  128.   // create and init structure for rd-opt. mode decision
  129.   init_rdopt ();
  130. #ifdef _FAST_FULL_ME_
  131.   // create arrays for fast full motion estimation
  132.   InitializeFastFullIntegerSearch (input->search_range);
  133. #endif
  134.   // Initialize Statistic Parameters
  135.   init_stat();
  136.   // allocate memory for frame buffers
  137.   get_mem4global_buffers();
  138.   // Just some information which goes to the standard output
  139.   information_init();
  140.   // Write sequence header; open bitstream files
  141.   stat->bit_slice = start_sequence();
  142.   // B pictures
  143.   Bframe_ctr=0;
  144.   img->refPicID=-1;  //WYK: Oct. 16, 2001
  145.   tot_time=0;                 // time for total encoding session
  146. #ifdef _ADAPT_LAST_GROUP_
  147.   if (input->last_frame > 0)
  148.     input->no_frames = 1 + (input->last_frame + input->jumpd) / (input->jumpd + 1);
  149.   initial_Bframes = input->successive_Bframe;
  150. #endif
  151.   return 0;
  152. }
  153. int H26L_Encode(byte* pY, byte* pU, byte* pV, 
  154. byte* pEncoded, int* pEncodedLength)
  155. {
  156. int image_type;
  157. if (H26L_InUse == 0) {
  158. return -1;
  159. }
  160. memout = pEncoded;
  161. memoutlength = 0;
  162.   
  163.     if (input->intra_period == 0)
  164.     {
  165.       if (img->number == 0)
  166.       {
  167.         img->type = INTRA_IMG;        // set image type for first image to I-frame
  168.       }
  169.       else
  170.       {
  171.         img->type = INTER_IMG;        // P-frame
  172.         if (input->sp_periodicity)
  173.         {
  174.           if ((img->number % input->sp_periodicity) ==0)
  175.           {
  176.             img->types=SP_IMG;
  177.           }
  178.           else img->types=INTER_IMG;
  179.         }
  180.       }
  181.     }
  182.     else
  183.     {
  184.       if ((img->number%input->intra_period) == 0)
  185.       {
  186.         img->type = INTRA_IMG;
  187.       }
  188.       else
  189.       {
  190.         img->type = INTER_IMG;        // P-frame
  191.         if (input->sp_periodicity)
  192.         {
  193.           if ((img->number % input->sp_periodicity) ==0)
  194.               img->types=SP_IMG;
  195.           else img->types=INTER_IMG;
  196.         }
  197.       }
  198.     }
  199. #ifdef _ADAPT_LAST_GROUP_
  200.     if (input->successive_Bframe && input->last_frame && img->number+1 == input->no_frames)
  201.       {
  202.         int bi = (int)((float)(input->jumpd+1)/(input->successive_Bframe+1.0)+0.499999);
  203.         input->successive_Bframe = (input->last_frame-(img->number-1)*(input->jumpd+1))/bi-1;
  204.       }
  205. #endif
  206.     image_type = img->type;
  207.     
  208. /* start of read_one_frame emulation */
  209. if(img->type == B_IMG)
  210. frame_no = (img->number-1)*(input->jumpd+1)+img->b_interval*img->b_frame_to_code;
  211. else {
  212. frame_no = img->number*(input->jumpd+1);
  213. #ifdef _ADAPT_LAST_GROUP_
  214. if (input->last_frame && img->number+1 == input->no_frames)
  215. frame_no=input->last_frame;
  216. #endif
  217. }
  218. memcpy(*imgY_org, pY, img->width * img->height);
  219. memcpy(*(imgUV_org[0]), pU, img->width_cr * img->height_cr);
  220. memcpy(*(imgUV_org[1]), pV, img->width_cr * img->height_cr);
  221. /* end of read_one_frame emulation */
  222.     encode_one_frame(); // encode one I- or P-frame
  223.     if ((input->successive_Bframe != 0) && (img->number > 0)) // B-frame(s) to encode
  224.     {
  225.       img->type = B_IMG;            // set image type to B-frame
  226.       img->types= INTER_IMG;
  227.       for(img->b_frame_to_code=1; img->b_frame_to_code<=input->successive_Bframe; img->b_frame_to_code++)
  228.         encode_one_frame();  // encode one B-frame
  229.     }
  230.     
  231.     if (image_type == INTRA_IMG || img->types==SP_IMG)
  232.     {
  233.         img->nb_references = 1;
  234.     }
  235.     else
  236.     {
  237.        img->nb_references += 1;
  238.        img->nb_references = min(img->nb_references, img->buf_cycle);
  239.     }
  240.   *pEncodedLength = memoutlength;
  241.   img->number++;
  242.   return 0;
  243. }
  244. int H26L_GetReconstructed(byte* pY, byte* pU, byte* pV)
  245. {
  246. memcpy(pY, *imgY, img->width * img->height);
  247. memcpy(pU, *(imgUV[0]), img->width_cr * img->height_cr);
  248. memcpy(pV, *(imgUV[1]), img->width_cr * img->height_cr);
  249. return 0;
  250. }
  251. int H26L_Close()
  252. {
  253.   if (H26L_InUse == 0) {
  254. return -1;
  255.   }
  256.   // terminate sequence
  257.   terminate_sequence();
  258. #ifdef _FAST_FULL_ME_
  259.   // free arrays for fast full motion estimation
  260.   ClearFastFullIntegerSearch ();
  261. #endif
  262.   // free structure for rd-opt. mode decision
  263.   clear_rdopt ();
  264. #ifdef _LEAKYBUCKET_
  265.   calc_buffer();
  266. #endif
  267. #ifndef H26L_LIB
  268.   // report everything
  269.   report();
  270. #endif
  271.   free_slice();
  272.   // free allocated memory for frame buffers
  273.   free_mem4global_buffers();
  274.   // free image mem
  275.   free_img ();
  276.   H26L_InUse = 0;
  277.   return 0;
  278. }
  279. /*!
  280.  ***********************************************************************
  281.  * brief
  282.  *    Initializes the Image structure with appropriate parameters.
  283.  * par Input:
  284.  *    Input Parameters struct inp_par *inp
  285.  * par  Output:
  286.  *    Image Parameters struct img_par *img
  287.  ***********************************************************************
  288.  */
  289. void init_img()
  290. {
  291.   int i,j;
  292.   img->no_multpred=input->no_multpred;
  293. #ifdef _ADDITIONAL_REFERENCE_FRAME_
  294.   img->buf_cycle = max (input->no_multpred, input->add_ref_frame+1);
  295. #else
  296.   img->buf_cycle = input->no_multpred;
  297. #endif
  298.   img->framerate=INIT_FRAME_RATE;   // The basic frame rate (of the original sequence)
  299.   get_mem_mv (&(img->mv));
  300.   get_mem_mv (&(img->p_fwMV));
  301.   get_mem_mv (&(img->p_bwMV));
  302.   get_mem_mv (&(img->all_mv));
  303.   get_mem_mv (&(img->all_bmv));
  304.   img->width    = input->img_width;
  305.   img->height   = input->img_height;
  306.   img->width_cr = input->img_width/2;
  307.   img->height_cr= input->img_height/2;
  308.   if(((img->mb_data) = (Macroblock *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(Macroblock))) == NULL)
  309.     no_mem_exit("init_img: img->mb_data");
  310.   if(((img->slice_numbers) = (int *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL)
  311.     no_mem_exit("init_img: img->slice_numbers");
  312.   if(input->UseConstrainedIntraPred)
  313.   {
  314.     if(((img->intra_mb) = (int *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL)
  315.       no_mem_exit("init_img: img->intra_mb");
  316.   }
  317.   init(img);
  318.   // allocate memory for intra pred mode buffer for each block: img->ipredmode
  319.   // int  img->ipredmode[90][74];
  320.   get_mem2Dint(&(img->ipredmode), img->width/BLOCK_SIZE+2, img->height/BLOCK_SIZE+2);
  321.   // Prediction mode is set to -1 outside the frame, indicating that no prediction can be made from this part
  322.   for (i=0; i < img->width/BLOCK_SIZE+1; i++)
  323.   {
  324.     img->ipredmode[i+1][0]=-1;
  325.   }
  326.   for (j=0; j < img->height/BLOCK_SIZE+1; j++)
  327.   {
  328.     img->ipredmode[0][j+1]=-1;
  329.   }
  330.   img->mb_y_upd=0;
  331. }
  332. /*!
  333.  ***********************************************************************
  334.  * brief
  335.  *    Free the Image structures
  336.  * par Input:
  337.  *    Image Parameters struct img_par *img
  338.  ***********************************************************************
  339.  */
  340. void free_img ()
  341. {
  342.   free_mem_mv (img->mv);
  343.   free_mem_mv (img->p_fwMV);
  344.   free_mem_mv (img->p_bwMV);
  345.   free_mem_mv (img->all_mv);
  346.   free_mem_mv (img->all_bmv);
  347. }
  348. /*!
  349.  ************************************************************************
  350.  * brief
  351.  *    Allocates the slice structure along with its dependent
  352.  *    data structures
  353.  * par Input:
  354.  *    Input Parameters struct inp_par *inp,  struct img_par *img
  355.  ************************************************************************
  356.  */
  357. void malloc_slice()
  358. {
  359.   int i;
  360.   DataPartition *dataPart;
  361.   Slice *currSlice;
  362.   const int buffer_size = (img->width * img->height * 3)/2; // DM 070301: The only assumption here is that we
  363.                                 // do not consider the case of data expansion.
  364.                                 // So this is a strictly conservative estimation
  365.                                 // of the size of the bitstream buffer for one frame */                                                       /* ~DM
  366.   switch(input->of_mode) // init depending on NAL mode
  367.   {
  368.     case PAR_OF_26L:
  369.       // Current File Format
  370.       img->currentSlice = (Slice *) calloc(1, sizeof(Slice));
  371.       if ( (currSlice = img->currentSlice) == NULL)
  372.       {
  373.         snprintf (errortext, ET_SIZE, "Memory allocation for Slice datastruct in NAL-mode %d failed", input->of_mode);
  374.         error(errortext, 600);
  375.       }
  376.       if (input->symbol_mode == CABAC)
  377.       {
  378.         // create all context models
  379.         currSlice->mot_ctx = create_contexts_MotionInfo();
  380.         currSlice->tex_ctx = create_contexts_TextureInfo();
  381.       }
  382.       switch(input->partition_mode)
  383.       {
  384.       case PAR_DP_1:
  385.         currSlice->max_part_nr = 1;
  386.         break;
  387.       case PAR_DP_3:
  388.         error("Data Partitioning not supported with bit stream file format",600);
  389.         break;
  390.       default:
  391.         error("Data Partitioning Mode not supported!",600);
  392.         break;
  393.       }
  394.       currSlice->partArr = (DataPartition *) calloc(currSlice->max_part_nr, sizeof(DataPartition));
  395.       if (currSlice->partArr == NULL)
  396.       {
  397.         snprintf(errortext, ET_SIZE, "Memory allocation for Data Partition datastruct in NAL-mode %d failed", input->of_mode);
  398.         error(errortext, 100);
  399.       }
  400.       for (i=0; i<currSlice->max_part_nr; i++) // loop over all data partitions
  401.       {
  402.         dataPart = &(currSlice->partArr[i]);
  403.         dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));
  404.         if (dataPart->bitstream == NULL)
  405.         {
  406.           snprintf(errortext, ET_SIZE, "Memory allocation for Bitstream datastruct in NAL-mode %d failed", input->of_mode);
  407.           error (errortext, 100);
  408.         }
  409.         dataPart->bitstream->streamBuffer = (byte *) calloc(buffer_size, sizeof(byte));
  410.         if (dataPart->bitstream->streamBuffer == NULL)
  411.         {
  412.           snprintf(errortext, ET_SIZE, "Memory allocation for bitstream buffer in NAL-mode %d failed", input->of_mode);
  413.           error (errortext, 100);
  414.         }
  415.         // Initialize storage of bitstream parameters
  416.         dataPart->bitstream->stored_bits_to_go = 8;
  417.         dataPart->bitstream->stored_byte_pos = 0;
  418.         dataPart->bitstream->stored_byte_buf = 0;
  419.       }
  420.       return;
  421.     case PAR_OF_RTP:
  422.       // RTP packet file format
  423.       img->currentSlice = (Slice *) calloc(1, sizeof(Slice));
  424.       if ( (currSlice = img->currentSlice) == NULL)
  425.       {
  426.         snprintf(errortext, ET_SIZE, "Memory allocation for Slice datastruct in NAL-mode %d failed", input->of_mode);
  427.         error(errortext, 100);
  428.       }
  429.       if (input->symbol_mode == CABAC)
  430.       {
  431.         // create all context models
  432.         currSlice->mot_ctx = create_contexts_MotionInfo();
  433.         currSlice->tex_ctx = create_contexts_TextureInfo();
  434.       }
  435.       switch(input->partition_mode)
  436.       {
  437.       case PAR_DP_1:
  438.         currSlice->max_part_nr = 1;
  439.         break;
  440.       case PAR_DP_3:
  441.         currSlice->max_part_nr = 3;
  442.         break;
  443.       default:
  444.         error("Data Partitioning Mode not supported!",600);
  445.         break;
  446.       }
  447.       currSlice->partArr = (DataPartition *) calloc(currSlice->max_part_nr, sizeof(DataPartition));
  448.       if (currSlice->partArr == NULL)
  449.       {
  450.         snprintf(errortext, ET_SIZE, "Memory allocation for Data Partition datastruct in NAL-mode %d failed", input->of_mode);
  451.         error(errortext, 100);
  452.       }
  453.       for (i=0; i<currSlice->max_part_nr; i++) // loop over all data partitions
  454.       {
  455.         dataPart = &(currSlice->partArr[i]);
  456.         dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));
  457.         if (dataPart->bitstream == NULL)
  458.         {
  459.           snprintf(errortext, ET_SIZE, "Memory allocation for Bitstream datastruct in NAL-mode %d failed", input->of_mode);
  460.           error(errortext, 100);
  461.         }
  462.         dataPart->bitstream->streamBuffer = (byte *) calloc(buffer_size, sizeof(byte));
  463.         if (dataPart->bitstream->streamBuffer == NULL)
  464.         {
  465.           snprintf(errortext, ET_SIZE, "Memory allocation for bitstream buffer in NAL-mode %d failed", input->of_mode);
  466.           error(errortext, 100);
  467.         }
  468.         // Initialize storage of bitstream parameters
  469.         dataPart->bitstream->stored_bits_to_go = 8;
  470.         dataPart->bitstream->stored_byte_pos = 0;
  471.         dataPart->bitstream->stored_byte_buf = 0;
  472.       }
  473.       return;
  474.     default:
  475.       snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
  476.       error(errortext, 600);
  477.   }
  478. }
  479. /*!
  480.  ************************************************************************
  481.  * brief
  482.  *    Memory frees of the Slice structure and of its dependent
  483.  *    data structures
  484.  * par Input:
  485.  *    Input Parameters struct inp_par *inp,  struct img_par *img
  486.  ************************************************************************
  487.  */
  488. void free_slice()
  489. {
  490.   int i;
  491.   DataPartition *dataPart;
  492.   Slice *currSlice = img->currentSlice;
  493.   for (i=0; i<currSlice->max_part_nr; i++) // loop over all data partitions
  494.   {
  495.     dataPart = &(currSlice->partArr[i]);
  496.     if (dataPart->bitstream->streamBuffer != NULL)
  497.       free(dataPart->bitstream->streamBuffer);
  498.     if (dataPart->bitstream != NULL)
  499.       free(dataPart->bitstream);
  500.   }
  501.   if (currSlice->partArr != NULL)
  502.     free(currSlice->partArr);
  503.   if (input->symbol_mode == CABAC)
  504.   {
  505.     // delete all context models
  506.     delete_contexts_MotionInfo(currSlice->mot_ctx);
  507.     delete_contexts_TextureInfo(currSlice->tex_ctx);
  508.   }
  509.   if (currSlice != NULL)
  510.     free(img->currentSlice);
  511. }
  512. /*!
  513.  ************************************************************************
  514.  * brief
  515.  *    Initializes the Statistics structure with appropriate parameters
  516.  * par Input:
  517.  *    Statistic Parameters struct stat_par *stat
  518.  * par Output:
  519.  *    Statistic Parameters struct stat_par *stat
  520.  ************************************************************************
  521.  */
  522. void init_stat()
  523. {
  524.   int i;
  525.   if ((stat->mode_use_Bframe = (int *)malloc(sizeof(int)*41))==NULL)
  526.     no_mem_exit("init_stat: stat->mode_use_Bframe");
  527.   if ((stat->bit_use_mode_Bframe =  (int *)malloc(sizeof(int)*41))==NULL)
  528.     no_mem_exit("init_stat: stat->bit_use_mode_Bframe");
  529.   for(i=0; i<41; i++)
  530.     stat->mode_use_Bframe[i]=stat->bit_use_mode_Bframe[i]=0;
  531. }
  532. /*!
  533.  ************************************************************************
  534.  * brief
  535.  *    Reports the gathered information to appropriate outputs
  536.  * par Input:
  537.  *    struct inp_par *inp,                                            n
  538.  *    struct img_par *img,                                            n
  539.  *    struct stat_par *stat,                                          n
  540.  *    struct stat_par *stat                                           n
  541.  *
  542.  * par Output:
  543.  *    None
  544.  ************************************************************************
  545.  */
  546. void report()
  547. {
  548.   int bit_use[2][2] ;
  549.   int i,j;
  550.   char name[20];
  551.   int bit_use_Bframe=0;
  552.   int total_bits;
  553.   float frame_rate;
  554. #ifndef WIN32
  555.   time_t now;
  556.   struct tm *l_time;
  557.   char string[1000];
  558. #else
  559.   char timebuf[128];
  560. #endif
  561.   bit_use[0][0]=1;
  562.   bit_use[1][0]=max(1,input->no_frames-1);
  563.   //  Accumulate bit usage for inter and intra frames
  564.   bit_use[0][1]=bit_use[1][1]=0;
  565.   for (i=0; i < 9; i++)
  566.     bit_use[1][1] += stat->bit_use_mode_inter[i];
  567.   for (j=0;j<2;j++)
  568.   {
  569.     bit_use[j][1]+=stat->bit_use_header[j];
  570.     bit_use[j][1]+=stat->bit_use_mb_type[j];
  571.     bit_use[j][1]+=stat->tmp_bit_use_cbp[j];
  572.     bit_use[j][1]+=stat->bit_use_coeffY[j];
  573.     bit_use[j][1]+=stat->bit_use_coeffC[j];
  574.     bit_use[j][1]+=stat->bit_use_delta_quant[j];
  575.   }
  576.   // B pictures
  577.   if(Bframe_ctr!=0)
  578.   {
  579.     bit_use_Bframe=0;
  580.     for(i=0; i<41; i++)
  581.       bit_use_Bframe += stat->bit_use_mode_Bframe[i]; // fw_predframe_no, blk_size
  582.     bit_use_Bframe += stat->bit_use_header[2];
  583.     bit_use_Bframe += stat->tmp_bit_use_cbp[2];
  584.     bit_use_Bframe += stat->bit_use_coeffY[2];
  585.     bit_use_Bframe += stat->bit_use_coeffC[2];
  586.     bit_use_Bframe += stat->bit_use_delta_quant[2];
  587.     stat->bitrate_P=(stat->bit_ctr_0+stat->bit_ctr_P)*(float)(img->framerate/(input->jumpd+1))/input->no_frames;
  588. #ifdef _ADAPT_LAST_GROUP_
  589.     stat->bitrate_B=(stat->bit_ctr_B)*(float)(img->framerate/(input->jumpd+1))*initial_Bframes/Bframe_ctr;
  590. #else
  591.     stat->bitrate_B=(stat->bit_ctr_B)*(float)(img->framerate/(input->jumpd+1))*input->successive_Bframe/Bframe_ctr;
  592. #endif
  593.   }
  594.   else
  595.   {
  596.     if (input->no_frames > 1)
  597.     {
  598.       stat->bitrate=(bit_use[0][1]+bit_use[1][1])*(float)img->framerate/(input->no_frames*(input->jumpd+1));
  599.     }
  600.   }
  601.   fprintf(stdout,"--------------------------------------------------------------------------n");
  602.   fprintf(stdout,   " Freq. for encoded bitstream       : %1.0fn",(float)img->framerate/(float)(input->jumpd+1));
  603.   if(input->hadamard)
  604.     fprintf(stdout," Hadamard transform                : Usedn");
  605.   else
  606.     fprintf(stdout," Hadamard transform                : Not usedn");
  607.   fprintf(stdout," Image format                      : %dx%dn",input->img_width,input->img_height);
  608.   if(input->intra_upd)
  609.     fprintf(stdout," Error robustness                  : Onn");
  610.   else
  611.     fprintf(stdout," Error robustness                  : Offn");
  612.   fprintf(stdout,    " Search range                      : %dn",input->search_range);
  613.   if(input->mv_res)
  614.     fprintf(stdout," MV resolution                     : 1/8-peln");
  615.   else
  616.     fprintf(stdout," MV resolution                     : 1/4-peln");
  617. #ifdef _ADDITIONAL_REFERENCE_FRAME_
  618.   if (input->add_ref_frame >= input->no_multpred)
  619.   {
  620.       fprintf(stdout,   " No of ref. frames used in P pred  : %d (+ no. %d)n",input->no_multpred,input->add_ref_frame);
  621.       if(input->successive_Bframe != 0)
  622.         fprintf(stdout,   " No of ref. frames used in B pred  : %d (+ no. %d)n",input->no_multpred,input->add_ref_frame);
  623.   }
  624.   else
  625. #endif
  626.   {
  627.     fprintf(stdout,   " No of ref. frames used in P pred  : %dn",input->no_multpred);
  628.     if(input->successive_Bframe != 0)
  629.       fprintf(stdout,   " No of ref. frames used in B pred  : %dn",input->no_multpred);
  630.   }
  631.   fprintf(stdout,   " Total encoding time for the seq.  : %.3f sec n",tot_time*0.001);
  632.   // B pictures
  633.   fprintf(stdout, " Sequence type                     :" );
  634.   if(input->successive_Bframe==1)   fprintf(stdout, " IBPBP (QP: I %d, P %d, B %d) n",
  635.     input->qp0, input->qpN, input->qpB);
  636.   else if(input->successive_Bframe==2) fprintf(stdout, " IBBPBBP (QP: I %d, P %d, B %d) n",
  637.     input->qp0, input->qpN, input->qpB);
  638.   else if(input->successive_Bframe==0 && input->sp_periodicity==0) fprintf(stdout, " IPPP (QP: I %d, P %d) n",   input->qp0, input->qpN);
  639.   else fprintf(stdout, " I-P-P-SP-P (QP: I %d, P %d, SP (%d, %d)) n",  input->qp0, input->qpN, input->qpsp, input->qpsp_pred);
  640.   // report on entropy coding  method
  641.   if (input->symbol_mode == UVLC)
  642.     fprintf(stdout," Entropy coding method             : UVLCn");
  643.   else
  644.     fprintf(stdout," Entropy coding method             : CABACn");
  645. #ifdef _FULL_SEARCH_RANGE_
  646.   if (input->full_search == 2)
  647.     fprintf(stdout," Search range restrictions         : nonen");
  648.   else if (input->full_search == 1)
  649.     fprintf(stdout," Search range restrictions         : older reference framesn");
  650.   else
  651.     fprintf(stdout," Search range restrictions         : smaller blocks and older reference framesn");
  652. #endif
  653.   if (input->rdopt)
  654.     fprintf(stdout," RD-optimized mode decision        : usedn");
  655.   else
  656.     fprintf(stdout," RD-optimized mode decision        : not usedn");
  657.   switch(input->partition_mode)
  658.     {
  659.     case PAR_DP_1:
  660.       fprintf(stdout," Data Partitioning Mode            : 1 partition n");
  661.       break;
  662.     case PAR_DP_3:
  663.       fprintf(stdout," Data Partitioning Mode            : 3 partitions n");
  664.       break;
  665.     default:
  666.       fprintf(stdout," Data Partitioning Mode            : not supportedn");
  667.       break;
  668.     }
  669.     switch(input->of_mode)
  670.     {
  671.     case PAR_OF_26L:
  672.       fprintf(stdout," Output File Format                : H.26L Bit Stream File Format n");
  673.       break;
  674.     case PAR_OF_RTP:
  675.       fprintf(stdout," Output File Format                : RTP Packet File Format n");
  676.       break;
  677.     default:
  678.       fprintf(stdout," Output File Format                : not supportedn");
  679.       break;
  680.     }
  681.   fprintf(stdout,"------------------ Average data all frames  ------------------------------n");
  682.   fprintf(stdout," SNR Y(dB)                         : %5.2fn",snr->snr_ya);
  683.   fprintf(stdout," SNR U(dB)                         : %5.2fn",snr->snr_ua);
  684.   fprintf(stdout," SNR V(dB)                         : %5.2fn",snr->snr_va);
  685.   if(Bframe_ctr!=0)
  686.   {
  687.     fprintf(stdout, " Total bits                        : %d (I %5d, P %5d, B %d) n",
  688.             total_bits=stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B);
  689.     frame_rate = (float)img->framerate / ( (float) (input->jumpd - input->successive_Bframe + 1) );
  690.     stat->bitrate= ((float) total_bits * frame_rate)/((float) (input->no_frames + Bframe_ctr));
  691.     fprintf(stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2fn", frame_rate, stat->bitrate/1000);
  692.   }
  693.   else if (input->sp_periodicity==0)
  694.   {
  695.     fprintf(stdout, " Total bits                        : %d (I %5d, P %5d) n",
  696.     total_bits=stat->bit_ctr_P + stat->bit_ctr_0 , stat->bit_ctr_0, stat->bit_ctr_P);
  697.     frame_rate = (float)img->framerate / ( (float) (input->jumpd + 1) );
  698.     stat->bitrate= ((float) total_bits * frame_rate)/((float) input->no_frames );
  699.     fprintf(stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2fn", frame_rate, stat->bitrate/1000);
  700.   }else
  701.   {
  702.     fprintf(stdout, " Total bits                        : %d (I %5d, P %5d) n",
  703.     total_bits=stat->bit_ctr_P + stat->bit_ctr_0 , stat->bit_ctr_0, stat->bit_ctr_P);
  704.     frame_rate = (float)img->framerate / ( (float) (input->jumpd + 1) );
  705.     stat->bitrate= ((float) total_bits * frame_rate)/((float) input->no_frames );
  706.     fprintf(stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2fn", frame_rate, stat->bitrate/1000);
  707.   }
  708.   fprintf(stdout,"--------------------------------------------------------------------------n");
  709.   fprintf(stdout,"Exit TML %s encoder ver %sn", TML, VERSION);
  710.   // status file
  711.   if ((p_stat=fopen("stat.dat","wb"))==0)
  712.   {
  713.     snprintf(errortext, ET_SIZE, "Error open file %s", "stat.dat");
  714.     error(errortext, 500);
  715.   }
  716.   fprintf(p_stat," -------------------------------------------------------------- n");
  717.   fprintf(p_stat,"  This file contains statistics for the last encoded sequence   n");
  718.   fprintf(p_stat," -------------------------------------------------------------- n");
  719.   fprintf(p_stat,   " Sequence                     : %sn",input->infile);
  720.   fprintf(p_stat,   " No.of coded pictures         : %dn",input->no_frames+Bframe_ctr);
  721.   fprintf(p_stat,   " Freq. for encoded bitstream  : %3.0fn",frame_rate);
  722.   // B pictures
  723.   if(input->successive_Bframe != 0)
  724.   {
  725.     fprintf(p_stat,   " BaseLayer Bitrate(kb/s)      : %6.2fn", stat->bitrate_P/1000);
  726.     fprintf(p_stat,   " EnhancedLyaer Bitrate(kb/s)  : %6.2fn", stat->bitrate_B/1000);
  727.   }
  728.   else
  729.     fprintf(p_stat,   " Bitrate(kb/s)                : %6.2fn", stat->bitrate/1000);
  730.   if(input->hadamard)
  731.     fprintf(p_stat," Hadamard transform           : Usedn");
  732.   else
  733.     fprintf(p_stat," Hadamard transform           : Not usedn");
  734.   fprintf(p_stat," Image format                 : %dx%dn",input->img_width,input->img_height);
  735.   if(input->intra_upd)
  736.     fprintf(p_stat," Error robustness             : Onn");
  737.   else
  738.     fprintf(p_stat," Error robustness             : Offn");
  739.   fprintf(p_stat,    " Search range                 : %dn",input->search_range);
  740.   if(input->mv_res)
  741.     fprintf(p_stat," MV resolution                : 1/8-peln");
  742.   else
  743.     fprintf(p_stat," MV resolution                : 1/4-peln");
  744. #ifdef _ADDITIONAL_REFERENCE_FRAME_
  745.   if (input->add_ref_frame >= input->no_multpred)
  746.     {
  747.       fprintf(p_stat,   " No of frame used in P pred   : %d (+ no. %d)n",input->no_multpred,input->add_ref_frame);
  748.       if(input->successive_Bframe != 0)
  749.         fprintf(p_stat,   " No of frame used in B pred   : %d (+ no. %d)n",input->no_multpred,input->add_ref_frame);
  750.     }
  751.   else
  752. #endif
  753.   {
  754.     fprintf(p_stat,   " No of frame used in P pred   : %dn",input->no_multpred);
  755.     if(input->successive_Bframe != 0)
  756.       fprintf(p_stat,   " No of frame used in B pred   : %dn",input->no_multpred);
  757.   }
  758.   if (input->symbol_mode == UVLC)
  759.     fprintf(p_stat,   " Entropy coding method        : UVLCn");
  760.   else
  761.     fprintf(p_stat,   " Entropy coding method        : CABACn");
  762. #ifdef _FULL_SEARCH_RANGE_
  763.   if (input->full_search == 2)
  764.     fprintf(p_stat," Search range restrictions    : nonen");
  765.   else if (input->full_search == 1)
  766.     fprintf(p_stat," Search range restrictions    : older reference framesn");
  767.   else
  768.     fprintf(p_stat," Search range restrictions    : smaller blocks and older reference framesn");
  769. #endif
  770.   if (input->rdopt)
  771.     fprintf(p_stat," RD-optimized mode decision   : usedn");
  772.   else
  773.     fprintf(p_stat," RD-optimized mode decision   : not usedn");
  774.   fprintf(p_stat," -------------------|---------------|---------------|n");
  775.   fprintf(p_stat,"     Item           |     Intra     |   All frames  |n");
  776.   fprintf(p_stat," -------------------|---------------|---------------|n");
  777.   fprintf(p_stat," SNR Y(dB)          |");
  778.   fprintf(p_stat," %5.2f         |",snr->snr_y1);
  779.   fprintf(p_stat," %5.2f         |n",snr->snr_ya);
  780.   fprintf(p_stat," SNR U/V (dB)       |");
  781.   fprintf(p_stat," %5.2f/%5.2f   |",snr->snr_u1,snr->snr_v1);
  782.   fprintf(p_stat," %5.2f/%5.2f   |n",snr->snr_ua,snr->snr_va);
  783.   // QUANT.
  784.   fprintf(p_stat," Average quant      |");
  785.   fprintf(p_stat," %5d         |",absm(input->qp0));
  786.   fprintf(p_stat," %5.2f         |n",(float)stat->quant1/max(1.0,(float)stat->quant0));
  787.   // MODE
  788.   fprintf(p_stat,"n -------------------|---------------|n");
  789.   fprintf(p_stat,"   Intra            |   Mode used   |n");
  790.   fprintf(p_stat," -------------------|---------------|n");
  791.   fprintf(p_stat," Mode 0  intra oldt| %5d         |n",stat->mode_use_intra[0]);
  792.   for (i=1;i<24;i++)
  793.     fprintf(p_stat," Mode %d intra newt| %5d         |n",i,stat->mode_use_intra[i]);
  794.   fprintf(p_stat,"n -------------------|---------------|---------------|n");
  795.   fprintf(p_stat,"   Inter            |   Mode used   | Vector bit use|n");
  796.   fprintf(p_stat," -------------------|---------------|---------------|");
  797.   fprintf(p_stat,"n Mode 0  (copy)  t| %5d         | %5.0f         |",stat->mode_use_inter[0],(float)stat->bit_use_mode_inter[0]/(float)bit_use[1][0]);
  798.   fprintf(p_stat,"n Mode 1  (16x16) t| %5d         | %5.0f         |",stat->mode_use_inter[1],(float)stat->bit_use_mode_inter[1]/(float)bit_use[1][0]);
  799.   fprintf(p_stat,"n Mode 2  (16x8)  t| %5d         | %5.0f         |",stat->mode_use_inter[2],(float)stat->bit_use_mode_inter[2]/(float)bit_use[1][0]);
  800.   fprintf(p_stat,"n Mode 3  (8x16)  t| %5d         | %5.0f         |",stat->mode_use_inter[3],(float)stat->bit_use_mode_inter[3]/(float)bit_use[1][0]);
  801.   fprintf(p_stat,"n Mode 4  (8x8)   t| %5d         | %5.0f         |",stat->mode_use_inter[4],(float)stat->bit_use_mode_inter[4]/(float)bit_use[1][0]);
  802.   fprintf(p_stat,"n Mode 5  (8x4)   t| %5d         | %5.0f         |",stat->mode_use_inter[5],(float)stat->bit_use_mode_inter[5]/(float)bit_use[1][0]);
  803.   fprintf(p_stat,"n Mode 6  (4x8)   t| %5d         | %5.0f         |",stat->mode_use_inter[6],(float)stat->bit_use_mode_inter[6]/(float)bit_use[1][0]);
  804.   fprintf(p_stat,"n Mode 7  (4x4)   t| %5d         | %5.0f         |",stat->mode_use_inter[7],(float)stat->bit_use_mode_inter[7]/(float)bit_use[1][0]);
  805.   fprintf(p_stat,"n Mode 8 intra oldt| %5d         | --------------|",stat->mode_use_inter[8]);
  806.   for (i=9;i<33;i++)
  807.     fprintf(p_stat,"n Mode %d intr.new t| %5d         |",i,stat->mode_use_inter[i]);
  808.   // B pictures
  809.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  810.   {
  811.     fprintf(p_stat,"nn -------------------|---------------|n");
  812.     fprintf(p_stat,"   B frame          |   Mode used   |n");
  813.     fprintf(p_stat," -------------------|---------------|");
  814.     for(i=0; i<16; i++)
  815.       fprintf(p_stat,"n Mode %d   t| %5d         |", i, stat->mode_use_Bframe[i]);
  816.     fprintf(p_stat,"n Mode %d intra oldt| %5d     |", 16, stat->mode_use_Bframe[16]);
  817.     for (i=17; i<41; i++)
  818.       fprintf(p_stat,"n Mode %d intr.new t| %5d     |",i, stat->mode_use_Bframe[i]);
  819.   }
  820.   fprintf(p_stat,"nn -------------------|---------------|---------------|---------------|n");
  821.   fprintf(p_stat,"  Bit usage:        |     Intra     |    Inter      |   B frame     |n");
  822.   fprintf(p_stat," -------------------|---------------|---------------|---------------|n");
  823.   fprintf(p_stat," Header+modeinfo    |");
  824.   fprintf(p_stat," %7d       |",stat->bit_use_header[0]);
  825.   fprintf(p_stat," %7d       |",stat->bit_use_header[1]/bit_use[1][0]);
  826.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  827.     fprintf(p_stat," %7d       |",stat->bit_use_header[2]/Bframe_ctr);
  828.   else fprintf(p_stat," %7d       |", 0);
  829.   fprintf(p_stat,"n");
  830.   fprintf(p_stat," CBP Y/C            |");
  831.   for (j=0; j < 2; j++)
  832.   {
  833.     fprintf(p_stat," %7.2f       |", (float)stat->tmp_bit_use_cbp[j]/bit_use[j][0]);
  834.   }
  835.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  836.     fprintf(p_stat," %7.2f       |", (float)stat->tmp_bit_use_cbp[2]/Bframe_ctr);
  837.   else fprintf(p_stat," %7.2f       |", 0.);
  838.   fprintf(p_stat,"n");
  839.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  840.     fprintf(p_stat," Coeffs. Y          | %7.2f      | %7.2f       | %7.2f       |n",
  841.       (float)stat->bit_use_coeffY[0]/bit_use[0][0], (float)stat->bit_use_coeffY[1]/bit_use[1][0], (float)stat->bit_use_coeffY[2]/Bframe_ctr);
  842.   else
  843.     fprintf(p_stat," Coeffs. Y          | %7.2f      | %7.2f       | %7.2f       |n",
  844.       (float)stat->bit_use_coeffY[0]/bit_use[0][0], (float)stat->bit_use_coeffY[1]/bit_use[1][0], 0.);
  845.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  846.     fprintf(p_stat," Coeffs. C          | %7.2f       | %7.2f       | %7.2f       |n",
  847.       (float)stat->bit_use_coeffC[0]/bit_use[0][0], (float)stat->bit_use_coeffC[1]/bit_use[1][0], (float)stat->bit_use_coeffC[2]/Bframe_ctr);
  848.   else
  849.     fprintf(p_stat," Coeffs. C          | %7.2f       | %7.2f       | %7.2f       |n",
  850.       (float)stat->bit_use_coeffC[0]/bit_use[0][0], (float)stat->bit_use_coeffC[1]/bit_use[1][0], 0.);
  851.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  852.     fprintf(p_stat," Delta quant        | %7.2f       | %7.2f       | %7.2f       |n",
  853.       (float)stat->bit_use_delta_quant[0]/bit_use[0][0], (float)stat->bit_use_delta_quant[1]/bit_use[1][0], (float)stat->bit_use_delta_quant[2]/Bframe_ctr);
  854.   else
  855.     fprintf(p_stat," Delta quant        | %7.2f       | %7.2f       | %7.2f       |n",
  856.       (float)stat->bit_use_delta_quant[0]/bit_use[0][0], (float)stat->bit_use_delta_quant[1]/bit_use[1][0], 0.);
  857.   fprintf(p_stat," -------------------|---------------|---------------|---------------|n");
  858.   fprintf(p_stat," average bits/frame |");
  859.   for (i=0; i < 2; i++)
  860.   {
  861.     fprintf(p_stat," %7d       |",bit_use[i][1]/bit_use[i][0]);
  862.   }
  863.   if(input->successive_Bframe!=0 && Bframe_ctr!=0)
  864.     fprintf(p_stat," %7d       |", bit_use_Bframe/Bframe_ctr);
  865.   else fprintf(p_stat," %7d       |", 0);
  866.   fprintf(p_stat,"n");
  867.   fprintf(p_stat," -------------------|---------------|---------------|---------------|n");
  868.   // write to log file
  869.   if (fopen("log.dat","r")==0)                      // check if file exist
  870.   {
  871.     if ((p_log=fopen("log.dat","a"))==NULL)            // append new statistic at the end
  872.     {
  873.       snprintf(errortext, ET_SIZE, "Error open file %s  n","log.dat");
  874.       error(errortext, 500);
  875.     }
  876.     else                                            // Create header for new log file
  877.     {
  878.       fprintf(p_log," ---------------------------------------------------------------------------------------------------------------------------------------------------------------- n");
  879.       fprintf(p_log,"|            Encoder statistics. This file is generated during first encoding session, new sessions will be appended                                               |n");
  880.       fprintf(p_log," ---------------------------------------------------------------------------------------------------------------------------------------------------------------- n");
  881.       fprintf(p_log,"| Date  | Time  |    Sequence        |#Img|Quant1|QuantN|Format|Hadamard|Search r|#Ref |Freq |Intra upd|SNRY 1|SNRU 1|SNRV 1|SNRY N|SNRU N|SNRV N|#Bitr P|#Bitr B|n");
  882.       fprintf(p_log," ---------------------------------------------------------------------------------------------------------------------------------------------------------------- n");
  883.     }
  884.   }
  885.   else
  886.     if ((p_log=fopen("log.dat","a"))==NULL)            // File exist,just open for appending
  887.     {
  888.       snprintf(errortext, ET_SIZE, "Error open file %s  n","log.dat");
  889.       error(errortext, 500);
  890.     }
  891. #ifdef WIN32
  892.   _strdate( timebuf );
  893.   fprintf(p_log,"| %1.5s |",timebuf );
  894.   _strtime( timebuf);
  895.   fprintf(p_log," % 1.5s |",timebuf);
  896. #else
  897.   now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time'
  898.   time (&now);
  899.   l_time = localtime (&now);
  900.   strftime (string, sizeof string, "%d-%b-%Y", l_time);
  901.   fprintf(p_log,"| %1.5s |",string );
  902.   strftime (string, sizeof string, "%H:%M:%S", l_time);
  903.   fprintf(p_log," %1.5s |",string );
  904. #endif
  905.   for (i=0;i<20;i++)
  906.     name[i]=input->infile[i+max(0,strlen(input->infile)-20)]; // write last part of path, max 20 chars
  907.   fprintf(p_log,"%20.20s|",name);
  908.   fprintf(p_log,"%3d |",input->no_frames);
  909.   fprintf(p_log,"  %2d  |",input->qp0);
  910.   fprintf(p_log,"  %2d  |",input->qpN);
  911.   fprintf(p_log,"%dx%d|",input->img_width,input->img_height);
  912.   if (input->hadamard==1)
  913.     fprintf(p_log,"   ON   |");
  914.   else
  915.     fprintf(p_log,"   OFF  |");
  916.   fprintf(p_log,"   %2d   |",input->search_range );
  917.   fprintf(p_log," %2d  |",input->no_multpred);
  918.   fprintf(p_log," %2d  |",img->framerate/(input->jumpd+1));
  919.   if (input->intra_upd==1)
  920.     fprintf(p_log,"   ON    |");
  921.   else
  922.     fprintf(p_log,"   OFF   |");
  923.   fprintf(p_log,"%5.3f|",snr->snr_y1);
  924.   fprintf(p_log,"%5.3f|",snr->snr_u1);
  925.   fprintf(p_log,"%5.3f|",snr->snr_v1);
  926.   fprintf(p_log,"%5.3f|",snr->snr_ya);
  927.   fprintf(p_log,"%5.3f|",snr->snr_ua);
  928.   fprintf(p_log,"%5.3f|",snr->snr_va);
  929.   if(input->successive_Bframe != 0)
  930.   {
  931.     fprintf(p_log,"%7.0f|",stat->bitrate_P);
  932.     fprintf(p_log,"%7.0f|n",stat->bitrate_B);
  933.   }
  934.   else
  935.   {
  936.     fprintf(p_log,"%7.0f|",stat->bitrate);
  937.     fprintf(p_log,"%7.0f|n",0.0);
  938.   }
  939.   fclose(p_log);
  940.   p_log=fopen("data.txt","a");
  941.   if(input->successive_Bframe != 0 && Bframe_ctr != 0) // B picture used
  942.   {
  943.     fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5d "
  944.           "%2.2f %2.2f %2.2f %5d "
  945.         "%2.2f %2.2f %2.2f %5d %5d %.3fn",
  946.         input->no_frames, input->qp0, input->qpN,
  947.         snr->snr_y1,
  948.         snr->snr_u1,
  949.         snr->snr_v1,
  950.         stat->bit_ctr_0,
  951.         0.0,
  952.         0.0,
  953.         0.0,
  954.         0,
  955.         snr->snr_ya,
  956.         snr->snr_ua,
  957.         snr->snr_va,
  958.         (stat->bit_ctr_0+stat->bit_ctr)/input->no_frames,
  959.         stat->bit_ctr_B/Bframe_ctr,
  960.         (double)0.001*tot_time/(input->no_frames+Bframe_ctr));
  961.   }
  962.   else
  963.   {
  964.     fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5d "
  965.           "%2.2f %2.2f %2.2f %5d "
  966.         "%2.2f %2.2f %2.2f %5d %5d %.3fn",
  967.         input->no_frames, input->qp0, input->qpN,
  968.         snr->snr_y1,
  969.         snr->snr_u1,
  970.         snr->snr_v1,
  971.         stat->bit_ctr_0,
  972.         0.0,
  973.         0.0,
  974.         0.0,
  975.         0,
  976.         snr->snr_ya,
  977.         snr->snr_ua,
  978.         snr->snr_va,
  979.         (stat->bit_ctr_0+stat->bit_ctr)/input->no_frames,
  980.         0,
  981.         (double)0.001*tot_time/input->no_frames);
  982.   }
  983.   fclose(p_log);
  984.   // B pictures
  985.   free(stat->mode_use_Bframe);
  986.   free(stat->bit_use_mode_Bframe);
  987. }
  988. /*!
  989.  ************************************************************************
  990.  * brief
  991.  *    Some matrices are initilized here.
  992.  * par Input:
  993.  *    none
  994.  * par Output:
  995.  *    none
  996.  ************************************************************************
  997.  */
  998. void init()
  999. {
  1000.   int i, ii, ind, j, i2;
  1001.   InitMotionVectorSearchModule();
  1002.   /*  img->mv_bituse[] is the number of bits used for motion vectors.
  1003.   It is used to add a portion to the SAD depending on bit usage in the motion search
  1004.   */
  1005.   img->mv_bituse[0]=1;
  1006.   ind=0;
  1007.   for (i=0; i < 9; i++)
  1008.   {
  1009.     ii= 2*i + 3;
  1010.     for (j=1; j <= (int)pow(2,i); j++)
  1011.     {
  1012.       ind++;
  1013.       img->mv_bituse[ind]=ii;
  1014.     }
  1015.   }
  1016.   // quad(0:255) SNR quad array
  1017.   for (i=0; i < 256; ++i) // fix from TML1 / TML2 sw, truncation removed
  1018.   {
  1019.     i2=i*i;
  1020.     img->quad[i]=i2;
  1021.   }
  1022.   // B pictures : img->blk_bitsue[] is used when getting bidirection SAD
  1023.   for (i=0; i < 7; i++)
  1024.   {
  1025.     if(i==0) img->blk_bituse[i]=1;
  1026.     else if(i==1 || i==2) img->blk_bituse[i]=3;
  1027.     else img->blk_bituse[i]=5;
  1028.   }
  1029. }
  1030. /*!
  1031.  ************************************************************************
  1032.  * brief
  1033.  *    Prints the header of the protocol.
  1034.  * par Input:
  1035.  *    struct inp_par *inp
  1036.  * par Output:
  1037.  *    none
  1038.  ************************************************************************
  1039.  */
  1040. void information_init()
  1041. {
  1042.   printf("--------------------------------------------------------------------------n");
  1043.   printf(" Input YUV file                    : %s n",input->infile);
  1044.   printf(" Output H.26L bitstream            : %s n",input->outfile);
  1045.   if (p_dec != NULL)
  1046.     printf(" Output YUV file(debug)            : %s n",input->ReconFile);
  1047.   printf(" Output log file                   : log.dat n");
  1048.   printf(" Output statistics file            : stat.dat n");
  1049.   printf("--------------------------------------------------------------------------n");
  1050.   printf(" Frame   Bit/pic   QP   SnrY    SnrU    SnrV    Time(ms) IntraMBsn");
  1051. }
  1052. /*!
  1053.  ************************************************************************
  1054.  * brief
  1055.  *    Dynamic memory allocation of frame size related global buffers
  1056.  *    buffers are defined in global.h, allocated memory must be freed in
  1057.  *    void free_mem4global_buffers()
  1058.  * par Input:
  1059.  *    Input Parameters struct inp_par *inp,                            n
  1060.  *    Image Parameters struct img_par *img
  1061.  * return Number of allocated bytes
  1062.  ************************************************************************
  1063.  */
  1064. int get_mem4global_buffers()
  1065. {
  1066.   int j,memory_size=0;
  1067. #ifdef _ADAPT_LAST_GROUP_
  1068.   extern int *last_P_no;
  1069.   if ((last_P_no = (int*)malloc(img->buf_cycle*sizeof(int))) == NULL)
  1070.     no_mem_exit("get_mem4global_buffers: last_P_no");
  1071. #endif
  1072.   // allocate memory for encoding frame buffers: imgY, imgUV
  1073.   // byte imgY[288][352];
  1074.   // byte imgUV[2][144][176];
  1075.   memory_size += get_mem2D(&imgY, img->height, img->width);
  1076.   memory_size += get_mem3D(&imgUV, 2, img->height_cr, img->width_cr);
  1077.   // allocate memory for reference frame buffers: imgY_org, imgUV_org
  1078.   // byte imgY_org[288][352];
  1079.   // byte imgUV_org[2][144][176];
  1080.   memory_size += get_mem2D(&imgY_org, img->height, img->width);
  1081.   memory_size += get_mem3D(&imgUV_org, 2, img->height_cr, img->width_cr);
  1082.   // allocate memory for post filter frame buffers: imgY_pf, imgUV_pf
  1083.   // byte imgY_pf[288][352];
  1084.   // byte imgUV_pf[2][144][176];
  1085.   memory_size += get_mem2D(&imgY_pf, img->height, img->width);
  1086.   memory_size += get_mem3D(&imgUV_pf, 2, img->height_cr, img->width_cr);
  1087.   // allocate memory for B frame coding: nextP_imgY, nextP_imgUV
  1088.   // byte nextP_imgY[288][352];
  1089.   // byte nextP_imgUV[2][144][176];
  1090.   memory_size += get_mem2D(&nextP_imgY, img->height, img->width);
  1091.   memory_size += get_mem3D(&nextP_imgUV, 2, img->height_cr, img->width_cr);
  1092.   // allocate memory for multiple ref. frame buffers: mref, mcref
  1093.   //byte mref[MAX_MULT_PRED][1152][1408];  */   /* 1/4 pix luma
  1094.   //byte mcef[MAX_MULT_PRED][2][352][288]; */   /* pix chroma
  1095.   // rows and cols for croma component mcef[ref][croma][4x][4y] are switched
  1096.   // compared to luma mref[ref][4y][4x] for whatever reason
  1097.   // number of reference frames increased by one for next P-frame
  1098.   memory_size += get_mem3D(&mref, img->buf_cycle+1, (img->height+2*IMG_PAD_SIZE)*4, (img->width+2*IMG_PAD_SIZE)*4);
  1099.   if((mcef = (byte****)calloc(img->buf_cycle+1,sizeof(byte***))) == NULL)
  1100.     no_mem_exit("get_mem4global_buffers: mcef");
  1101.   for(j=0;j<img->buf_cycle+1;j++)
  1102.   {
  1103.     memory_size += get_mem3D(&(mcef[j]), 2, img->height_cr, img->width_cr);
  1104.   }
  1105.   InitRefbuf (Refbuf11, Refbuf11_P);
  1106.   // allocate memory for B-frame coding (last upsampled P-frame): mref_P, mcref_P
  1107.   // is currently also used in oneforthpix_1() and _2() for coding without B-frames
  1108.   //byte mref[1152][1408];  */   /* 1/4 pix luma
  1109.   //byte mcef[2][352][288]; */   /* pix chroma
  1110.   memory_size += get_mem2D(&mref_P, (img->height+2*IMG_PAD_SIZE)*4, (img->width+2*IMG_PAD_SIZE)*4);
  1111.   memory_size += get_mem3D(&mcef_P, 2, img->height_cr, img->width_cr);
  1112.   if(input->successive_Bframe!=0)
  1113.   {
  1114.     // allocate memory for temp B-frame motion vector buffer: tmp_fwMV, tmp_bwMV, dfMV, dbMV
  1115.     // int ...MV[2][72][92];  ([2][72][88] should be enough)
  1116.     memory_size += get_mem3Dint(&tmp_fwMV, 2, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE+4);
  1117.     memory_size += get_mem3Dint(&tmp_bwMV, 2, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE+4);
  1118.     memory_size += get_mem3Dint(&dfMV,     2, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE+4);
  1119.     memory_size += get_mem3Dint(&dbMV,     2, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE+4);
  1120.     // allocate memory for temp B-frame motion vector buffer: fw_refFrArr, bw_refFrArr
  1121.     // int ...refFrArr[72][88];
  1122.     memory_size += get_mem2Dint(&fw_refFrArr, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
  1123.     memory_size += get_mem2Dint(&bw_refFrArr, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
  1124.   }
  1125.   // allocate memory for temp P and B-frame motion vector buffer: tmp_mv, temp_mv_block
  1126.   // int tmp_mv[2][72][92];  ([2][72][88] should be enough)
  1127.   memory_size += get_mem3Dint(&tmp_mv, 2, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE+4);
  1128.   // allocate memory for temp quarter pel luma frame buffer: img4Y_tmp
  1129.   // int img4Y_tmp[576][704];  (previously int imgY_tmp in global.h)
  1130.   memory_size += get_mem2Dint(&img4Y_tmp, img->height+2*IMG_PAD_SIZE, (img->width+2*IMG_PAD_SIZE)*4);
  1131.   // allocate memory for tmp loop filter frame buffers: imgY_tmp, imgUV_tmp
  1132.   // byte imgY_tmp[288][352];
  1133.   memory_size += get_mem2D(&imgY_tmp, img->height, img->width);
  1134.   memory_size += get_mem3D(&imgUV_tmp, 2, img->height_cr, img->width_cr);
  1135.   // allocate memory for reference frames of each block: refFrArr
  1136.   // int  refFrArr[72][88];
  1137.   memory_size += get_mem2Dint(&refFrArr, img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
  1138.   if (input->rdopt==2)
  1139.   {
  1140.     memory_size += get_mem2Dint(&resY, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  1141.     if ((decref = (byte****) calloc(input->NoOfDecoders,sizeof(byte***))) == NULL) 
  1142.       no_mem_exit("get_mem4global_buffers: decref");
  1143.     for (j=0 ; j<input->NoOfDecoders; j++)
  1144.     {
  1145.       memory_size += get_mem3D(&decref[j], img->buf_cycle+1, img->height, img->width);
  1146.     }
  1147.     memory_size += get_mem2D(&RefBlock, BLOCK_SIZE,BLOCK_SIZE);
  1148.     memory_size += get_mem3D(&decY, input->NoOfDecoders, img->height, img->width);
  1149.     memory_size += get_mem3D(&decY_best, input->NoOfDecoders, img->height, img->width);
  1150.     memory_size += get_mem2D(&status_map, img->height/MB_BLOCK_SIZE,img->width/MB_BLOCK_SIZE);
  1151.   }
  1152.   return (memory_size);
  1153. }
  1154. /*!
  1155.  ************************************************************************
  1156.  * brief
  1157.  *    Free allocated memory of frame size related global buffers
  1158.  *    buffers are defined in global.h, allocated memory is allocated in
  1159.  *    int get_mem4global_buffers()
  1160.  * par Input:
  1161.  *    Input Parameters struct inp_par *inp,                             n
  1162.  *    Image Parameters struct img_par *img
  1163.  * par Output:
  1164.  *    none
  1165.  ************************************************************************
  1166.  */
  1167. void free_mem4global_buffers()
  1168. {
  1169.   int  i,j;
  1170. #ifdef _ADAPT_LAST_GROUP_
  1171.   extern int *last_P_no;
  1172.   free (last_P_no);
  1173. #endif
  1174.   free(imgY[0]);
  1175.   free(imgY);
  1176.   free(imgUV[0][0]);
  1177.   free(imgUV[1][0]);
  1178.   free(imgUV[0]);
  1179.   free(imgUV[1]);
  1180.   free(imgUV);
  1181.   free(imgY_org[0]);    // free ref frame buffers
  1182.   free(imgY_org);
  1183.   free(imgUV_org[0][0]);
  1184.   free(imgUV_org[1][0]);
  1185.   free(imgUV_org[0]);
  1186.   free(imgUV_org[1]);
  1187.   free(imgUV_org);
  1188.   free(imgY_pf[0]);  // free post filtering frame buffers
  1189.   free(imgY_pf);
  1190.   free(imgUV_pf[0][0]);
  1191.   free(imgUV_pf[1][0]);
  1192.   free(imgUV_pf[0]);
  1193.   free(imgUV_pf[1]);
  1194.   free(imgUV_pf);
  1195.   free(nextP_imgY[0]);    // free next frame buffers (for B frames)
  1196.   free(nextP_imgY);
  1197.   free(nextP_imgUV[0][0]);
  1198.   free(nextP_imgUV[1][0]);
  1199.   free(nextP_imgUV[0]);
  1200.   free(nextP_imgUV[1]);
  1201.   free(nextP_imgUV);
  1202.   free (Refbuf11_P);
  1203.   for (j=0; j<img->buf_cycle; j++)
  1204.     free (Refbuf11[j]);
  1205.   free (Refbuf11);
  1206.   // free multiple ref frame buffers
  1207.   // number of reference frames increased by one for next P-frame
  1208.   for(j=0;j<=img->buf_cycle;j++)
  1209.   {
  1210.     free(mref[j][0]);
  1211.     free(mref[j]);
  1212.     free(mcef[j][0][0]);
  1213.     free(mcef[j][1][0]);
  1214.     free(mcef[j][0]);
  1215.     free(mcef[j][1]);
  1216.     free(mcef[j]);
  1217.   }
  1218.   free(mref);
  1219.   free(mcef);
  1220.   free(mref_P[0]);
  1221.   free(mref_P);
  1222.   free(mcef_P[0][0]);
  1223.   free(mcef_P[1][0]);
  1224.   free(mcef_P[0]);
  1225.   free(mcef_P[1]);
  1226.   free(mcef_P);
  1227.   if(input->successive_Bframe!=0)
  1228.   {
  1229.     // free last P-frame buffers for B-frame coding
  1230.     for(j=0;j<2;j++)
  1231.     {
  1232.       free(tmp_fwMV[j][0]);
  1233.       free(tmp_bwMV[j][0]);
  1234.       free(dfMV[j][0]);
  1235.       free(dbMV[j][0]);
  1236.       free(tmp_fwMV[j]);
  1237.       free(tmp_bwMV[j]);
  1238.       free(dfMV[j]);
  1239.       free(dbMV[j]);
  1240.     }
  1241.     free(tmp_fwMV);
  1242.     free(tmp_bwMV);
  1243.     free(dfMV);
  1244.     free(dbMV);
  1245.     free(fw_refFrArr[0]);
  1246.     free(bw_refFrArr[0]);
  1247.     free(fw_refFrArr);
  1248.     free(bw_refFrArr);
  1249.   } // end if B frame
  1250.   free(tmp_mv[0][0]);
  1251.   free(tmp_mv[0]);
  1252.   free(tmp_mv[1][0]);
  1253.   free(tmp_mv[1]);
  1254.   free(tmp_mv);
  1255.   free(img4Y_tmp[0]);    // free temp quarter pel frame buffer
  1256.   free(img4Y_tmp);
  1257.   free(imgY_tmp[0]);    // free temp loop filter frame buffer
  1258.   free(imgY_tmp);
  1259.   free(imgUV_tmp[0][0]);
  1260.   free(imgUV_tmp[1][0]);
  1261.   free(imgUV_tmp[0]);
  1262.   free(imgUV_tmp[1]);
  1263.   free(imgUV_tmp);
  1264.   free(refFrArr[0]);
  1265.   free(refFrArr);
  1266.   // free mem, allocated in init_img()
  1267.   // free intra pred mode buffer for blocks
  1268.   free(img->ipredmode[0]);
  1269.   free(img->ipredmode);
  1270.   free(img->mb_data);
  1271.   free(img->slice_numbers);
  1272.   if(input->UseConstrainedIntraPred)
  1273.   {
  1274.     free(img->intra_mb);
  1275.   }
  1276.   if (input->rdopt==2)
  1277.   {
  1278.     free(resY[0]);
  1279.     free(resY);
  1280.     free(RefBlock[0]);
  1281.     free(RefBlock);
  1282.     for (j=0; j<input->NoOfDecoders; j++)
  1283.     {
  1284.       free(decY[j][0]);
  1285.       free(decY[j]);
  1286.       free(decY_best[j][0]);
  1287.       free(decY_best[j]);
  1288.       for (i=0; i<img->buf_cycle+1; i++)
  1289.       {
  1290.         free(decref[j][i][0]);
  1291.         free(decref[j][i]);
  1292.       }
  1293.       free(decref[j]);
  1294.     }
  1295.     free(decY);
  1296.     free(decY_best);
  1297.     free(decref);
  1298.     free(status_map[0]);
  1299.     free(status_map);
  1300.   }
  1301. }
  1302. /*!
  1303.  ************************************************************************
  1304.  * brief
  1305.  *    Allocate 2D memory array -> unsigned char array2D[rows][columns]
  1306.  * par Input:
  1307.  *    none
  1308.  * return memory size in bytes
  1309.  ************************************************************************
  1310.  */
  1311. // Change 9-Aug-2001 P. List: dont allocate independant row arrays anymore
  1312. // but one complete array and move row-pointers to array. Now you can step
  1313. // to the next line with an offset of img->width
  1314. int get_mem2D(byte ***array2D, int rows, int columns)
  1315. {
  1316.   int i;
  1317.   if((*array2D      = (byte**)calloc(rows,        sizeof(byte*))) == NULL)
  1318.     no_mem_exit("get_mem2D: array2D");
  1319.   if(((*array2D)[0] = (byte* )calloc(columns*rows,sizeof(byte ))) == NULL)
  1320.     no_mem_exit("get_mem2D: array2D");
  1321.   for(i=1;i<rows;i++)
  1322.     (*array2D)[i] = (*array2D)[i-1] + columns ;
  1323.   return rows*columns;
  1324. }
  1325. /*!
  1326.  ************************************************************************
  1327.  * brief
  1328.  *    Allocate memory for mv
  1329.  * par Input:
  1330.  *    Image Parameters struct img_par *img                             n
  1331.  *    int****** mv
  1332.  * return memory size in bytes
  1333.  ************************************************************************
  1334.  */
  1335. int get_mem_mv (int****** mv)
  1336. {
  1337.   int i, j, k, l;
  1338.   if ((*mv = (int*****)calloc(4,sizeof(int****))) == NULL)
  1339.     no_mem_exit ("get_mem_mv: mv");
  1340.   for (i=0; i<4; i++)
  1341.   {
  1342.     if (((*mv)[i] = (int****)calloc(4,sizeof(int***))) == NULL)
  1343.       no_mem_exit ("get_mem_mv: mv");
  1344.     for (j=0; j<4; j++)
  1345.     {
  1346.       if (((*mv)[i][j] = (int***)calloc(img->buf_cycle,sizeof(int**))) == NULL)
  1347.         no_mem_exit ("get_mem_mv: mv");
  1348.       for (k=0; k<img->buf_cycle; k++)
  1349.       {
  1350.         if (((*mv)[i][j][k] = (int**)calloc(9,sizeof(int*))) == NULL)
  1351.           no_mem_exit ("get_mem_mv: mv");
  1352.         for (l=0; l<9; l++)
  1353.           if (((*mv)[i][j][k][l] = (int*)calloc(2,sizeof(int))) == NULL)
  1354.             no_mem_exit ("get_mem_mv: mv");
  1355.       }
  1356.     }
  1357.   }
  1358.   return 4*4*img->buf_cycle*9*2*sizeof(int);
  1359. }
  1360. /*!
  1361.  ************************************************************************
  1362.  * brief
  1363.  *    Free memory from mv
  1364.  * par Input:
  1365.  *    int****** mv
  1366.  ************************************************************************
  1367.  */
  1368. void free_mem_mv (int***** mv)
  1369. {
  1370.   int i, j, k, l;
  1371.   for (i=0; i<4; i++)
  1372.   {
  1373.     for (j=0; j<4; j++)
  1374.     {
  1375.       for (k=0; k<img->buf_cycle; k++)
  1376.       {
  1377.         for (l=0; l<9; l++)
  1378.           free (mv[i][j][k][l]);
  1379.         free (mv[i][j][k]);
  1380.       }
  1381.       free (mv[i][j]);
  1382.     }
  1383.     free (mv[i]);
  1384.   }
  1385.   free (mv);
  1386. }
  1387. /*!
  1388.  ************************************************************************
  1389.  * brief
  1390.  *    Allocate 2D memory array -> int array2D[rows][columns]
  1391.  * param rows
  1392.  *    number of rows
  1393.  * param columns
  1394.  *    number of columns
  1395.  * par Output:
  1396.  *    int ***array2D allocated memory
  1397.  * return memory size in bytes
  1398.  ************************************************************************
  1399.  */
  1400. // same change as in get_mem2Dint
  1401. int get_mem2Dint(int ***array2D, int rows, int columns)
  1402. {
  1403.   int i;
  1404.   if((*array2D      = (int**)calloc(rows,        sizeof(int*))) == NULL)
  1405.     no_mem_exit("get_mem2Dint:array2D");
  1406.   if(((*array2D)[0] = (int* )calloc(rows*columns,sizeof(int ))) == NULL)
  1407.     no_mem_exit("get_mem2Dint:array2D");
  1408.   for(i=1 ; i<rows ; i++)
  1409.     (*array2D)[i] =  (*array2D)[i-1] + columns  ;
  1410.   return rows*columns*sizeof(int);
  1411. }
  1412. /*!
  1413.  ************************************************************************
  1414.  * brief
  1415.  *   Allocate 3D memory array -> unsigned char array3D[frames][rows][columns]
  1416.  * param frames
  1417.  *    number of frames
  1418.  * param rows
  1419.  *    number of rows
  1420.  * param columns
  1421.  *    number of columns
  1422.  * par Output:
  1423.  *    byte ****array3D allocated memory
  1424.  * return memory size in bytes
  1425.  ************************************************************************
  1426.  */
  1427. // same change as in get_mem2Dint
  1428. int get_mem3D(byte ****array3D, int frames, int rows, int columns)
  1429. {
  1430.   int  j;
  1431.   if(((*array3D) = (byte***)calloc(frames,sizeof(byte**))) == NULL)
  1432.     no_mem_exit("get_mem3D: array3D");
  1433.   for(j=0;j<frames;j++)
  1434.     get_mem2D( (*array3D)+j, rows, columns ) ;
  1435.   return frames*rows*columns;
  1436. }
  1437. /*!
  1438.  ************************************************************************
  1439.  * brief
  1440.  *    Allocate 3D memory array -> int array3D[frames][rows][columns]
  1441.  * param frames
  1442.  *    number of frames
  1443.  * param rows
  1444.  *    number of rows
  1445.  * param columns
  1446.  *    number of columns
  1447.  * par Output:
  1448.  *    int ****array3D allocated memory
  1449.  * return memory size in bytes
  1450.  ************************************************************************
  1451.  */
  1452. // same change as in get_mem2Dint
  1453. int get_mem3Dint(int ****array3D, int frames, int rows, int columns)
  1454. {
  1455.   int  j;
  1456.   if(((*array3D) = (int***)calloc(frames,sizeof(int**))) == NULL)
  1457.     no_mem_exit("get_mem3Dint: array3D");
  1458.   for(j=0;j<frames;j++)
  1459.     get_mem2Dint( (*array3D)+j, rows, columns ) ;
  1460.   return frames*rows*columns*sizeof(int);
  1461. }
  1462. /*!
  1463.  ************************************************************************
  1464.  * brief
  1465.  *    Exit program if memory allocation failed (using error())
  1466.  * param where
  1467.  *    string indicating which memory allocation failed
  1468.  ************************************************************************
  1469.  */
  1470. void no_mem_exit(char *where)
  1471. {
  1472.    snprintf(errortext, ET_SIZE, "Could not allocate memory: %s",where);
  1473.    error (errortext, 100);
  1474. }