
/*!
 **************************************************************************************
 * \file
 *    slice.c
 * \brief
 *    generate the slice header, setup the bit buffer for slices,
 *    and generates the slice NALU(s)

 * \author
 *    Main contributors (see contributors.h for copyright, address and affiliation details)
 *      - Thomas Stockhammer            <stockhammer@ei.tum.de>
 *      - Detlev Marpe                  <marpe@hhi.de>
 *      - Stephan Wenger                <stewe@cs.tu-berlin.de>
 *      - Alexis Michael Tourapis       <alexismt@ieee.org>
 ***************************************************************************************
 */

#include "contributors.h"

#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <float.h>

#include "global.h"
#include "header.h"
#include "rtp.h"
#include "fmo.h"
#include "vlc.h"
#include "image.h"
#include "cabac.h"
#include "elements.h"
#include "me_epzs.h"
#include "ratectl.h"
#include "rc_quadratic.h"
#include "macroblock.h"
#include "symbol.h"

// Local declarations
static Slice *malloc_slice();
static void  free_slice(Slice *slice);
static void  init_slice(int start_mb_addr);
static void set_ref_pic_num();
extern ColocatedParams *Co_located;
extern StorablePicture **listX[6];
void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no);
void SetLagrangianMultipliers();

/*!
 ************************************************************************
 * \brief
 *    init_ref_pic_list_reordering initializations should go here
 ************************************************************************
 */
void init_ref_pic_list_reordering()
{
  Slice* currSlice = img->currentSlice;

  currSlice->ref_pic_list_reordering_flag_l0 = 0;
  currSlice->ref_pic_list_reordering_flag_l1 = 0;
}


/*!
 ************************************************************************
 *  \brief
 *     This function generates the slice (and partition) header(s)
 *
 *  \return number of bits used for the slice (and partition) header(s)
 *
 *  \par Side effects:
 *      Adds slice/partition header symbols to the symbol buffer
 *      increments Picture->no_slices, allocates memory for the
 *      slice, sets img->currSlice
 ************************************************************************
*/
int start_slice()
{
  EncodingEnvironmentPtr eep;
  Slice *currSlice = img->currentSlice;
  Bitstream *currStream;
  int header_len = 0;
  int i;
  int NumberOfPartitions = (input->partition_mode == PAR_DP_1?1:3);

  //one  partition for IDR img
  if(img->currentPicture->idr_flag)
  {
     NumberOfPartitions = 1;
  }

  RTPUpdateTimestamp (img->tr);   // this has no side effects, just leave it for all NALs

  for (i=0; i<NumberOfPartitions; i++)
  {
    currStream = (currSlice->partArr[i]).bitstream;

    currStream->write_flag = 0;
    if (i==0)     // First partition
      header_len += SliceHeader (0);
    else          // Second/Third partition
      header_len += Partition_BC_Header(i);

    //! Initialize CABAC
    if (input->symbol_mode == CABAC)
    {
      eep = &((currSlice->partArr[i]).ee_cabac);
      if (currStream->bits_to_go != 8)
        header_len+=currStream->bits_to_go;
      writeVlcByteAlign(currStream);
      arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
      cabac_new_slice();
    }
    else
    {
      // Initialize CA-VLC
      CAVLC_init();
    }
  }
  if(input->symbol_mode == CABAC)
  {
    init_contexts();
  }
  return header_len;
}



/*!
 ************************************************************************
 * \brief
 *    This function terminates a slice (but doesn't write it out),
 *    the old terminate_slice (0)
 * \return
 *    0 if OK,                                                         \n
 *    1 in case of error
 *
 ************************************************************************
 */
int terminate_slice(int lastslice)
{
  static int MbWidthC  [4]= { 0, 8, 8,  16};
  static int MbHeightC [4]= { 0, 8, 16, 16};

  int bytes_written;
  Bitstream *currStream;
  Slice *currSlice = img->currentSlice;
  EncodingEnvironmentPtr eep;
  int i;
  int byte_pos_before_startcode_emu_prevention;
  int min_num_bytes=0;
  int stuffing_bytes=0;
  int RawMbBits;

  if (input->symbol_mode == CABAC)
    write_terminating_bit (1);      // only once, not for all partitions

  for (i=0; i<currSlice->max_part_nr; i++)
  {
    currStream = (currSlice->partArr[i]).bitstream;
    if (input->symbol_mode == UVLC)
    {
      SODBtoRBSP(currStream);
      byte_pos_before_startcode_emu_prevention = currStream->byte_pos;
      currStream->byte_pos = RBSPtoEBSP(currStream->streamBuffer, 0 , currStream->byte_pos, 0);
      *(stats->em_prev_bits) += (currStream->byte_pos - byte_pos_before_startcode_emu_prevention) * 8;
    }
    else     // CABAC
    {
      eep = &((currSlice->partArr[i]).ee_cabac);
      // terminate the arithmetic code
      arienco_done_encoding(eep);
      currStream->bits_to_go = eep->Ebits_to_go;
      currStream->byte_buf = 0;
      bytes_written = currStream->byte_pos;
      img->bytes_in_picture += currStream->byte_pos;

      byte_pos_before_startcode_emu_prevention= currStream->byte_pos;
      if (lastslice && i==((currSlice->max_part_nr-1)))
      {
        RawMbBits = 256 * img->bitdepth_luma + 2 * MbWidthC[active_sps->chroma_format_idc] * MbHeightC[active_sps->chroma_format_idc] * img->bitdepth_chroma;
        min_num_bytes = ((96 * get_pic_bin_count()) - (RawMbBits * (int)img->PicSizeInMbs *3) + 1023) / 1024;
        if (min_num_bytes>img->bytes_in_picture)
        {
          stuffing_bytes = min_num_bytes - img->bytes_in_picture;
          printf ("CABAC stuffing words = %6d\n", stuffing_bytes/3);
        }
      }

//      printf ("bytepos: %d\n", currStream->byte_pos);
      currStream->byte_pos = RBSPtoEBSP(currStream->streamBuffer, 0, currStream->byte_pos, currStream->byte_pos + stuffing_bytes);
      *(stats->em_prev_bits) += (currStream->byte_pos - byte_pos_before_startcode_emu_prevention) * 8;
    }           // CABAC
  }           // partition loop
  if( input->symbol_mode == CABAC )
  {
    store_contexts();
  }

  if (img->type != I_SLICE || img->type != SI_SLICE)
    free_ref_pic_list_reordering_buffer (currSlice);
  return 0;
}

