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

📄 encodeiff.c

📁 比较老的264解码器baseline实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  currPictureInfo.pictureOffset = currPictureInfo.currPictureSize;
  currPictureInfo.currPictureSize = 0;  // reset

  // to set the picture display time (relative to the previous coded frame)
  currPictureInfo.pictureDisplayTime = frame_no - prev_frame_no;
  prev_frame_no = frame_no;

  if ( img->type != B_SLICE )
    currPictureInfo.lastFrameNr = frame_no;

  currPictureInfo.numPayloads = 0;  // numPayloads must be set to zero here
  currPictureInfo.payloadData = NULL;

  // the follow values may be updated.
  currPictureInfo.layerNumber = 0;
  currPictureInfo.subSequenceIdentifier = 0;
  currPictureInfo.originLayerNumber = 0;
  currPictureInfo.originSubSequenceIdentifier = 0;

  if ( input->NumFramesInELSubSeq != 0 )
  {
    if (IMG_NUMBER%(input->NumFramesInELSubSeq+1)==0 && img->type!=B_SLICE)
      currPictureInfo.layerNumber = 0;
    else
    {
      currPictureInfo.layerNumber = 1;
    }
    currPictureInfo.subSequenceIdentifier = box_sseq[currPictureInfo.layerNumber].subSequenceIdentifier;
    if (img->type!=B_SLICE)
    {
      currPictureInfo.refFromLayerNumber = currPictureInfo.layerNumber;
      currPictureInfo.refFromSubSequenceIdentifier = currPictureInfo.subSequenceIdentifier;
    }
  }

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write the meta data of the current picture
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrPictureInfo( FILE* fp )
{
  int i;
  INT64 size;
  PayloadInfo* pp;
  unsigned char cd;
  size_t num = 0;

  assert( fp != NULL );

  if ( currPictureInfo.intraPictureFlag == TRUE ) cd = 0x80;
  else cd = 0x00;
  if ( currPictureInfo.syncPictureFlag == TRUE ) cd |= 0x40;
  num += writefile( &cd, 1, 1, fp );

  num += writefile_s( &currPictureInfo.pictureOffset, sizeof(currPictureInfo.pictureOffset), box_fh.numBytesInPictureOffsetMinusTwo + 2, 1, fp );
  num += writefile_s( &currPictureInfo.pictureDisplayTime, sizeof(currPictureInfo.pictureDisplayTime), box_fh.numBytesInPictureDisplayTimeMinusOne + 1, 1, fp );

  if ( box_ath.numLayers )
  {
    if ( -1 == writefile( &currPictureInfo.layerNumber, 1, 1, fp ) ) return -1;
    if ( -1 == writefile( &currPictureInfo.subSequenceIdentifier, 2, 1, fp ) ) return -1;
    if ( currPictureInfo.syncPictureFlag )
    {
      if ( -1 == writefile( &currPictureInfo.originLayerNumber, 1, 1, fp ) ) return -1;
      if ( -1 == writefile( &currPictureInfo.originSubSequenceIdentifier, 2, 1, fp ) ) return -1;
    }
  }

  num += writefile_s( &currPictureInfo.numPayloads, sizeof(currPictureInfo.numPayloads), box_fh.numBytesInPayloadCountMinusOne + 1, 1, fp );

  // check if the operations to write file are successful.
  if ( num != (unsigned)(1+box_fh.numBytesInPictureOffsetMinusTwo + 2+box_fh.numBytesInPictureDisplayTimeMinusOne + 1+box_fh.numBytesInPayloadCountMinusOne + 1) ) return -1;

  pp = currPictureInfo.payloadData;
  for ( i = 0; i < currPictureInfo.numPayloads; i++ )
  { 
    assert( pp != NULL );

    // update and write the payload to file
    if ( -1 == wrPayloadInfo( pp, fp ) ) return -1;

    // then update the parameter in Alternate Track Info Box
    size = pp->payloadSize + pp->headerSize;
    box_ati.info[0].numSDU++;
    box_ati.info[0].sumSDUSize += (long double)size;
    if ( box_ati.info[0].maxSDUSize < size ) box_ati.info[0].maxSDUSize = (unsigned INT16)size;

    pp = pp->next;
  }

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this Picture Info
 * \return
 *      None
 ************************************************************************
 */
void freePictureInfo()
{
  int i;
  PayloadInfo* next;

  for ( i = 0; i < currPictureInfo.numPayloads; i++ )
  {
    assert( currPictureInfo.payloadData != NULL );
    next = currPictureInfo.payloadData->next;
    free( currPictureInfo.payloadData );
    currPictureInfo.payloadData = next;
  }
}

// Functions on payloadInfo

/*!
 ************************************************************************
 * \brief
 *      To new a payload info to save the meta data of a slice
 *      Tian Dong, Feb 10, 2002:
 *      No data partition supported.
 * \return
 *      a pointer to the allocated mem, if success
 *      NULL, if failed
 ************************************************************************
 */
PayloadInfo* newPayloadInfo()
{
  PayloadInfo* pli;

  pli = calloc(1, sizeof(PayloadInfo));
  if ( pli == NULL ) return NULL;

  pli->payloadSize = 0;
  pli->headerSize = box_fh.numBytesInPayloadSizeMinusOne+1 + 1 + 1;
  pli->payloadType = 0;  // single slice
  pli->errorIndication = 0;  // no known error
  pli->reserved = 0;
  pli->parameterSet = 0;
  pli->pictureID = 0;
  pli->sliceID = 0;
  pli->sliceType = 0;
  pli->firstMBInSliceX = 0;
  pli->firstMBInSliceY = 0;
  pli->directType=input->direct_type;
  pli->spSwitchFlag = 0;     // Flag for SP picture. 1 for switching SP, 0 for normal SP
  pli->next = NULL;
  pli->pn = img->pn;
  pli->type = img->type;
  pli->max_lindex = img->max_lindex;
  pli->lindex = img->lindex;
//  pli->disposable_flag               = img->disposable_flag;
  pli->weighted_prediction         = input->WeightedPrediction;
  pli->weighted_biprediction         = input->WeightedBiprediction;
  pli->num_ref_pic_active_fwd_minus1 = img->num_ref_pic_active_fwd_minus1;
  pli->num_ref_pic_active_bwd_minus1 = img->num_ref_pic_active_bwd_minus1;

  // set values
  assert ( input->partition_mode == PAR_DP_1 );

  // Tian Dong: JVT-C083. June 15, 2002
  // Calculating payload type, the conditions may be updated when more
  // coding options are supported later.
  if ( FirstFrameIn2ndIGOP == img->number )
    pli->payloadType = PAYLOAD_TYPE_IDERP;

  pli->parameterSet = box_ps.parameterSetID;
  pli->pictureID = img->currentSlice->picture_id;
  pli->sliceID = img->current_slice_nr;
  pli->pstruct = img->pstruct;

  // copied from rtp.c, and add pli->sliceType2
  switch (img->type)
  {
    case P_SLICE:
      if (img->types==SP_SLICE)
      {
        pli->sliceType = 2;
        pli->sliceType2 = SP_SLICE;
      }
      else
      {
        pli->sliceType = 0;
        pli->sliceType2 = P_SLICE;
      }
      break;
    case I_SLICE:
      pli->sliceType = 3;
      pli->sliceType2 = I_SLICE;
      break;
    case B_SLICE:
    case BS_IMG:
      pli->sliceType = 1;
      pli->sliceType2 = B_SLICE;
      break;
    case SP_SLICE:
      pli->sliceType = 2;
      pli->sliceType2 = SP_SLICE;
      break;
    default:
      printf ("Panic: unknown picture type %d, exit\n", img->type);
      assert (0==1);
  }

  pli->firstMBInSliceX = img->mb_x;
  pli->firstMBInSliceY = img->mb_y;
  pli->initialQP = img->qp;
  pli->qpsp = img->qpsp;

  pli->filter_parameters_flag = input->LFSendParameters;
  pli->lf_disable = input->LFDisableIdc;
  pli->lf_alpha_c0_offset_div2 = input->LFAlphaC0Offset >> 1;
  pli->lf_beta_offset_div2 = input->LFBetaOffset >> 1;

  // Tian: begin of ERPS
  pli->numRMPNI = 0;
  if ( img->type != I_SLICE )
  {
    // do the possible remapping 
    remap_ref_short_term(pli);
  }

  // begin of ERPS
#ifdef _CHECK_MULTI_BUFFER_1_

  // Tian Dong: It is suggested to delete the lines 
  // for test purpose. June 7, 2002
  printf("_CHECK_MULTI_BUFFER_1_ cannot be defined!\n");
  exit(0);

  /* RPSL: Reference Picture Selection Layer */
  if(img->type!=I_SLICE)
  {
    // let's mix some reference frames
    if ((img->pn==5)&&(img->type==P_SLICE))
    {
      RMPNIbuffer_t *r;
      r = (RMPNIbuffer_t*)calloc (1,sizeof(RMPNIbuffer_t));
      r->RMPNI=0;
      r->Data=2;
      r->Next=NULL;
      img->currentSlice->rmpni_buffer=r;
    }
  }
  reorder_mref(img);
  
#endif

#ifdef _CHECK_MULTI_BUFFER_2_

  // Tian Dong: It is suggested to delete such check coding lines
  // for test purpose. June 7, 2002
  assert(0);

  // some code to check operation
  if ((img->pn==3) && (img->type==P_SLICE))
  {
    // check in this frame as long term picture
//    if (img->max_lindex==0)
    {
      // set long term buffer size = 2
      img->max_lindex=2;
    }

    // assign local long term
    init_long_term_buffer(2,img);
    init_mref();
    init_Refbuf(img);

    if (img->current_slice_nr==0)
    {
      assign_long_term_id(3,img->lindex,img);
      img->lindex=(img->lindex+1)%img->max_lindex;
    }
  }

#endif 
  // end of ERPS

  return pli;
}

/*!
 ************************************************************************
 * \brief
 *      Add a payload info to the Payloadinfo List, which head is stored in PictureInfo
 *      Tian Dong, Feb 10, 2002:
 *      No data partition supported.
 * \return
 *      1, if success
 *      0, if failed
 * \param pi
 *      The PayloadInfo will be added to the list
 ************************************************************************
 */
int addOnePayloadInfo(PayloadInfo* pi)
{
  PayloadInfo* p;
  PayloadInfo* last;

  last = p = currPictureInfo.payloadData;

  assert( pi != NULL );

  while ( p )
  {
    last = p;
    p = p->next;
  }

  if (last == NULL)
    currPictureInfo.payloadData = pi;  // this is the first payloadInfo
  else
    last->next = pi;  // add the payloadInfo to the end of the payloadInfo list

  currPictureInfo.numPayloads++;
  
  return 1;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write one payloadinfo to file
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param pp
 *      PayloadInfo pointer
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrPayloadInfo( PayloadInfo* pp, FILE *fp )
{
  byte cd; 
  Bitstream* bitstream; // used as a MEM buffer of slice header
  SyntaxElement sym;
  size_t num = 0, bytes_written;
  int start_mb_nr;

  assert( pp != NULL );
  assert( fp != NULL );

  // Initialize the bitsteam:
  bitstream = alloca(sizeof(Bitstream));
  assert( bitstream != NULL );
  bitstream->streamBuffer = alloca(BUFSIZE_FOR_PAYLOADINFO);
  memset( bitstream->streamBuffer, 0, BUFSIZE_FOR_PAYLOADINFO);
  
  bitstream->bits_to_go  = 8;
  bitstream->byte_pos    = 0;
  bitstream->byte_buf    = 0;
  
  // First write the element to the MEM bitstream buffer
  sym.type = SE_HEADER;       // This will be true for all symbols generated here
  sym.mapping = ue_linfo;       // Mapping rule: Simple code number to len/info
  if ( pp->payloadType == 0 || pp->payloadType == PAYLOAD_TYPE_IDERP )
  {
    // write the parameter set
    sym.value1 = pp->parameterSet;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write picture structure
    sym.value1 = pp->pstruct;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write slice header;
    sym.value1 = pp->pictureID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->sliceType;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->disposable_flag;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    if ( pp->sliceType2==P_SLICE )
    {
      sym.value1 = pp->weighted_prediction;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    }
    if ( pp->sliceType2==B_SLICE )
    {
          // weighted_bipred_explicit_flag
          sym.value1 = (pp->weighted_biprediction == 1) ? 1:0;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);

          // weighted_bipred_implicit_flag
          sym.value1 = (pp->weighted_biprediction == 2) ? 1:0;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    }
    if ( pp->sliceType2==P_SLICE || pp->sliceType2==B_SLICE )
    {
      sym.value1 = pp->num_ref_pic_active_fwd_minus1;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    }
    if ( pp->sliceType2==B_SLICE )
    {
      sym.value1 = pp->num_ref_pic_active_bwd_minus1;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    }
    sym.value1 = pp->firstMBInSliceX;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->firstMBInSliceY;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    start_mb_nr = (img->width/16)*pp->firstMBInSliceY+pp->firstMBInSliceX;

    if (pp->sliceType2==B_SLICE)
    {
      sym.bitpattern = pp->directType;
      sym.len = 1;
      writeSyntaxElement2Buf_Fixed(&sym, bitstream);
    }


    sym.mapping = se_linfo;
    sym.value1 = pp->initialQP - (MAX_QP - MIN_QP +1)/2;
    writeSyntaxElement2Buf_UVLC (&sym, bitstream);
    
    if ( pp->sliceType2 == SP_SLICE) 
    {
      if ( pp->sliceType2 == SP_SLICE) // Needs some definition for SI Images. Currently code seems not to support them,
      {
        sym.bitpattern = pp->spSwitchFlag;
        sym.len = 1;
        writeSyntaxElement2Buf_Fixed(&sym, bitstream);
      }
      sym.value1 = pp->qpsp - (MAX_QP - MIN_QP +1)/2;
      writeSyntaxElement2Buf_UVLC (&sym, bitstream);

⌨️ 快捷键说明

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