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

📄 image.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
***********************************************************************
* 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.
************************************************************************
*/

/*!
 *************************************************************************************
 * \file image.c
 *
 * \brief
 *    Code one image/slice
 *
 * \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>
 *     - Jani Lainema                    <jani.lainema@nokia.com>
 *     - Sebastian Purreiter             <sebastian.purreiter@mch.siemens.de>
 *     - 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>
 *     - Thomas Wedi                     <wedi@tnt.uni-hannover.de>
 *     - Ragip Kurceren                  <ragip.kurceren@nokia.com>
 *     - Antti Hallapuro                 <antti.hallapuro@nokia.com>
 *************************************************************************************
 */
#include "contributors.h"

#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <memory.h>
#include <assert.h>

#include "global.h"
#include "image.h"
#include "refbuf.h"

#ifdef _ADAPT_LAST_GROUP_
int *last_P_no;
#endif

//! The followibng two variables are used for debug purposes.  They store
//! the status of the currStream data structure elements after the header
//! writing, and are used whether any MB bits were written during the
//! macroblock coding stage.  We need to worry about empty slices!
static int Byte_Pos_After_Header;
static int Bits_To_Go_After_Header;

static void UnifiedOneForthPix (pel_t **imgY, pel_t** imgU, pel_t **imgV,
        pel_t **out4Y, pel_t **outU, pel_t **outV, pel_t *ref11);

/*!
 ************************************************************************
 * \brief
 *    Encodes one frame
 ************************************************************************
 */
int encode_one_frame()
{
#ifdef _LEAKYBUCKET_
  extern long Bit_Buffer[10000];
  extern unsigned long total_frame_buffer;
#endif
  Boolean end_of_frame = FALSE;
  SyntaxElement sym;

  time_t ltime1;   // for time measurement
  time_t ltime2;

#ifdef WIN32
  struct _timeb tstruct1;
  struct _timeb tstruct2;
#else
  struct timeval tstruct1;
  struct timeval tstruct2;
#endif

  int tmp_time;

#ifdef WIN32
  _ftime( &tstruct1 );    // start time ms
#else
  gettimeofday(&tstruct1, NULL);
#endif
  time( &ltime1 );        // start time s


  // Initialize frame with all stat and img variables
  img->total_number_mb = (img->width * img->height)/(MB_BLOCK_SIZE*MB_BLOCK_SIZE);
  init_frame();

  // Read one new frame
#ifndef H26L_LIB
  read_one_new_frame();
#endif

  if (img->type == B_IMG)
    Bframe_ctr++;

  while (end_of_frame == FALSE) // loop over slices
  {
    // Encode the current slice
    encode_one_slice(&sym);

    // Proceed to next slice
    img->current_slice_nr++;
    stat->bit_slice = 0;
    if (img->current_mb_nr == img->total_number_mb) // end of frame reached?
      end_of_frame = TRUE;
  }

  // in future only one call of oneforthpix() for all frame tyoes will be necessary, because
  // mref buffer will be increased by one frame to store also the next P-frame. Then mref_P
  // will not be used any more
  if (img->type != B_IMG) //all I- and P-frames
  {
    if (input->successive_Bframe == 0 || img->number == 0)
      interpolate_frame(); // I- and P-frames:loop-filtered imgY, imgUV -> mref[][][], mcef[][][][]
    else
      interpolate_frame_2();    // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
                                 // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
  }
  else
    if (img->b_frame_to_code == input->successive_Bframe)
      copy2mref(img);          // last successive B-frame: mref_P[][][], mcef_P[][][][] (loop-filtered imgY, imgUV)-> mref[][][], mcef[][][][]

  if (input->rdopt==2)
    UpdateDecoders(); // simulate packet losses and move decoded image to reference buffers

  find_snr(snr,img);

  time(&ltime2);       // end time sec
#ifdef WIN32
  _ftime(&tstruct2);   // end time ms
  tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);
#else
  gettimeofday(&tstruct2, NULL);    // end time ms
  tmp_time=(ltime2*1000+tstruct2.tv_usec/1000) - (ltime1*1000+(tstruct1.tv_usec / 1000));
#endif
  tot_time=tot_time + tmp_time;

#ifndef H26L_LIB
  // Write reconstructed images
  write_reconstructed_image();
#endif