/*!
************************************************************************
* \brief
*    Encodes one slice
* \par
*   returns the number of coded MBs in the SLice
************************************************************************
*/
int encode_one_slice (int SliceGroupId, Picture *pic, int TotalCodedMBs)
{
  Boolean end_of_slice = FALSE;
  Boolean recode_macroblock;
  int len;
  int NumberOfCodedMBs = 0;
  int CurrentMbAddr;
  double FrameRDCost = DBL_MAX, FieldRDCost = DBL_MAX;

  img->cod_counter = 0;

  CurrentMbAddr = FmoGetFirstMacroblockInSlice (SliceGroupId);
// printf ("\n\nEncode_one_slice: PictureID %d SliceGroupId %d  SliceID %d  FirstMB %d \n", img->tr, SliceGroupId, img->current_slice_nr, CurrentMbInScanOrder);

  init_slice (CurrentMbAddr);
  Bytes_After_Header = img->currentSlice->partArr[0].bitstream->byte_pos;

  SetLagrangianMultipliers();

  if (input->symbol_mode==CABAC)
  {
    SetCtxModelNumber ();
  }

  img->checkref = (input->rdopt && input->RestrictRef && (img->type==P_SLICE || img->type==SP_SLICE));

/*
  // Tian Dong: June 7, 2002 JVT-B042
  // When the pictures are put into different layers and subseq, not all the reference frames
  // in multi-frame buffer are valid for prediction. The acutual number of the valid reference
  // frames, fb->num_short_used, will be given by start_slice(sym).
  // Save the fb->short_used.
  if (input->NumFramesInELSubSeq)
    {
      short_used = fb->short_used;
    }
*/

  len = start_slice ();

  // Rate control
  if (input->RCEnable)
  {
    generic_RC->NumberofHeaderBits +=len;

    // basic unit layer rate control
    if(img->BasicUnit < img->FrameSizeInMbs)
      generic_RC->NumberofBasicUnitHeaderBits +=len;
  }
//  printf("short size, used, num-used: (%d,%d,%d)\n", fb->short_size, fb->short_used, fb->num_short_used);

/*
  // Tian Dong: June 7, 2002 JVT-B042
  if (input->NumFramesInELSubSeq)
    {
      fb->short_used = fb->num_short_used;
    }
*/
  // Update statistics
  stats->bit_slice += len;
  stats->bit_use_header[img->type] += len;
// printf ("\n\n");

  while (end_of_slice == FALSE) // loop over macroblocks
  {
    if (img->AdaptiveRounding && input->AdaptRndPeriod && (img->current_mb_nr % input->AdaptRndPeriod == 0))
    {
      CalculateOffsetParam();

      if(input->Transform8x8Mode)
      {
        CalculateOffset8Param();
      }
    }

    //sw paff
    if (!img->MbaffFrameFlag)
    {
      recode_macroblock = FALSE;
      rdopt = &rddata_top_frame_mb;   // store data in top frame MB

      start_macroblock (CurrentMbAddr, FALSE);
      encode_one_macroblock ();

      write_one_macroblock (1);

      terminate_macroblock (&end_of_slice, &recode_macroblock);

//       printf ("encode_one_slice: mb %d,  slice %d,   bitbuf bytepos %d EOS %d\n",
//       img->current_mb_nr, img->current_slice_nr,
//       img->currentSlice->partArr[0].bitstream->byte_pos, end_of_slice);

      if (recode_macroblock == FALSE)       // The final processing of the macroblock has been done
      {
        CurrentMbAddr = FmoGetNextMBNr (CurrentMbAddr);
        if (CurrentMbAddr == -1)   // end of slice
        {
//          printf ("FMO End of Slice Group detected, current MBs %d, force end of slice\n", NumberOfCodedMBs+1);
          end_of_slice = TRUE;
        }
        NumberOfCodedMBs++;       // only here we are sure that the coded MB is actually included in the slice
        proceed2nextMacroblock ();
      }
      else
      {
        //!Go back to the previous MB to recode it
        img->current_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
        if(img->current_mb_nr == -1 )   // The first MB of the slice group  is too big,
                                        // which means it's impossible to encode picture using current slice bits restriction
        {
          snprintf (errortext, ET_SIZE, "Error encoding first MB with specified parameter, bits of current MB may be too big");
          error (errortext, 300);
        }
      }
    }
    else                      // TBD -- Addition of FMO
    {

//! This following ugly code breaks slices, at least for a slice mode that accumulates a certain
//! number of bits into one slice.
//! The suggested algorithm is as follows:
//!
//! SaveState (Bitstream, stats,  etc. etc.);
//! BitsForThisMBPairInFrameMode = CodeMB (Upper, FRAME_MODE) + CodeMB (Lower, FRAME_MODE);
//! DistortionForThisMBPairInFrameMode = CalculateDistortion(Upper) + CalculateDistortion (Lower);
//! RestoreState();
//! BitsForThisMBPairInFieldMode = CodeMB (Upper, FIELD_MODE) + CodeMB (Lower, FIELD_MODE);
//! DistortionForThisMBPairInFrameMode = CalculateDistortion(Upper) + CalculateDistortion (Lower);
//! FrameFieldMode = Decision (...)
//! RestoreState()
//! if (FrameFieldMode == FRAME) {
//!   CodeMB (Upper, FRAME); CodeMB (Lower, FRAME);
//! } else {
//!   CodeMB (Upper FIELD); CodeMB (Lower, FIELD);
//! }
//!
//! Open questions/issues:
//!   1. CABAC/CA-VLC state:  It seems that the CABAC/CA_VLC states are changed during the
//!      dummy encoding processes (for the R-D based selection), but that they are never
//!      reset, once the selection is made.  I believe that this breaks the MB-adaptive
//!      frame/field coding.  The necessary code for the state saves is readily available
//!      in macroblock.c, start_macroblock() and terminate_macroblock() (this code needs
//!      to be double checked that it works with CA-VLC as well
//!   2. would it be an option to allocate Bitstreams with zero data in them (or copy the
//!      already generated bitstream) for the "test coding"?

      img->write_macroblock = 0;
      if (input->MbInterlace == ADAPTIVE_CODING || input->MbInterlace == FRAME_MB_PAIR_CODING)
      {
        //================ code MB pair as frame MB ================
        //----------------------------------------------------------
        recode_macroblock = FALSE;

        img->field_mode = 0;  // MB coded as frame
        img->top_field = 0;   // Set top field to 0

        //Rate control
        img->write_macroblock = 0;
        img->bot_MB = 0;

        // save RC state only when it is going to change
        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING
          && img->NumberofCodedMacroBlocks > 0 && (img->NumberofCodedMacroBlocks % img->BasicUnit) == 0 )
          copy_rc_jvt( quadratic_RC_init, quadratic_RC ); // save initial RC status

        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING )
          copy_rc_generic( generic_RC_init, generic_RC ); // save initial RC status

        start_macroblock (CurrentMbAddr, FALSE);

        rdopt = &rddata_top_frame_mb; // store data in top frame MB
        encode_one_macroblock ();         // code the MB as frame

        FrameRDCost = rdopt->min_rdcost;
        //***   Top MB coded as frame MB ***//

        //Rate control
        img->bot_MB = 1; //for Rate control

        // go to the bottom MB in the MB pair
        img->field_mode = 0;  // MB coded as frame  //GB

        start_macroblock (CurrentMbAddr+1, FALSE);
        rdopt = &rddata_bot_frame_mb; // store data in top frame MB
        encode_one_macroblock ();         // code the MB as frame

        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING
          && img->NumberofCodedMacroBlocks > 0 && (img->NumberofCodedMacroBlocks % img->BasicUnit) == 0 )
          copy_rc_jvt( quadratic_RC_best, quadratic_RC ); // restore initial RC status

        if (input->RCEnable && input->MbInterlace == ADAPTIVE_CODING )
          copy_rc_generic( generic_RC_best, generic_RC ); // save frame RC stats

        FrameRDCost += rdopt->min_rdcost;

        //***   Bottom MB coded as frame MB ***//
      }

      if ((input->MbInterlace == ADAPTIVE_CODING) || (input->MbInterlace == FIELD_CODING))
      {
        //Rate control
        img->bot_MB = 0;

        //=========== start coding the MB pair as a field MB pair =============
        //---------------------------------------------------------------------
        img->field_mode = 1;  // MB coded as field
        img->top_field = 1;   // Set top field to 1
        img->buf_cycle <<= 1;
        input->num_ref_frames <<= 1;
        img->num_ref_idx_l0_active <<= 1;
        img->num_ref_idx_l0_active += 1;

        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING
          && img->NumberofCodedMacroBlocks > 0 && (img->NumberofCodedMacroBlocks % img->BasicUnit) == 0 )
          copy_rc_jvt( quadratic_RC, quadratic_RC_init ); // restore initial RC status

        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING )
          copy_rc_generic( generic_RC, generic_RC_init ); // reset RC stats

        start_macroblock (CurrentMbAddr, TRUE);

        rdopt = &rddata_top_field_mb; // store data in top frame MB
