⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 h26l.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose.  In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/

/*
 * Feb 28, 2002
 * dmackie@cisco.com
 * Restructured version of lencod.c that provides a library API to encoder
 */

/*!
 ***********************************************************************
 *  \mainpage
 *     This is the H.26L encoder reference software. For detailed documentation
 *     see the comments in each file.
 *
 *  \author
 *     The main contributors are listed in contributors.h
 *
 *  \version
 *     TML 9.4
 *
 *  \note
 *     tags are used for document system "doxygen"
 *     available at http://www.doxygen.org
 */
/*!
 *  \file
 *     lencod.c
 *  \brief
 *     TML encoder project main
 *  \author
 *   Main contributors (see contributors.h for copyright, address and affiliation details)
 *   - Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com>
 *   - Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
 *   - Stephan Wenger                  <stewe@cs.tu-berlin.de>
 *   - Jani Lainema                    <jani.lainema@nokia.com>
 *   - Byeong-Moon Jeon                <jeonbm@lge.com>
 *   - Yoon-Seong Soh                  <yunsung@lge.com>
 *   - Thomas Stockhammer              <stockhammer@ei.tum.de>
 *   - Detlev Marpe                    <marpe@hhi.de>
 *   - Guido Heising                   <heising@hhi.de>
 *
 ***********************************************************************
 */

#include "contributors.h"

#include <string.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdlib.h>
#if defined WIN32
  #include <conio.h>
#endif
#include "global.h"
#include "configfile.h"
#include "leaky_bucket.h"

#define TML     "9"
#define VERSION "9.40"

InputParameters inputs, *input = &inputs;
ImageParameters images, *img   = &images;
StatParameters  stats,  *stat  = &stats;
SNRParameters   snrs,   *snr   = &snrs;

#ifdef H26L_LIB
byte* memout;
int memoutlength;
#endif

#ifdef _ADAPT_LAST_GROUP_
int initial_Bframes = 0;
#endif

int H26L_InUse = 0;

/*!
 ***********************************************************************
 * \brief
 *    Main function for encoder.
 * \param argc
 *    number of command line arguments
 * \param argv
 *    command line arguments
 * \return
 *    exit code
 ***********************************************************************
 */
int H26L_Init(char *config)
{
  char* argv[1];

  /* dmackie@cisco.com
   * Since code uses globals everywhere
   * we need to ensure only 1 calling instance
   */
  if (H26L_InUse) {
    return -1;
  }
  H26L_InUse = 1;

  p_dec = p_dec_u = p_dec_v = p_stat = p_log = p_datpart = p_trace = NULL;

  argv[0] = config;
  Configure (1, argv);

  // Initialize Image Parameters
  init_img();

  // Allocate Slice data struct
  malloc_slice();

  // create and init structure for rd-opt. mode decision
  init_rdopt ();

#ifdef _FAST_FULL_ME_
  // create arrays for fast full motion estimation
  InitializeFastFullIntegerSearch (input->search_range);
#endif

  // Initialize Statistic Parameters
  init_stat();

  // allocate memory for frame buffers
  get_mem4global_buffers();

  // Just some information which goes to the standard output
  information_init();

  // Write sequence header; open bitstream files
  stat->bit_slice = start_sequence();
  // B pictures
  Bframe_ctr=0;
  img->refPicID=-1;  //WYK: Oct. 16, 2001
  tot_time=0;                 // time for total encoding session

#ifdef _ADAPT_LAST_GROUP_
  if (input->last_frame > 0)
    input->no_frames = 1 + (input->last_frame + input->jumpd) / (input->jumpd + 1);
  initial_Bframes = input->successive_Bframe;
#endif

  return 0;
}

int H26L_Encode(byte* pY, byte* pU, byte* pV, 
	byte* pEncoded, int* pEncodedLength)
{
	int image_type;

	if (H26L_InUse == 0) {
		return -1;
	}

	memout = pEncoded;
	memoutlength = 0;
  
    if (input->intra_period == 0)
    {
      if (img->number == 0)
      {
        img->type = INTRA_IMG;        // set image type for first image to I-frame
      }
      else
      {
        img->type = INTER_IMG;        // P-frame
        if (input->sp_periodicity)
        {
          if ((img->number % input->sp_periodicity) ==0)
          {
            img->types=SP_IMG;
          }
          else img->types=INTER_IMG;
        }
      }
    }
    else
    {
      if ((img->number%input->intra_period) == 0)
      {
        img->type = INTRA_IMG;
      }
      else
      {
        img->type = INTER_IMG;        // P-frame
        if (input->sp_periodicity)
        {
          if ((img->number % input->sp_periodicity) ==0)
              img->types=SP_IMG;
          else img->types=INTER_IMG;
        }
      }
    }

#ifdef _ADAPT_LAST_GROUP_
    if (input->successive_Bframe && input->last_frame && img->number+1 == input->no_frames)
      {
        int bi = (int)((float)(input->jumpd+1)/(input->successive_Bframe+1.0)+0.499999);
        input->successive_Bframe = (input->last_frame-(img->number-1)*(input->jumpd+1))/bi-1;
      }
#endif

    image_type = img->type;
    
	/* start of read_one_frame emulation */

	if(img->type == B_IMG)
		frame_no = (img->number-1)*(input->jumpd+1)+img->b_interval*img->b_frame_to_code;
	else {
		frame_no = img->number*(input->jumpd+1);
#ifdef _ADAPT_LAST_GROUP_
		if (input->last_frame && img->number+1 == input->no_frames)
			frame_no=input->last_frame;
#endif
	}

	memcpy(*imgY_org, pY, img->width * img->height);
	memcpy(*(imgUV_org[0]), pU, img->width_cr * img->height_cr);
	memcpy(*(imgUV_org[1]), pV, img->width_cr * img->height_cr);

	/* end of read_one_frame emulation */

    encode_one_frame(); // encode one I- or P-frame
    if ((input->successive_Bframe != 0) && (img->number > 0)) // B-frame(s) to encode
    {
      img->type = B_IMG;            // set image type to B-frame
      img->types= INTER_IMG;
      for(img->b_frame_to_code=1; img->b_frame_to_code<=input->successive_Bframe; img->b_frame_to_code++)
        encode_one_frame();  // encode one B-frame
    }
    
    if (image_type == INTRA_IMG || img->types==SP_IMG)
    {
        img->nb_references = 1;
    }
    else
    {
       img->nb_references += 1;
       img->nb_references = min(img->nb_references, img->buf_cycle);
    }

  *pEncodedLength = memoutlength;
  img->number++;
  return 0;
}