#ifdef _LEAKYBUCKET_
  // Store bits used for this frame and increment counter of no. of coded frames
  Bit_Buffer[total_frame_buffer] = stat->bit_ctr - stat->bit_ctr_n;
  total_frame_buffer++;
#endif
  if(img->number == 0)
  {
    printf("%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d \n",
        frame_no, stat->bit_ctr-stat->bit_ctr_n,
        img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
    stat->bitr0=stat->bitr;
    stat->bit_ctr_0=stat->bit_ctr;
    stat->bit_ctr=0;
  }
  else
  {
    if (img->type == INTRA_IMG)
    {
      stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;
      printf("%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d \n",
        frame_no, stat->bit_ctr-stat->bit_ctr_n,
        img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
    }
    else if (img->type != B_IMG)
    {
      stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;
      if(img->types == SP_IMG)
        printf("%3d(SP) %8d %4d %7.4f %7.4f %7.4f  %5d    %3d\n",
          frame_no, stat->bit_ctr-stat->bit_ctr_n,
          img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, intras);
      else
        printf("%3d(P)  %8d %4d %7.4f %7.4f %7.4f  %5d    %3d\n",
          frame_no, stat->bit_ctr-stat->bit_ctr_n,
          img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, intras);
    }
    else
    {
      stat->bit_ctr_B += stat->bit_ctr-stat->bit_ctr_n;
      printf("%3d(B)  %8d %4d %7.4f %7.4f %7.4f  %5d \n",
        frame_no, stat->bit_ctr-stat->bit_ctr_n, img->qp,
        snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
    }
  }
  stat->bit_ctr_n=stat->bit_ctr;


  if(img->number == 0)
    return 0;
  else
    return 1;
}


/*!
 ************************************************************************
 * \brief
 *    Encodes one slice
 ************************************************************************
 */
void encode_one_slice(SyntaxElement *sym)
{
  Boolean end_of_slice = FALSE;
  Boolean recode_macroblock;
  int len;

  img->cod_counter=0;

  // Initializes the parameters of the current slice
  init_slice();

  // Write slice or picture header
  len = start_slice(sym);

  Byte_Pos_After_Header = img->currentSlice->partArr[0].bitstream->byte_pos;
  Bits_To_Go_After_Header = img->currentSlice->partArr[0].bitstream->bits_to_go;

  if (input->of_mode==PAR_OF_RTP)
  {
    assert (Byte_Pos_After_Header > 0);     // there must be a header
    assert (Bits_To_Go_After_Header == 8);  // byte alignment must have been established
  }

  // Update statistics
  stat->bit_slice += len;
  stat->bit_use_header[img->type] += len;

  while (end_of_slice == FALSE) // loop over macroblocks
  {
    // recode_macroblock is used in slice mode two and three where
    // backing of one macroblock in the bitstream is possible
    recode_macroblock = FALSE;

    // Initializes the current macroblock
    start_macroblock();

    // Encode one macroblock
    encode_one_macroblock();

    // Pass the generated syntax elements to the NAL
    write_one_macroblock();

    // Terminate processing of the current macroblock
    terminate_macroblock(&end_of_slice, &recode_macroblock);

    if (recode_macroblock == FALSE)         // The final processing of the macroblock has been done
      proceed2nextMacroblock(); // Go to next macroblock

  }
  terminate_slice();
}


/*!
 ************************************************************************
 * \brief
 *    Initializes the parameters for a new frame
 ************************************************************************
 */
void init_frame()
{
  int i,j,k;
  int prevP_no, nextP_no;

  img->current_mb_nr=0;
  img->current_slice_nr=0;
  stat->bit_slice = 0;

  if(input->UseConstrainedIntraPred)
  {
    for (i=0; i<img->total_number_mb; i++)
      img->intra_mb[i] = 1; // default 1 = intra mb
  }

  img->mhor  = img->width *4-1;
  img->mvert = img->height*4-1;

  img->mb_y = img->mb_x = 0;
  img->block_y = img->pix_y = img->pix_c_y = 0;   // define vertical positions
  img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; // define horizontal positions

  if (input->intra_upd > 0 && img->mb_y <= img->mb_y_intra)
    img->height_err=(img->mb_y_intra*16)+15;     // for extra intra MB
  else
    img->height_err=img->height-1;

  if(img->type != B_IMG)
  {
    img->refPicID ++;

⌨️ 快捷键说明

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