//        TopFieldIsSkipped = 0;        // set the top field MB skipped flag to 0
        encode_one_macroblock ();         // code the MB as field

        FieldRDCost = rdopt->min_rdcost;
        //***   Top MB coded as field MB ***//
        //Rate control
        img->bot_MB = 1;//for Rate control

        img->top_field = 0;   // Set top field to 0
        start_macroblock (CurrentMbAddr+1, TRUE);
        rdopt = &rddata_bot_field_mb; // store data in top frame MB
        encode_one_macroblock ();         // code the MB as field

        FieldRDCost += rdopt->min_rdcost;
        //***   Bottom MB coded as field MB ***//
      }

      //Rate control
      img->write_mbaff_frame = 0;  //Rate control

      //=========== decide between frame/field MB pair ============
      //-----------------------------------------------------------
      if ( ((input->MbInterlace == ADAPTIVE_CODING) && (FrameRDCost < FieldRDCost)) || input->MbInterlace == FRAME_MB_PAIR_CODING )
      {
        img->field_mode = 0;
        MBPairIsField = 0;
        if ( input->MbInterlace != FRAME_MB_PAIR_CODING )
        {
          img->buf_cycle >>= 1;
          input->num_ref_frames >>= 1;
          img->num_ref_idx_l0_active -= 1;
          img->num_ref_idx_l0_active >>= 1;
        }

        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING
          && img->NumberofCodedMacroBlocks > 0 && (img->NumberofCodedMacroBlocks % img->BasicUnit) == 0 )
          copy_rc_jvt( quadratic_RC, quadratic_RC_best ); // restore initial RC status

        if ( input->RCEnable && input->MbInterlace == ADAPTIVE_CODING )
          copy_rc_generic( generic_RC, generic_RC_best ); // restore frame RC stats

        //Rate control
        img->write_mbaff_frame = 1;  //for Rate control
      }
      else
      {
        img->field_mode = 1;
        MBPairIsField = 1;
      }

      //Rate control
      img->write_macroblock = 1;//Rate control

      if (MBPairIsField)
        img->top_field = 1;
      else
        img->top_field = 0;

      //Rate control
      img->bot_MB = 0;// for Rate control

      // go back to the Top MB in the MB pair
      start_macroblock (CurrentMbAddr, img->field_mode);

      rdopt =  img->field_mode ? &rddata_top_field_mb : &rddata_top_frame_mb;
      copy_rdopt_data (0);  // copy the MB data for Top MB from the temp buffers
      write_one_macroblock (1);     // write the Top MB data to the bitstream
      terminate_macroblock (&end_of_slice, &recode_macroblock);     // done coding the Top MB

      if (recode_macroblock == FALSE)       // The final processing of the macroblock has been done
      {
        CurrentMbAddr = FmoGetNextMBNr (CurrentMbAddr);
        if (CurrentMbAddr == -1)   // end of slice
        {
          end_of_slice = TRUE;
        }
        NumberOfCodedMBs++;       // only here we are sure that the coded MB is actually included in the slice
        proceed2nextMacroblock ();


        //Rate control
        img->bot_MB = 1;//for Rate control
        // go to the Bottom MB in the MB pair
        img->top_field = 0;
        start_macroblock (CurrentMbAddr, img->field_mode);

        rdopt = img->field_mode ? &rddata_bot_field_mb : &rddata_bot_frame_mb;
        copy_rdopt_data (1);  // copy the MB data for Bottom MB from the temp buffers

        write_one_macroblock (0);     // write the Bottom MB data to the bitstream
        terminate_macroblock (&end_of_slice, &recode_macroblock);     // done coding the Top MB
        if (recode_macroblock == FALSE)       // The final processing of the macroblock has been done
        {
          CurrentMbAddr = FmoGetNextMBNr (CurrentMbAddr);
          if (CurrentMbAddr == -1)   // end of slice
          {
            end_of_slice = TRUE;
          }
          NumberOfCodedMBs++;       // only here we are sure that the coded MB is actually included in the slice
          proceed2nextMacroblock ();
        }
        else
        {
          //Go back to the beginning of the macroblock pair to recode it
          img->current_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
          img->current_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
          if(img->current_mb_nr == -1 )   // The first MB of the slice group  is too big,
            // which means it's impossible to encode picture using current slice bits restriction
          {
            snprintf (errortext, ET_SIZE, "Error encoding first MB with specified parameter, bits of current MB may be too big");
            error (errortext, 300);
          }
        }
      }
      else
      {
        //!Go back to the previous MB to recode it
        img->current_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
        if(img->current_mb_nr == -1 )   // The first MB of the slice group  is too big,
                                        // which means it's impossible to encode picture using current slice bits restriction
        {
          snprintf (errortext, ET_SIZE, "Error encoding first MB with specified parameter, bits of current MB may be too big");
          error (errortext, 300);
        }
      }

      if (MBPairIsField)    // if MB Pair was coded as field the buffer size variables back to frame mode
      {
        img->buf_cycle >>= 1;
        input->num_ref_frames >>= 1;
        img->num_ref_idx_l0_active -= 1;
        img->num_ref_idx_l0_active >>= 1;
      }

      img->field_mode = img->top_field = 0; // reset to frame mode

      if ( !end_of_slice )
      {
        assert( CurrentMbAddr < (int)img->PicSizeInMbs );
        assert( CurrentMbAddr >= 0 );
        if (CurrentMbAddr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (CurrentMbAddr)))
          end_of_slice = TRUE;        // just in case it doesn't get set in terminate_macroblock
      }
    }
  }