int H26L_GetReconstructed(byte* pY, byte* pU, byte* pV)
{
	memcpy(pY, *imgY, img->width * img->height);
	memcpy(pU, *(imgUV[0]), img->width_cr * img->height_cr);
	memcpy(pV, *(imgUV[1]), img->width_cr * img->height_cr);
	return 0;
}

int H26L_Close()
{
  if (H26L_InUse == 0) {
	return -1;
  }

  // terminate sequence
  terminate_sequence();

#ifdef _FAST_FULL_ME_
  // free arrays for fast full motion estimation
  ClearFastFullIntegerSearch ();
#endif

  // free structure for rd-opt. mode decision
  clear_rdopt ();

#ifdef _LEAKYBUCKET_
  calc_buffer();
#endif

#ifndef H26L_LIB
  // report everything
  report();
#endif

  free_slice();

  // free allocated memory for frame buffers
  free_mem4global_buffers();

  // free image mem
  free_img ();

  H26L_InUse = 0;

  return 0;
}

/*!
 ***********************************************************************
 * \brief
 *    Initializes the Image structure with appropriate parameters.
 * \par Input:
 *    Input Parameters struct inp_par *inp
 * \par  Output:
 *    Image Parameters struct img_par *img
 ***********************************************************************
 */
void init_img()
{
  int i,j;

  img->no_multpred=input->no_multpred;
#ifdef _ADDITIONAL_REFERENCE_FRAME_
  img->buf_cycle = max (input->no_multpred, input->add_ref_frame+1);
#else
  img->buf_cycle = input->no_multpred;
#endif
  img->framerate=INIT_FRAME_RATE;   // The basic frame rate (of the original sequence)

  get_mem_mv (&(img->mv));
  get_mem_mv (&(img->p_fwMV));
  get_mem_mv (&(img->p_bwMV));
  get_mem_mv (&(img->all_mv));
  get_mem_mv (&(img->all_bmv));

  img->width    = input->img_width;
  img->height   = input->img_height;
  img->width_cr = input->img_width/2;
  img->height_cr= input->img_height/2;

  if(((img->mb_data) = (Macroblock *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(Macroblock))) == NULL)
    no_mem_exit("init_img: img->mb_data");

  if(((img->slice_numbers) = (int *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL)
    no_mem_exit("init_img: img->slice_numbers");

  if(input->UseConstrainedIntraPred)
  {
    if(((img->intra_mb) = (int *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL)
      no_mem_exit("init_img: img->intra_mb");
  }

  init(img);

  // allocate memory for intra pred mode buffer for each block: img->ipredmode
  // int  img->ipredmode[90][74];
  get_mem2Dint(&(img->ipredmode), img->width/BLOCK_SIZE+2, img->height/BLOCK_SIZE+2);

  // Prediction mode is set to -1 outside the frame, indicating that no prediction can be made from this part
  for (i=0; i < img->width/BLOCK_SIZE+1; i++)
  {
    img->ipredmode[i+1][0]=-1;
  }
  for (j=0; j < img->height/BLOCK_SIZE+1; j++)
  {
    img->ipredmode[0][j+1]=-1;
  }

  img->mb_y_upd=0;

}

/*!
 ***********************************************************************
 * \brief
 *    Free the Image structures
 * \par Input:
 *    Image Parameters struct img_par *img
 ***********************************************************************
 */
void free_img ()
{
  free_mem_mv (img->mv);
  free_mem_mv (img->p_fwMV);
  free_mem_mv (img->p_bwMV);
  free_mem_mv (img->all_mv);
  free_mem_mv (img->all_bmv);
}


/*!
 ************************************************************************
 * \brief
 *    Allocates the slice structure along with its dependent
 *    data structures
 * \par Input:
 *    Input Parameters struct inp_par *inp,  struct img_par *img
 ************************************************************************
 */
void malloc_slice()
{
  int i;
  DataPartition *dataPart;
  Slice *currSlice;
  const int buffer_size = (img->width * img->height * 3)/2; // DM 070301: The only assumption here is that we
                                // do not consider the case of data expansion.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -