www.pudn.com > jm50g.zip > header.c


/* 
*********************************************************************** 
* 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 header.c 
 * 
 * \brief 
 *    H.26L Slice and Picture headers 
 * 
 ************************************************************************************* 
 */ 
 
#include  
#include  
#include  
 
#include "global.h" 
#include "elements.h" 
#include "defines.h" 
#include "fmo.h" 
 
 
#if TRACE 
#define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE) 
#else 
#define SYMTRACESTRING(s) // to nothing 
#endif 
 
 
/*! 
 ************************************************************************ 
 * \brief 
 *    read the whole Slice header without the Startcode UVLC 
 ************************************************************************ 
 */ 
int SliceHeader(struct img_par *img, struct inp_par *inp) 
{ 
  Slice *currSlice = img->currentSlice; 
  int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; 
  DataPartition *partition = &(currSlice->partArr[dP_nr]); 
  SyntaxElement sym; 
  int UsedBits= partition->bitstream->frame_bitoffset; // was hardcoded to 31 for previous start-code. This is better. 
  static int last_imgtr_frm=0,modulo_ctr_frm=0,last_imgtr_fld=0,modulo_ctr_fld=0; 
  static int last_imgtr_frm_b=0,modulo_ctr_frm_b=0,last_imgtr_fld_b=0,modulo_ctr_fld_b=0; 
  static int FirstCall = 1;   // used for FMO initialization 
  int luma_weight_flag_l0, luma_weight_flag_l1, chroma_weight_flag_l0, chroma_weight_flag_l1; 
  int tmp1; 
  RMPNIbuffer_t *tmp_rmpni,*tmp_rmpni2; 
  MMCObuffer_t *tmp_mmco,*tmp_mmco2; 
  int done; 
#ifdef USEPOC                    
  unsigned int i,AbsFrameNum, ExpectedPicOrderCnt, PicOrderCntCycleCnt, FrameNumInPicOrderCntCycle; 
  static unsigned int PreviousFrameNum, FrameNumOffset, ExpectedDeltaPerPicOrderCntCycle; 
  static unsigned int Previousfield_pic_flag,Previousbottom_field_flag,Previousnal_reference_idc; 
  static unsigned int Previousdelta_pic_order_cnt[2], PreviousPOC=11111, ThisPOC, FirstFieldType; 
#endif 
  int j; 
 
  sym.type = SE_HEADER; 
  sym.mapping = linfo; 
 
#ifndef USEPOC 
  // 1. TRType = 0 
  SYMTRACESTRING("SH TemporalReferenceType"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  // Currently, only the value 0 is supported, hence a simple assert to 
  // catch evenntual  encoder problems 
  if (sym.value1 != 0) 
  { 
    snprintf (errortext, ET_SIZE, "Unsupported value %d in Picture Header TemporalReferenceType, len %d info %d", sym.value1, sym.len, sym.inf); 
    error(errortext, 600); 
  } 
  UsedBits += sym.len; 
 
  // 2. TR, variable length 
  SYMTRACESTRING("SH TemporalReference"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  currSlice->picture_id = img->tr = sym.value1; 
  UsedBits += sym.len; 
 
#else  //USEPOC  defined                 
   
  //sequence parameter set stuff 
  sym.type = SE_HEADER;                 // This will be true for all symbols generated here 
  sym.mapping = linfo;               // Mapping rule: unsigned integer 
   
  SYMTRACESTRING("log2_max_frame_num_minus4"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  img->log2_max_frame_num_minus4 = sym.value1;    //ue(v) 
                img->MaxFrameNum = 1<<(img->log2_max_frame_num_minus4+4); 
   
  SYMTRACESTRING("pic_order_cnt_type"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  img->pic_order_cnt_type = sym.value1;     //ue(v)   
  if(img->pic_order_cnt_type != 1)error("pic_order_cnt_type != 1",-1000); 
   
   
                SYMTRACESTRING("num_ref_frames_in_pic_order_cnt_cycle"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
                img->num_ref_frames_in_pic_order_cnt_cycle = sym.value1;  //ue(v)   
                if(img->num_ref_frames_in_pic_order_cnt_cycle != 1) 
                                                error("num_ref_frames_in_pic_order_cnt_cycle != 1",-1001); 
                if(img->num_ref_frames_in_pic_order_cnt_cycle >= MAX_LENGTH_POC_CYCLE) 
                                                error("num_ref_frames_in_pic_order_cnt_cycle too large",-1011); 
   
   
  sym.len = 1; 
  SYMTRACESTRING("delta_pic_order_always_zero_flag");    
  readSyntaxElement_fixed (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  img->delta_pic_order_always_zero_flag = sym.inf;   //u(1)  
                if(img->delta_pic_order_always_zero_flag != 0)error("delta_pic_order_always_zero_flag != 0",-1002); 
   
  sym.mapping = linfo_dquant;               // change to signed integer 
   
                SYMTRACESTRING("offset_for_non_ref_pic"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
                img->offset_for_non_ref_pic = sym.value1;  //    se(v)    
   
   
  SYMTRACESTRING("offset_for_top_to_bottom_field"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  img->offset_for_top_to_bottom_field = sym.value1;   //se(v) 
   
                ExpectedDeltaPerPicOrderCntCycle=0; 
                if(img->num_ref_frames_in_pic_order_cnt_cycle) 
                for(i=0;inum_ref_frames_in_pic_order_cnt_cycle;i++){ 
                        SYMTRACESTRING("offset_for_ref_frame[i]"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
                        img->offset_for_ref_frame[i] = sym.value1;              //se(v) 
                        ExpectedDeltaPerPicOrderCntCycle += sym.value1; 
                } 
   
  // putting weighted prediction flags here  
  sym.len = 1; 
  SYMTRACESTRING("weighted_pred_flag"); 
  readSyntaxElement_fixed (&sym, img, inp, partition); 
  UsedBits += sym.len; 
  img->weighted_pred_flag = sym.inf;                     //u(1)  
   
  sym.len = 1; 
  SYMTRACESTRING("weighted_bipred_explicit_flag"); 
  readSyntaxElement_fixed (&sym, img, inp, partition); 
  UsedBits += sym.len; 
  img->weighted_bipred_explicit_flag = sym.inf;                     //u(1)  
   
  sym.len = 1; 
  SYMTRACESTRING("weighted_pred_implicit_flag"); 
  readSyntaxElement_fixed (&sym, img, inp, partition); 
  UsedBits += sym.len; 
  img->weighted_bipred_implicit_flag = sym.inf;                     //u(1)  
   
  //picture parameter  set stuff 
  sym.type = SE_HEADER;                 
  sym.len = 1; 
  SYMTRACESTRING("pic_order_present_flag"); 
  readSyntaxElement_fixed (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  sym.bitpattern = img->pic_order_present_flag = sym.inf;     //u(1) 
  if(img->pic_order_present_flag != 0) 
    error("pic_order_present_flag != 0",-1004); 
   
   
  //slice header stuff 
  sym.type = SE_HEADER;                 
  sym.mapping = linfo;              // change to unsigned integer 
   
  SYMTRACESTRING("frame_num"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  img->frame_num = sym.value1;            //ue(v)  
   
   
  //field_pic_flag  always sent here    u(1) 
  // frame_coding_only_flag not yet sent 
  sym.len = 1; 
  SYMTRACESTRING("field_pic_flag"); 
  readSyntaxElement_fixed (&sym,img,inp,partition); 
  img->field_pic_flag = sym.inf; 
   
  if(img->field_pic_flag){ 
    //bottom_field_flag  u(1) 
    sym.len = 1; 
    SYMTRACESTRING("bottom_field_flag"); 
    readSyntaxElement_fixed (&sym,img,inp,partition); 
    img->bottom_field_flag = sym.inf; 
  } 
  else img->bottom_field_flag = 0; 
   
   
  //to be done.... 
  //first_mb_in_slice  
  //slice_type_idc 
   
  sym.mapping = linfo_dquant;               // change to signed integer 
   
                if(!img->delta_pic_order_always_zero_flag){ 
  SYMTRACESTRING("delta_pic_order_cnt[0]"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  img->delta_pic_order_cnt[0] = sym.value1; //  se(v) 
                } 
                else img->delta_pic_order_cnt[0] = 0; 
                         
                if(img->pic_order_present_flag  && !img->delta_pic_order_always_zero_flag){ 
                                SYMTRACESTRING("delta_pic_order_cnt[1]"); 
                                readSyntaxElement_UVLC (&sym,img,inp,partition); 
                                UsedBits += sym.len; 
                                img->delta_pic_order_cnt[1] = sym.value1;       //  se(v) 
                } 
                else img->delta_pic_order_cnt[1] = 0; 
   
   
  sym.mapping = linfo;               // change to unsigned integer 
 
#endif 
 
  // 3. Size Type 
  SYMTRACESTRING ("SH WhichSize..."); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
  if (sym.value1 == 0) 
    SYMTRACESTRING("SH:    Size Information Unchanged"); 
  else 
  { 
    // width * 16 
    SYMTRACESTRING("SH FullSize-X"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    img->width = sym.value1 * MB_BLOCK_SIZE; 
    img->width_cr = img->width/2; 
    UsedBits+=sym.len; 
    SYMTRACESTRING("SH FullSize-Y"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    img->height = sym.value1 * MB_BLOCK_SIZE; 
    img->height_cr = img->height/2; 
    UsedBits+= sym.len; 
  } 
 
  // 4. Picture Type indication (I, P, Mult_P, B , Mult_B, SP, Mult_SP) 
  SYMTRACESTRING("SH SliceType"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  currSlice->picture_type = img->type = sym.value1; 
  UsedBits += sym.len; 
 
  // Picture Structure indication (0 for frame, 1 for top field and 2 for bottom field) 
  SYMTRACESTRING("SH PictureStructure"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  currSlice->structure = img->structure = sym.value1; 
  UsedBits += sym.len; 
 
  img->mb_frame_field_flag = 0; 
 
  if (img->structure == 3) 
    img->mb_frame_field_flag = 1; 
 
  if (img->structure == 3) 
    img->structure = 0;         // Frame coding with new scan for super MB pair 
 
  // 5. Finally, read Reference Picture ID (same as TR here).  Note that this is an 
  // optional field that is not present if the input parameters do not indicate 
  // multiframe prediction ?? 
 
  // Ok, the above comment is nonsense.  There is no way how a decoder could 
  // know that we use multiple reference frames (except probably through a 
  // sequence header).  Hence, it's now an if (1) -- PHRefPicID is always present 
 
  // Of course, the decoder can know. It is indicated by the previously decoded 
  // parameter "PHPictureType". So, I changed the if-statement again to be 
  // compatible with the encoder. 
 
  // WYK: Oct. 16, 2001. Now I use this for the reference frame ID (non-B frame ID).  
  // Thus, we can know how many  non-B frames are lost, and then we can adjust  
  // the reference frame buffers correctly. 
  if (1) 
  { 
    // refPicID, variable length 
    SYMTRACESTRING("SH RefPicID"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    if (img->refPicID != sym.value1) 
    { 
      img->refPicID_old = img->refPicID; 
      img->refPicID = sym.value1; 
    } 
    UsedBits += sym.len; 
  } 
 
  SYMTRACESTRING("disposable_flag"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  img->disposable_flag = sym.value1; 
  UsedBits += sym.len; 
 
#ifdef USEPOC           //5.0f 
  SYMTRACESTRING("idr_flag"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  img->idr_flag = sym.value1; 
  UsedBits += sym.len; 
#endif 
  img->num_ref_pic_active_fwd = 0; 
  img->num_ref_pic_active_bwd = 0; 
 
  if(img->type==INTER_IMG_1 || img->type==INTER_IMG_MULT || img->type == SP_IMG_1 || img->type == SP_IMG_MULT) 
  { 
    SYMTRACESTRING("num_ref_pic_active_fwd_minus1"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    img->num_ref_pic_active_fwd = sym.value1+1; 
    UsedBits += sym.len;     
  } 
  else if(img->type==B_IMG_1 || img->type==B_IMG_MULT) 
  { 
    SYMTRACESTRING("num_ref_pic_active_fwd_minus1"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    img->num_ref_pic_active_fwd = sym.value1+1; 
    UsedBits += sym.len; 
 
    SYMTRACESTRING("num_ref_pic_active_bwd_minus1"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    img->num_ref_pic_active_bwd = sym.value1+1; 
    UsedBits += sym.len; 
  } 
 
#ifndef USEPOC          //USEPOC moves some of this stuff below 
  if(!img->current_slice_nr) 
  {  
    if (img->type <= INTRA_IMG || img->type >= SP_IMG_1 || !img->disposable_flag)  
    { 
      if (img->structure == FRAME) 
      {      
        if(img->tr tr; 
        img->tr_frm = img->tr + (256*modulo_ctr_frm); 
      } 
      else 
      { 
        if(img->tr tr; 
        img->tr_fld = img->tr + (256*modulo_ctr_fld); 
      } 
    } 
    else 
    { 
      if (img->structure == FRAME) 
      {      
        if(img->tr tr; 
        img->tr_frm = img->tr + (256*modulo_ctr_frm_b); 
      } 
      else 
      { 
        if(img->tr tr; 
        img->tr_fld = img->tr + (256*modulo_ctr_fld_b); 
      } 
    } 
    if((img->type != B_IMG_MULT && img->type != B_IMG_1) || !img->disposable_flag)  
    { 
      img->pstruct_next_P = img->structure; 
      if(img->structure == TOP_FIELD) 
      { 
        img->imgtr_last_P = img->imgtr_next_P; 
        img->imgtr_next_P = img->tr_fld; 
      } 
      else if(img->structure == FRAME) 
      { 
        img->imgtr_last_P = img->imgtr_next_P; 
        img->imgtr_next_P = 2*img->tr_frm; 
      } 
    } 
  } 
#endif  // USEPOC  
 
  // 6. Get MB-Adresse 
  SYMTRACESTRING("SH FirstMBInSlice"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  currSlice->start_mb_nr = sym.value1; 
  UsedBits += sym.len; 
 
 
  if(img->type==B_IMG_1 || img->type==B_IMG_MULT) 
    { 
      SYMTRACESTRING("SH DirectSpatialFlag"); 
      sym.len = 1; 
      readSyntaxElement_fixed (&sym,img,inp,partition); 
      img->direct_type = sym.inf; 
    } 
 
#ifdef _ABT_FLAG_IN_SLICE_HEADER_ 
  SYMTRACESTRING("SH ABTMode"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  currSlice->abt = sym.value1; 
  UsedBits += sym.len; 
#endif 
 
  // 7. Get Quant. 
  SYMTRACESTRING("SH SliceQuant"); 
  sym.mapping = linfo_dquant; 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  currSlice->qp = img->qp = sym.value1 + (MAX_QP - MIN_QP + 1)/2; 
  UsedBits += sym.len; 
  if(img->type==SP_IMG_1 || img->type==SP_IMG_MULT || img->type == SI_IMG)  
  { 
    if(img->type==SP_IMG_1 || img->type==SP_IMG_MULT) 
    { 
      SYMTRACESTRING("SH SP SWITCH"); 
      sym.len = 1; 
      readSyntaxElement_fixed (&sym,img,inp,partition); 
      img->sp_switch = sym.inf;       
    } 
    if(img->type==SI_IMG) 
      SYMTRACESTRING("SH SI SliceQuant"); 
    else 
      SYMTRACESTRING("SH SP SliceQuant"); 
    readSyntaxElement_UVLC (&sym,img,inp,partition); 
    img->qpsp = sym.value1 + (MAX_QP - MIN_QP + 1)/2; 
  } 
 
  if (inp->LFParametersFlag) 
  { 
    SYMTRACESTRING("SH LF_DISABLE FLAG"); 
    sym.len = 1; 
    readSyntaxElement_fixed (&sym,img,inp,partition); 
    currSlice->LFDisable = sym.inf; 
 
    if (!currSlice->LFDisable) 
    { 
      sym.mapping = linfo_dquant;           // Mapping rule: Signed integer 
      SYMTRACESTRING("SH LFAlphaC0OffsetDiv2"); 
      readSyntaxElement_UVLC (&sym,img,inp,partition); 
      currSlice->LFAlphaC0Offset = sym.value1 << 1; 
      UsedBits += sym.len; 
 
      SYMTRACESTRING("SH LFBetaOffsetDiv2"); 
      readSyntaxElement_UVLC (&sym,img,inp,partition); 
      currSlice->LFBetaOffset = sym.value1 << 1; 
      UsedBits += sym.len; 
    } 
  } 
 
  // putting pred_weight_table() here 
 
 
  img->apply_weights = ((img->weighted_pred_flag && (currSlice->picture_type == INTER_IMG_1 || currSlice->picture_type == INTER_IMG_MULT || currSlice->picture_type == SP_IMG_1 || currSlice->picture_type == SP_IMG_MULT) ) 
          || ((img->weighted_bipred_explicit_flag  || img->weighted_bipred_implicit_flag ) && (currSlice->picture_type == B_IMG_1 || currSlice->picture_type == B_IMG_MULT ))); 
 
  if  ( (img->weighted_pred_flag && (img->type == INTER_IMG_1 || img->type == INTER_IMG_MULT || img->type == SP_IMG_1 || img->type == SP_IMG_MULT) ) 
         || ((img->weighted_bipred_explicit_flag) && (currSlice->picture_type == B_IMG_1 || currSlice->picture_type == B_IMG_MULT )))  
  { 
    sym.mapping = linfo_dquant;               // change to signed integer 
 
    SYMTRACESTRING("luma_log_weight_denom"); 
    readSyntaxElement_UVLC (&sym,img,inp, partition); 
    img->luma_log_weight_denom = sym.value1; 
    img->wp_round_luma = 1<<(img->luma_log_weight_denom - 1); 
    UsedBits += sym.len; 
   
    SYMTRACESTRING("chroma_log_weight_denom"); 
    readSyntaxElement_UVLC (&sym, img, inp, partition); 
    img->chroma_log_weight_denom = sym.value1; 
    img->wp_round_chroma = 1<<(img->chroma_log_weight_denom - 1); 
    UsedBits += sym.len; 
 
    reset_wp_params(img); 
    for (i=0; inum_ref_pic_active_fwd; i++) 
    { 
      sym.mapping = linfo;               // change to unsigned integer 
      sym.len = 1; 
      SYMTRACESTRING("luma_weight_flag_l0"); 
      readSyntaxElement_fixed (&sym, img, inp, partition); 
      UsedBits += sym.len; 
      luma_weight_flag_l0 = sym.inf; 
 
      if (luma_weight_flag_l0) 
      { 
        sym.mapping = linfo_dquant;               // change to signed integer 
        SYMTRACESTRING("luma_weight_l0"); 
        readSyntaxElement_UVLC (&sym, img, inp, partition); 
        UsedBits += sym.len; 
        img->wp_weight[0][i][0] = sym.value1; 
        SYMTRACESTRING("luma_offset_l0"); 
        readSyntaxElement_UVLC (&sym, img, inp, partition); 
        UsedBits += sym.len; 
        img->wp_offset[0][i][0] = sym.value1; 
      } 
      else 
      { 
        img->wp_weight[0][i][0] = 1<luma_log_weight_denom; 
        img->wp_offset[0][i][0] = 0; 
      } 
  
          for (j=1; j<3; j++) 
      { 
         sym.mapping = linfo;               // change to unsigned integer 
         sym.len = 1; 
         SYMTRACESTRING("chroma_weight_flag_l0"); 
         readSyntaxElement_fixed (&sym, img, inp, partition); 
         UsedBits += sym.len; 
         chroma_weight_flag_l0 = sym.inf; 
       
         if (chroma_weight_flag_l0) 
         { 
           sym.mapping = linfo_dquant;               // change to signed integer 
           SYMTRACESTRING("chroma_weight_l0"); 
           readSyntaxElement_UVLC (&sym, img, inp, partition); 
           UsedBits += sym.len; 
           img->wp_weight[0][i][j] = sym.value1; 
 
           SYMTRACESTRING("chroma_offset_l0"); 
           readSyntaxElement_UVLC (&sym, img, inp, partition); 
           UsedBits += sym.len; 
           img->wp_offset[0][i][j] = sym.value1; 
         } 
         else 
         { 
           img->wp_weight[0][i][j] = 1<luma_log_weight_denom; 
           img->wp_offset[0][i][j] = 0; 
         } 
          } 
    } 
  } 
  if ((img->type == B_IMG_1 || img->type == B_IMG_MULT) && img->weighted_bipred_explicit_flag == 1) 
  { 
    for (i=0; inum_ref_pic_active_bwd; i++) 
    { 
      sym.mapping = linfo;               // change to unsigned integer 
      sym.len = 1; 
      SYMTRACESTRING("luma_weight_flag_l1"); 
      readSyntaxElement_fixed (&sym, img, inp, partition); 
      UsedBits += sym.len; 
      luma_weight_flag_l1 = sym.inf; 
 
      if (luma_weight_flag_l1) 
      { 
        sym.mapping = linfo_dquant;               // change to signed integer 
        SYMTRACESTRING("luma_weight_l1"); 
        readSyntaxElement_UVLC (&sym, img, inp, partition); 
        UsedBits += sym.len; 
        img->wp_weight[1][i][0] = sym.value1; 
 
                SYMTRACESTRING("luma_offset_l1"); 
                readSyntaxElement_UVLC (&sym, img, inp, partition); 
                UsedBits += sym.len; 
                img->wp_offset[1][i][0] = sym.value1; 
          } 
          else 
          { 
                img->wp_weight[1][i][0] = 1<luma_log_weight_denom; 
                img->wp_offset[1][i][0] = 0; 
          } 
      
          for (j=1; j<3; j++) 
          { 
                         
                  sym.mapping = linfo;               // change to unsigned integer 
                  sym.len = 1; 
                  SYMTRACESTRING("chroma_weight_flag_l1"); 
                  readSyntaxElement_fixed (&sym, img, inp, partition); 
                  UsedBits += sym.len; 
                  chroma_weight_flag_l1 = sym.inf; 
                   
                  if (chroma_weight_flag_l1) 
                  { 
                                sym.mapping = linfo_dquant;               // change to signed integer 
                                SYMTRACESTRING("chroma_weight_l1"); 
                                readSyntaxElement_UVLC (&sym, img, inp, partition); 
                                UsedBits += sym.len; 
                                img->wp_weight[1][i][j] = sym.value1; 
 
                                SYMTRACESTRING("chroma_offset_l1"); 
                                readSyntaxElement_UVLC (&sym, img, inp, partition); 
                                UsedBits += sym.len; 
                                img->wp_offset[1][i][j] = sym.value1; 
                        } 
                        else 
                        { 
                                img->wp_weight[1][i][j] = 1<chroma_log_weight_denom; 
                                img->wp_offset[1][i][j] = 0; 
                        } 
                } 
                 
                } 
 
  } 
  sym.mapping = linfo; 
 
  /* KS: Multi-Picture Buffering Syntax */ 
 
  // Reference Picture Selection Flags  
  SYMTRACESTRING("SH Reference Picture Selection Flags"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
 
  // Picture Number  
  SYMTRACESTRING("SH Picture Number"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  img->pn=sym.value1; 
  UsedBits += sym.len; 
 
  // Reference picture selection layer  
  SYMTRACESTRING("SH Reference picture selection layer"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
   
  if (sym.value1) 
  { 
    // read Reference Picture Selection Layer  
    // free old buffer content 
    while (img->currentSlice->rmpni_buffer) 
    {  
      tmp_rmpni=img->currentSlice->rmpni_buffer; 
  
      img->currentSlice->rmpni_buffer=tmp_rmpni->Next; 
      free (tmp_rmpni); 
    }  
    done=0; 
    // if P or B frame RMPNI  
 
    if ((img->type==INTER_IMG_1)||(img->type==INTER_IMG_MULT)||(img->type==B_IMG_1)|| 
        (img->type==B_IMG_MULT)||(img->type==SP_IMG_1)||(img->type==SP_IMG_MULT)) 
    { 
      do 
      { 
     
        SYMTRACESTRING("SH RMPNI"); 
        readSyntaxElement_UVLC (&sym,img,inp,partition); 
        tmp1=sym.value1; 
        UsedBits += sym.len; 
 
 
        // check for illegal values 
        if ((tmp1<0)||(tmp1>3)) 
          error ("Invalid RMPNI operation specified",400); 
 
        if (tmp1!=3) 
        { 
          printf ("got RMPNI = %d\n",tmp1); 
          tmp_rmpni=(RMPNIbuffer_t*)calloc (1,sizeof (RMPNIbuffer_t)); 
          tmp_rmpni->Next=NULL; 
          tmp_rmpni->RMPNI=tmp1; 
 
          // get the additional parameter 
          SYMTRACESTRING("SH RMPNI Parameter"); 
          readSyntaxElement_UVLC (&sym,img,inp,partition); 
          tmp_rmpni->Data=sym.value1; 
          UsedBits += sym.len; 
 
          // add RMPNI to list 
          if (img->currentSlice->rmpni_buffer==NULL)  
          { 
            img->currentSlice->rmpni_buffer=tmp_rmpni; 
          } 
          else 
          { 
            tmp_rmpni2=img->currentSlice->rmpni_buffer; 
            while (tmp_rmpni2->Next!=NULL)  
              tmp_rmpni2=tmp_rmpni2->Next; 
            tmp_rmpni2->Next=tmp_rmpni; 
          } 
        } else 
        { 
          // free temporary memory (no need to save end loop operation) 
          done=1; 
        } 
      } while (!done); 
    } 
  } 
 
  // RBPT  
  SYMTRACESTRING("SH RBPT"); 
  readSyntaxElement_UVLC (&sym,img,inp,partition); 
  UsedBits += sym.len; 
 
  // free old buffer content 
  while (img->mmco_buffer) 
  {  
    tmp_mmco=img->mmco_buffer; 
 
    img->mmco_buffer=tmp_mmco->Next; 
    free (tmp_mmco); 
  }  
 
  if (sym.value1) 
  { 
    // read Memory Management Control Operation  
    do 
    { 
 
      tmp_mmco=(MMCObuffer_t*)calloc (1,sizeof (MMCObuffer_t)); 
      tmp_mmco->Next=NULL; 
     
      SYMTRACESTRING("SH MMCO"); 
      readSyntaxElement_UVLC (&sym,img,inp,partition); 
      tmp_mmco->MMCO=sym.value1; 
      UsedBits += sym.len; 
 
      switch (tmp_mmco->MMCO) 
      { 
      case 0: 
      case 5: 
        break; 
      case 1: 
        SYMTRACESTRING("SH DPN"); 
        readSyntaxElement_UVLC (&sym,img,inp,partition); 
        tmp_mmco->DPN=sym.value1; 
        UsedBits += sym.len; 
        break; 
      case 2: 
        SYMTRACESTRING("SH LPIN"); 
        readSyntaxElement_UVLC (&sym,img,inp,partition); 
        tmp_mmco->LPIN=sym.value1; 
        UsedBits += sym.len; 
        break; 
      case 3: 
        SYMTRACESTRING("SH DPN"); 
        readSyntaxElement_UVLC (&sym,img,inp,partition); 
        tmp_mmco->DPN=sym.value1; 
        UsedBits += sym.len; 
        SYMTRACESTRING("SH LPIN"); 
        readSyntaxElement_UVLC (&sym,img,inp,partition); 
        tmp_mmco->LPIN=sym.value1; 
        UsedBits += sym.len; 
        break; 
      case 4: 
        SYMTRACESTRING("SH MLIP1"); 
        readSyntaxElement_UVLC (&sym,img,inp,partition); 
        tmp_mmco->MLIP1=sym.value1; 
        UsedBits += sym.len; 
        break; 
      default: 
        error ("Invalid MMCO operation specified",400); 
        break; 
      } 
 
      // add MMCO to list 
      if (img->mmco_buffer==NULL)  
      { 
        img->mmco_buffer=tmp_mmco; 
      } 
      else 
      { 
        tmp_mmco2=img->mmco_buffer; 
        while (tmp_mmco2->Next!=NULL) tmp_mmco2=tmp_mmco2->Next; 
        tmp_mmco2->Next=tmp_mmco; 
      } 
       
    }while (tmp_mmco->MMCO!=0); 
  } 
 
  /* end KS */ 
  img->buf_cycle = inp->buf_cycle+1; 
  img->pn=(((img->structure==BOTTOM_FIELD) ? (img->number/2):img->number)%img->buf_cycle); 
 
  img->max_mb_nr = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE); 
 
 
  //! Note! This software reqiures a valid MBAmap in any case.  When FMO is not 
  //! used, the MBAmap consists of all zeros, yielding scan order slices.  
  //!  
  //! We cannot initialize the FMO module with the default (scan order MBAmap) 
  //! before we know the picture size.  Hence, the FMO Module is initialized here, 
  //! unless we have RTP file format.  The RTP NAL is currently the only one which 
  //! implements the ParameterSets.  There, we can initialize the FMO module as 
  //! soon as we got the Parameter Set packet. 
   
  if (inp->of_mode != PAR_OF_RTP && FirstCall) 
  { 
    if (currSlice->structure) 
    { 
      // if first call is field: init with double height 
      FmoInit (img, inp, img->width/16, img->height/8, NULL, 0);   // force a default MBAmap 
    } 
    else 
    { 
      FmoInit (img, inp, img->width/16, img->height/16, NULL, 0);   // force a default MBAmap 
    } 
    FirstCall = 0; 
  } 
 
#ifdef USEPOC                    
  //calculate pocs 
  if(img->idr_flag){ 
          FrameNumOffset=0;     //  first pix of IDRGOP,  
          FirstFieldType = img->bottom_field_flag;              //save type of first field of frame 
                                                                                                        //NB may not work with mixed field & frame coding 
          img->delta_pic_order_cnt[0]=0;                        //ignore first delta 
          if(img->frame_num)error("frame_num != 0 in idr pix", -1020); 
  } 
  else if(img->frame_numMaxFrameNum; 
  } 
 
  if(img->num_ref_frames_in_pic_order_cnt_cycle) AbsFrameNum = FrameNumOffset+img->frame_num; 
  else AbsFrameNum=0; 
 
  if(img->disposable_flag && AbsFrameNum)AbsFrameNum--; 
 
  if(AbsFrameNum){ 
          PicOrderCntCycleCnt = (AbsFrameNum-1)/img->num_ref_frames_in_pic_order_cnt_cycle; 
          FrameNumInPicOrderCntCycle = (AbsFrameNum-1)%img->num_ref_frames_in_pic_order_cnt_cycle; 
          ExpectedPicOrderCnt = PicOrderCntCycleCnt*ExpectedDeltaPerPicOrderCntCycle; 
          for(i=0;i<=FrameNumInPicOrderCntCycle;i++)ExpectedPicOrderCnt += img->offset_for_ref_frame[i]; 
  } 
  else ExpectedPicOrderCnt=0; 
 
  if(img->disposable_flag)ExpectedPicOrderCnt += img->offset_for_non_ref_pic; 
 
 
  if(img->field_pic_flag==0){           //frame pix 
                ThisPOC = img->toppoc = ExpectedPicOrderCnt + img->delta_pic_order_cnt[0]; 
                img->bottompoc = img->toppoc + img->offset_for_top_to_bottom_field + img->delta_pic_order_cnt[1]; 
                if(PreviousPOC!=ThisPOC){               //new frame detected 
                        if(img->disposable_flag)push_poc(img->toppoc,img->bottompoc,NONREFFRAME); 
                        else                                    push_poc(img->toppoc,img->bottompoc,REFFRAME); 
                } 
  } 
  else if (img->bottom_field_flag==0){  //top field  
                ThisPOC = img->toppoc = ExpectedPicOrderCnt + img->delta_pic_order_cnt[0]; 
                if(PreviousPOC!=ThisPOC  &&  FirstFieldType==img->bottom_field_flag){           //new frame detected 
                        if(img->disposable_flag)push_poc(img->toppoc,0,NONREFFRAME); 
                        else                                    push_poc(img->toppoc,0,REFFRAME); 
                } 
                else toprefpoc[0] = img->toppoc;                //2nd field of same frame 
 
  }  
  else{                                                   //bottom field 
                ThisPOC = img->bottompoc = ExpectedPicOrderCnt + img->offset_for_top_to_bottom_field + img->delta_pic_order_cnt[0]; 
                if(PreviousPOC!=ThisPOC  &&  FirstFieldType==img->bottom_field_flag){           //new frame detected 
                        if(img->disposable_flag)push_poc(0,img->bottompoc,NONREFFRAME); 
                        else                                    push_poc(0,img->bottompoc,REFFRAME); 
                } 
                else bottomrefpoc[0] = img->bottompoc;          //2nd field of same frame 
  } 
 
                                                                //temp stuff to track tr 
    if(img->field_pic_flag){ 
                img->tr_fld = ThisPOC; 
                if(img->bottom_field_flag){ 
                        currSlice->picture_id = img->tr = img->bottompoc%256; 
                } 
                else{   //top field 
                        currSlice->picture_id = img->tr = img->toppoc%256; 
                } 
        } 
        else{           //frame pix  -  use toppoc/2 
                img->tr_frm = ThisPOC/2; 
                currSlice->picture_id = img->tr = (img->toppoc/2)%256; 
        } 
 
         
                                 
                                                 
         
 
                                                                                //update "Previous" stuff for next slice 
         PreviousFrameNum=img->frame_num; 
         Previousfield_pic_flag=img->field_pic_flag; 
         Previousbottom_field_flag=img->bottom_field_flag; 
         Previousnal_reference_idc=img->idr_flag;                
         Previousdelta_pic_order_cnt[0]=img->delta_pic_order_cnt[0]; 
         Previousdelta_pic_order_cnt[1]=img->delta_pic_order_cnt[1]; 
         PreviousPOC=ThisPOC; 
 
                                                                                        //moved from above for stuff that still uses img->tr 
                                                                                        //soon to be obsolete 
        if(!img->current_slice_nr){  
    if((img->type != B_IMG_MULT && img->type != B_IMG_1) || !img->disposable_flag) { 
                 img->pstruct_next_P = img->structure; 
                 if(img->structure == TOP_FIELD){ 
                        img->imgtr_last_P = img->imgtr_next_P; 
                        img->imgtr_next_P = img->tr_fld; 
                 } 
                 else if(img->structure == FRAME){ 
                        img->imgtr_last_P = img->imgtr_next_P; 
                        img->imgtr_next_P = 2*img->tr_frm; 
                } 
    } 
     
  } 
#endif 
  //note  UsedBits is probably inaccurate 
 
  return UsedBits; 
}