/*
  // Tian Dong: June 7, 2002 JVT-B042
  // Restore the short_used
  if (input->NumFramesInELSubSeq)
    {
      fb->short_used = short_used;
    }
*/
  terminate_slice ( (NumberOfCodedMBs+TotalCodedMBs >= (int)img->PicSizeInMbs) );
  return NumberOfCodedMBs;
}



/*!
 ************************************************************************
 * \brief
 *    Initializes the parameters for a new slice and
 *     allocates the memory for the coded slice in the Picture structure
 *  \par Side effects:
 *      Adds slice/partition header symbols to the symbol buffer
 *      increments Picture->no_slices, allocates memory for the
 *      slice, sets img->currSlice
 ************************************************************************
 */
static void init_slice (int start_mb_addr)
{
  int i;
  Picture *currPic = img->currentPicture;
  DataPartition *dataPart;
  Bitstream *currStream;
  Slice *currSlice;

  img->current_mb_nr = start_mb_addr;

  // Allocate new Slice in the current Picture, and set img->currentSlice
  assert (currPic != NULL);
  currPic->no_slices++;

  if (currPic->no_slices >= MAXSLICEPERPICTURE)
    error ("Too many slices per picture, increase MAXSLICEPERPICTURE in global.h.", -1);

  currPic->slices[currPic->no_slices-1] = malloc_slice();
  currSlice = currPic->slices[currPic->no_slices-1];

  img->currentSlice = currSlice;

  currSlice->picture_id = img->tr % 256;
  currSlice->qp = img->qp;
  currSlice->start_mb_nr = start_mb_addr;
  currSlice->slice_too_big = dummy_slice_too_big;

  for (i = 0; i < currSlice->max_part_nr; i++)
  {
    dataPart = &(currSlice->partArr[i]);

    currStream = dataPart->bitstream;
    currStream->bits_to_go = 8;
    currStream->byte_pos = 0;
    currStream->byte_buf = 0;
  }

  img->num_ref_idx_l0_active = active_pps->num_ref_idx_l0_active_minus1 + 1;
  img->num_ref_idx_l1_active = active_pps->num_ref_idx_l1_active_minus1 + 1;

  // primary and redundant slices: number of references overriding.
  if(input->redundant_pic_flag)
  {
    if(!redundant_coding)
    {
      img->num_ref_idx_l0_active = imin(img->number,input->NumRefPrimary);
    }
    else
    {
      // 1 reference picture for redundant slices
      img->num_ref_idx_l0_active = 1;
    }
  }

  // code now also considers fields. Issue whether we should account this within the appropriate input params directly
  if ((img->type == P_SLICE || img->type == SP_SLICE) && input->P_List0_refs)
  {
    img->num_ref_idx_l0_active = imin(img->num_ref_idx_l0_active, input->P_List0_refs * ((img->structure !=0) + 1));
  }
  if (img->type == B_SLICE )
  {
    if (input->B_List0_refs)
    {
      img->num_ref_idx_l0_active = imin(img->num_ref_idx_l0_active, input->B_List0_refs * ((img->structure !=0) + 1));
    }
    if (input->B_List1_refs)
    {
      img->num_ref_idx_l1_active = imin(img->num_ref_idx_l1_active, input->B_List1_refs * ((img->structure !=0) + 1));
    }
  }
  // generate reference picture lists
  init_lists(img->type, (PictureStructure) img->structure);

  // assign list 0 size from list size
  img->num_ref_idx_l0_active = listXsize[0];
  img->num_ref_idx_l1_active = listXsize[1];

  //Perform memory management based on poc distances
  //if (img->nal_reference_idc  && input->HierarchicalCoding && input->PocMemoryManagement && dpb.ref_frames_in_buffer==active_sps->num_ref_frames)
  if (img->nal_reference_idc  && input->PocMemoryManagement && dpb.ref_frames_in_buffer==active_sps->num_ref_frames)
  {
    poc_based_ref_management(img->frame_num);
  }

  if (input->EnableOpenGOP)
  {
    for (i = 0; i<listXsize[0]; i++)
    {
      if (listX[0][i]->poc < img->last_valid_reference && img->ThisPOC > img->last_valid_reference)
      {
        listXsize[0] = img->num_ref_idx_l0_active = imax(1,i);
        break;
      }
    }

    for (i = 0; i<listXsize[1]; i++)
    {
      if (listX[1][i]->poc < img->last_valid_reference && img->ThisPOC > img->last_valid_reference)
      {
        listXsize[1] = img->num_ref_idx_l1_active = imax(1,i);
        break;
      }
    }
  }

  init_ref_pic_list_reordering();

  //Perform reordering based on poc distances for HierarchicalCoding
  //if (img->type==P_SLICE && input->HierarchicalCoding && input->ReferenceReorder)
  if (img->type==P_SLICE && input->ReferenceReorder)
  {

    int i, num_ref;

    alloc_ref_pic_list_reordering_buffer(currSlice);

    if ((img->type != I_SLICE) && (img->type !=SI_SLICE))
    {
      for (i=0; i<img->num_ref_idx_l0_active + 1; i++)
      {
        currSlice->reordering_of_pic_nums_idc_l0[i] = 3;
        currSlice->abs_diff_pic_num_minus1_l0[i] = 0;
        currSlice->long_term_pic_idx_l0[i] = 0;
      }

      if (img->type == B_SLICE)
      {
        for (i=0; i<img->num_ref_idx_l1_active + 1; i++)
        {
          currSlice->reordering_of_pic_nums_idc_l1[i] = 3;
          currSlice->abs_diff_pic_num_minus1_l1[i] = 0;
          currSlice->long_term_pic_idx_l1[i] = 0;
        }
      }
    }

    if ((img->type != I_SLICE) && (img->type !=SI_SLICE))
    {
      num_ref = img->num_ref_idx_l0_active;
      poc_ref_pic_reorder(listX[LIST_0],
                          num_ref,
                          currSlice->reordering_of_pic_nums_idc_l0,
                          currSlice->abs_diff_pic_num_minus1_l0,
                          currSlice->long_term_pic_idx_l0, LIST_0);

      //reference picture reordering
      reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0],
                           img->num_ref_idx_l0_active - 1,
                           currSlice->reordering_of_pic_nums_idc_l0,
                           currSlice->abs_diff_pic_num_minus1_l0,
                           currSlice->long_term_pic_idx_l0);

    // This is not necessary since order is already poc based...
      if (img->type == B_SLICE)
      {
        num_ref = img->num_ref_idx_l1_active;
        poc_ref_pic_reorder(listX[LIST_1],
                            num_ref,
                            currSlice->reordering_of_pic_nums_idc_l1,
                            currSlice->abs_diff_pic_num_minus1_l1,
                            currSlice->long_term_pic_idx_l1, LIST_1);

        //reference picture reordering
        reorder_ref_pic_list(listX[LIST_1], &listXsize[LIST_1],
                             img->num_ref_idx_l1_active - 1,
                             currSlice->reordering_of_pic_nums_idc_l1,
                             currSlice->abs_diff_pic_num_minus1_l1,
                             currSlice->long_term_pic_idx_l1);
      }
    }
  }


  //if (img->MbaffFrameFlag)
  if (img->structure==FRAME)
    init_mbaff_lists();

  if (img->type != I_SLICE && (active_pps->weighted_pred_flag == 1 || (active_pps->weighted_bipred_idc > 0 && (img->type == B_SLICE))))
  {
    if (img->type==P_SLICE || img->type==SP_SLICE)
    {
      if (input->GenerateMultiplePPS && input->RDPictureDecision)
      {
        if (enc_picture==enc_frame_picture2)
          estimate_weighting_factor_P_slice (0);
        else
          estimate_weighting_factor_P_slice (1);
      }
      else
        estimate_weighting_factor_P_slice (0);

    }
    else
       estimate_weighting_factor_B_slice ();
  }

  set_ref_pic_num();

  if (img->type == B_SLICE)
    compute_colocated(Co_located, listX);
  if (img->type != I_SLICE && input->SearchMode == EPZS)
    EPZSSliceInit(EPZSCo_located, listX);

  if (input->symbol_mode == UVLC)
  {
    writeMB_typeInfo       = writeSE_UVLC;
    writeIntraPredMode     = writeIntraPredMode_CAVLC;
    writeB8_typeInfo       = writeSE_UVLC;
    for (i=0; i<6; i++)
    {
      switch (listXsize[i])
      {
      case 0:
        writeRefFrame[i]     = NULL;
        break;
      case 1:
        writeRefFrame[i]     = writeSE_Dummy;
        break;
      case 2:
        writeRefFrame[i]     = writeSE_invFlag;
        break;
      default:
        writeRefFrame[i]     = writeSE_UVLC;
        break;
      }
    }
    writeMVD               = writeSE_SVLC;
    writeCBP               = writeCBP_VLC;
    writeDquant            = writeSE_SVLC;
    writeCIPredMode        = writeSE_UVLC;
    writeFieldModeInfo     = writeSE_Flag;
    writeMB_transform_size = writeSE_Flag;
  }
  else
  {
    writeMB_typeInfo       = writeMB_typeInfo_CABAC;
    writeIntraPredMode     = writeIntraPredMode_CABAC;
    writeB8_typeInfo       = writeB8_typeInfo_CABAC;
    for (i=0; i<6; i++)
    {
      switch (listXsize[i])
      {
      case 0:
        writeRefFrame[i]     = NULL;
      case 1:
        writeRefFrame[i]     = writeSE_Dummy;
        break;
      default:
        writeRefFrame[i]     = writeRefFrame_CABAC;
      }
    }
    writeMVD               = writeMVD_CABAC;
    writeCBP               = writeCBP_CABAC;
    writeDquant            = writeDquant_CABAC;
    writeCIPredMode        = writeCIPredMode_CABAC;
    writeFieldModeInfo     = writeFieldModeInfo_CABAC;
    writeMB_transform_size = writeMB_transform_size_CABAC;
  }

}


/*!
 ************************************************************************
 * \brief
 *    Allocates a slice structure along with its dependent data structures
 * \return
 *    Pointer to a Slice
 ************************************************************************
 */
static Slice *malloc_slice()
{
  int i;
  DataPartition *dataPart;
  Slice *slice;

//  const int buffer_size = (img->size * 4); // AH 190202: There can be data expansion with
                                                          // low QP values. So, we make sure that buffer
                                                          // does not overflow. 4 is probably safe multiplier.
  int buffer_size;

  switch (input->slice_mode)
  {
  case 2:
    buffer_size = 2 * input->slice_argument;
    break;
  case 1:
    buffer_size = 500 + input->slice_argument * (128 + 256 * img->bitdepth_luma + 512 * img->bitdepth_chroma);;
    break;
  default:
    buffer_size = 500 + img->FrameSizeInMbs * (128 + 256 * img->bitdepth_luma + 512 * img->bitdepth_chroma);
    break;
  }

                                                          // KS: this is approx. max. allowed code picture size

  if ((slice = (Slice *) calloc(1, sizeof(Slice))) == NULL) no_mem_exit ("malloc_slice: slice structure");

  if (input->symbol_mode == CABAC)
    {
      // create all context models
      slice->mot_ctx = create_contexts_MotionInfo();
      slice->tex_ctx = create_contexts_TextureInfo();
    }

  slice->max_part_nr = input->partition_mode==0?1:3;

  //for IDR img there should be only one partition
  if(img->currentPicture->idr_flag)
    slice->max_part_nr = 1;

  assignSE2partition[0] = assignSE2partition_NoDP;
  //ZL
  //for IDR img all the syntax element should be mapped to one partition
  if(!img->currentPicture->idr_flag&&input->partition_mode==1)
    assignSE2partition[1] =  assignSE2partition_DP;
  else
    assignSE2partition[1] =  assignSE2partition_NoDP;



  slice->num_mb = 0;          // no coded MBs so far

  if ((slice->partArr = (DataPartition *) calloc(slice->max_part_nr, sizeof(DataPartition))) == NULL) no_mem_exit ("malloc_slice: partArr");
  for (i=0; i<slice->max_part_nr; i++) // loop over all data partitions
  {
    dataPart = &(slice->partArr[i]);
    if ((dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream))) == NULL) no_mem_exit ("malloc_slice: Bitstream");
    if ((dataPart->bitstream->streamBuffer = (byte *) calloc(buffer_size, sizeof(byte))) == NULL) no_mem_exit ("malloc_slice: StreamBuffer");
    // Initialize storage of bitstream parameters
  }
  return slice;
}


/*!
 ************************************************************************
 * \brief
 *    Memory frees of all Slice structures and of its dependent
 *    data structures
 * \par Input:
 *    Image Parameters struct struct img_par *img
 ************************************************************************
 */
void free_slice_list(Picture *currPic)
{
  int i;

  for (i=0; i<currPic->no_slices; i++)
  {
    free_slice (currPic->slices[i]);
    currPic->slices[i]=NULL;
  }
}


/*!
 ************************************************************************
 * \brief
 *    Memory frees of the Slice structure and of its dependent
 *    data structures
 * \param slice:
 *    Slice to be freed
 ************************************************************************
 */
static void free_slice(Slice *slice)
{
  int i;
  DataPartition *dataPart;

  if (slice != NULL)
  {
    for (i=0; i<slice->max_part_nr; i++) // loop over all data partitions
    {
      dataPart = &(slice->partArr[i]);
      if (dataPart != NULL)
      {
        if (dataPart->bitstream->streamBuffer != NULL)
          free(dataPart->bitstream->streamBuffer);
        if (dataPart->bitstream != NULL)
          free(dataPart->bitstream);
      }
    }
    if (slice->partArr != NULL)
      free(slice->partArr);
    if (input->symbol_mode == CABAC)
    {
      delete_contexts_MotionInfo(slice->mot_ctx);
      delete_contexts_TextureInfo(slice->tex_ctx);
    }

    free(slice);
  }
}

void set_ref_pic_num()
{
  int i,j;
  StorablePicture *this_ref;

  //! need to add field ref_pic_num that handles field pair.

  for (i=0;i<listXsize[LIST_0];i++)
  {
    this_ref = listX[LIST_0][i];
    enc_picture->ref_pic_num        [LIST_0][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0) ;
    enc_picture->frm_ref_pic_num    [LIST_0][i] = this_ref->frame_poc * 2;
    enc_picture->top_ref_pic_num    [LIST_0][i] = this_ref->top_poc * 2;
    enc_picture->bottom_ref_pic_num [LIST_0][i] = this_ref->bottom_poc * 2 + 1;
  }

  for (i=0;i<listXsize[LIST_1];i++)
  {
    this_ref = listX[LIST_1][i];
    enc_picture->ref_pic_num        [LIST_1][i] = this_ref->poc  *2 + ((this_ref->structure==BOTTOM_FIELD)?1:0);
    enc_picture->frm_ref_pic_num    [LIST_1][i] = this_ref->frame_poc * 2;
    enc_picture->top_ref_pic_num    [LIST_1][i] = this_ref->top_poc * 2;
    enc_picture->bottom_ref_pic_num [LIST_1][i] = this_ref->bottom_poc * 2 + 1;
  }

  if (!active_sps->frame_mbs_only_flag && img->structure==FRAME)
  {
    for (j=2;j<6;j++)
      for (i=0;i<listXsize[j];i++)
      {
        this_ref = listX[j][i];
        enc_picture->ref_pic_num[j][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0);
        enc_picture->frm_ref_pic_num[j][i] = this_ref->frame_poc * 2 ;
        enc_picture->top_ref_pic_num[j][i] = this_ref->top_poc * 2 ;
        enc_picture->bottom_ref_pic_num[j][i] = this_ref->bottom_poc * 2 + 1;
      }
  }
}

/*!
************************************************************************
* \brief
*    decide reference picture reordering, Frame only
************************************************************************
*/
void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
{
  unsigned i,j,k;

  int currPicNum, picNumLXPred;

  int default_order[32];
  int re_order[32];
  int tmp_reorder[32];
  int list_sign[32];
  int reorder_stop, no_reorder;
  int poc_diff[32];
  int tmp_value, diff;

  int abs_poc_dist;
  int maxPicNum, MaxFrameNum = 1 << (log2_max_frame_num_minus4 + 4);

  if (img->structure==FRAME)
  {
    maxPicNum  = MaxFrameNum;
    currPicNum = img->frame_num;
  }
  else
  {
    maxPicNum  = 2 * MaxFrameNum;
    currPicNum = 2 * img->frame_num + 1;
  }

  picNumLXPred = currPicNum;

  // First assign default list order.
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    default_order[i] = list[i]->pic_num;
  }

  // Now access all references in buffer and assign them
  // to a pottential reordering list. For each one of these
  // references compute the poc distance compared to current
  // frame.
  for (i=0; i<dpb.ref_frames_in_buffer; i++)
  {
    re_order[i] = dpb.fs_ref[i]->frame->pic_num;

    if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
    {
      abs_poc_dist = iabs(dpb.fs_ref[i]->frame->poc - enc_picture->poc) ;
      poc_diff[i] = abs_poc_dist;
      if (list_no == LIST_0)
      {
        list_sign[i] = (enc_picture->poc < dpb.fs_ref[i]->frame->poc) ? +1 : -1;
      }
      else
      {
        list_sign[i] = (enc_picture->poc > dpb.fs_ref[i]->frame->poc) ? +1 : -1;
      }
    }
  }


  // now sort these references based on poc (temporal) distance
  for (i=0; i< dpb.ref_frames_in_buffer-1; i++)
  {
    for (j=i+1; j< dpb.ref_frames_in_buffer; j++)
    {
      if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
      {

        tmp_value = poc_diff[i];
        poc_diff[i] = poc_diff[j];
        poc_diff[j] = tmp_value;
        tmp_value  = re_order[i];
        re_order[i] = re_order[j];
        re_order[j] = tmp_value ;
        tmp_value  = list_sign[i];
        list_sign[i] = list_sign[j];
        list_sign[j] = tmp_value ;
      }
    }
  }

  // Check versus default list to see if any
  // change has happened
  no_reorder = 1;
  for (i=0; i<num_ref_idx_lX_active; i++)
  {
    if (default_order[i] != re_order[i])
    {
      no_reorder = 0;
    }
  }

  // If different, then signal reordering
  if (no_reorder==0)
  {
    for (i=0; i<num_ref_idx_lX_active; i++)
    {
      diff = re_order[i]-picNumLXPred;
      if (diff <= 0)
      {
        reordering_of_pic_nums_idc[i] = 0;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
        if (abs_diff_pic_num_minus1[i] < 0)
          abs_diff_pic_num_minus1[i] = maxPicNum -1;
      }
      else
      {
        reordering_of_pic_nums_idc[i] = 1;
        abs_diff_pic_num_minus1[i] = iabs(diff)-1;
      }
      picNumLXPred = re_order[i];

      tmp_reorder[i] = re_order[i];

      k = i;
      for (j=i; j<num_ref_idx_lX_active; j++)
      {
        if (default_order[j] != re_order[i])
        {
          ++k;
          tmp_reorder[k] = default_order[j];
        }
      }
      reorder_stop = 1;
      for(j=i+1; j<num_ref_idx_lX_active; j++)
      {
        if (tmp_reorder[j] != re_order[j])
        {
          reorder_stop = 0;
          break;
        }
      }

      if (reorder_stop==1)
      {
        ++i;
        break;
      }

      for(j=0; j<num_ref_idx_lX_active; j++)
      {
        default_order[j] = tmp_reorder[j];
      }

    }
    reordering_of_pic_nums_idc[i] = 3;

    for(j=0; j<num_ref_idx_lX_active; j++)
    {
      default_order[j] = tmp_reorder[j];
    }

    if (list_no==0)
    {
      img->currentSlice->ref_pic_list_reordering_flag_l0=1;
    }
    else
    {
      img->currentSlice->ref_pic_list_reordering_flag_l1=1;
    }
  }
}

extern const int QP2QUANT[40];

void SetLagrangianMultipliers()
{
  int qp, j, k;
  double qp_temp;
  double lambda_scale = 1.0 - dClip3(0.0,0.5,0.05 * (double) input->jumpd);;

  if (input->rdopt) // RDOPT on computation of Lagrangian multipliers
  {
    for (j = 0; j < 5; j++)
    {
      for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
      {
        qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;

        if (input->UseExplicitLambdaParams == 1) // consideration of explicit lambda weights.
        {
          img->lambda_md[j][qp] = input->LambdaWeight[j] * pow (2, qp_temp/3.0);
          // Scale lambda due to hadamard qpel only consideration
          img->lambda_md[j][qp] = ( (input->MEErrorMetric[H_PEL] == ERROR_SATD && input->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp];

          for (k = F_PEL; k <= Q_PEL; k++)
          {
            img->lambda_me[j][qp][k] = input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]);
            img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
          }

          if (j == B_SLICE)
          {
            img->lambda_md[5][qp] = input->LambdaWeight[5] * pow (2, qp_temp/3.0);
            img->lambda_md[5][qp] = ((input->MEErrorMetric[H_PEL] == ERROR_SATD && input->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[5][qp];

            for (k = F_PEL; k <= Q_PEL; k++)
            {
              img->lambda_me[5][qp][k] = input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[5][qp] : sqrt(img->lambda_md[5][qp]);
              img->lambda_mf[5][qp][k] = LAMBDA_FACTOR (img->lambda_me[5][qp][k]);
            }
          }
        }
        else if (input->UseExplicitLambdaParams == 2) // consideration of fixed lambda values.
        {
          img->lambda_md[j][qp] = input->FixedLambda[j];
          // Scale lambda due to hadamard qpel only consideration
          img->lambda_md[j][qp] = ( (input->MEErrorMetric[H_PEL] == ERROR_SATD && input->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp];

          for (k = F_PEL; k <= Q_PEL; k++)
          {
            img->lambda_me[j][qp][k] = input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]);
            img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
          }

          if (j == B_SLICE)
          {
            img->lambda_md[5][qp] = input->FixedLambda[5];
            img->lambda_md[5][qp] = ((input->MEErrorMetric[H_PEL] == ERROR_SATD && input->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[5][qp];

            for (k = F_PEL; k <= Q_PEL; k++)
            {
              img->lambda_me[5][qp][k] = input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[5][qp] : sqrt(img->lambda_md[5][qp]);
              img->lambda_mf[5][qp][k] = LAMBDA_FACTOR (img->lambda_me[5][qp][k]);
            }
          }
        }
        else
        {
          if (input->successive_Bframe>0)
            img->lambda_md[j][qp] = 0.68 * pow (2, qp_temp/3.0)
            * (j == B_SLICE ? dClip3(2.00,4.00,(qp_temp / 6.0)) : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0);
          else
            img->lambda_md[j][qp] = 0.85 * pow (2, qp_temp/3.0)
            * ( (j == B_SLICE) ? 4.0 : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0);
          // Scale lambda due to hadamard qpel only consideration
          img->lambda_md[j][qp] = ((input->MEErrorMetric[H_PEL] == ERROR_SATD && input->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp];
          img->lambda_md[j][qp] = (j == B_SLICE && input->BRefPictures == 2 && img->b_frame_to_code == 0 ? 0.50 : 1.00) * img->lambda_md[j][qp];

          if (j == B_SLICE)
          {
            img->lambda_md[5][qp] = img->lambda_md[j][qp];

            if (input->HierarchicalCoding == 2)
              img->lambda_md[5][qp] *= (1.0 - dmin(0.4,0.2 * (double) gop_structure[img->b_frame_to_code-1].hierarchy_layer)) ;
            else
              img->lambda_md[5][qp] *= 0.80;

            img->lambda_md[5][qp] *= lambda_scale;

            for (k = F_PEL; k <= Q_PEL; k++)
            {
              img->lambda_me[5][qp][k] = input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[5][qp] : sqrt(img->lambda_md[5][qp]);
              img->lambda_mf[5][qp][k] = LAMBDA_FACTOR (img->lambda_me[5][qp][k]);
            }
          }
          else
            img->lambda_md[j][qp] *= lambda_scale;

          for (k = F_PEL; k <= Q_PEL; k++)
          {
            img->lambda_me[j][qp][k] = input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]);
            img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
          }

          if (input->CtxAdptLagrangeMult == 1)
          {
            int lambda_qp = (qp >= 32 && !input->RCEnable) ? imax(0, qp - 4) : imax(0, qp - 6);
            img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0);
          }
        }
      }
    }
  }
  else // RDOPT off computation of Lagrangian multipliers
  {
    for (j = 0; j < 6; j++)
    {
      for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
      {
        img->lambda_md[j][qp] = QP2QUANT[imax(0,qp - SHIFT_QP)];

        for (k = F_PEL; k <= Q_PEL; k++)
        {
          img->lambda_me[j][qp][k]  = img->lambda_md[j][qp];
          img->lambda_me[j][qp][k] *= input->MEErrorMetric[k] == ERROR_SSE ? img->lambda_me[j][qp][k] : 1;
          img->lambda_mf[j][qp][k]  = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
        }

        if (input->CtxAdptLagrangeMult == 1)
        {
          int lambda_qp = (qp >= 32 && !input->RCEnable) ? imax(0, qp-4) : imax(0, qp-6);
          img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0);
        }
      }
    }
  }
}

