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

📄 encodeiff.c

📁 比较老的264解码器baseline实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    }

    if (pp->filter_parameters_flag)
    {
        sym.bitpattern = pp->lf_disable;
        sym.len = 1;
        writeSyntaxElement2Buf_Fixed(&sym, bitstream);
        
        if (!pp->lf_disable)
        {
          sym.mapping = se_linfo;
          sym.value1 = pp->lf_alpha_c0_offset_div2;
          writeSyntaxElement2Buf_UVLC (&sym, bitstream);

          sym.value1 = pp->lf_beta_offset_div2;
          writeSyntaxElement2Buf_UVLC (&sym, bitstream);
        }
    }

    sym.mapping = ue_linfo;
    iff_writeERPS(&sym, pp, bitstream); // Tian: to support ERPS (Annex U), Feb 27, 2002

    // Tian Dong: June 10, 2002
    // Update: a differential value is conveyed rather than an absolute value. 
  }
  else if ( pp->payloadType == 1 )
  {
    // 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 )
    {
      sym.value1 = pp->weighted_biprediction;
      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);
    sym.mapping = se_linfo;
    sym.value1 = pp->initialQP - (MAX_QP - MIN_QP + 1)/2;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.mapping = ue_linfo;
    // write the slice id
    sym.value1 = pp->sliceID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);

    iff_writeERPS(&sym, pp, bitstream);       // Tian: to support ERPS (Annex U), Feb 27, 2002
  }
  else if ( pp->payloadType == 2 || pp->payloadType == 3 )
  {
    // write picture structure
    sym.value1 = pp->pstruct;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write pictureID
    sym.value1 = pp->pictureID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write sliceID
    sym.value1 = pp->sliceID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);

    iff_writeERPS(&sym, pp, bitstream);       // Tian: to support ERPS (Annex U), Feb 27, 2002
  }
  else if ( pp->payloadType == 5 )
  {
    // no additional codewords
  }

  // finishing the MEM buffer
  if (bitstream->bits_to_go < 8)
  { // trailing bits to process
    bitstream->byte_buf <<= bitstream->bits_to_go;
    bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
    bitstream->bits_to_go = 8;
  }

  bytes_written = bitstream->byte_pos;

  // update & write headerSize
  num += writefile_s( &pp->payloadSize, sizeof(pp->payloadSize), box_fh.numBytesInPayloadSizeMinusOne+1, 1, fp );
  pp->headerSize += bytes_written;
  num += writefile( &pp->headerSize, 1, 1, fp );
  cd = (pp->payloadType << 4) | (pp->errorIndication << 3) | (pp->reserved);
  num += writefile( &cd, 1, 1, fp );
  if ( num != (unsigned)(box_fh.numBytesInPayloadSizeMinusOne+1+2) ) return -1;

  // Then write the bitstream to FILE
  if ( bytes_written != fwrite (bitstream->streamBuffer, 1, bytes_written, fp) ) return -1;
  return num+bytes_written;
}

/*!
 ************************************************************************
 * \brief
 *      writes the ERPS syntax elements to a bitstream
 *      imitate write_ERPS(), and change the function calls:
 *    from:
 *      len += writeSyntaxElement_UVLC (sym, partition);
 *    to:
 *      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param bitstream
 *      destination: where the code to be written
 ************************************************************************
 */
size_t iff_writeERPS(SyntaxElement *sym, PayloadInfo* pp, Bitstream* bitstream)
{
  size_t len=0;
  int i; 

  // RPSF: Reference Picture Selection Flags
  sym->value1 = 0;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  // PN: Picture Number
  sym->value1 = pp->pn;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  if (pp->numRMPNI)
  {
    sym->value1 = 1;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

    // now write the data:
    for (i=0; i<pp->numRMPNI; i++)
    {
      assert( pp->rmpni_RMPNI[i] >= 0 && pp->rmpni_RMPNI[i] <= 3 );
      sym->value1 = pp->rmpni_RMPNI[i];
//      printf("write RMPNI %d\n", pp->rmpni_RMPNI[i]);
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
      if ( pp->rmpni_RMPNI[i] != 3 )
      {
        sym->value1 = pp->rmpni_Data[i];
        len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
      }
    }
  }
  else
  {
    sym->value1 = 0;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
  }

#ifdef _CHECK_MULTI_BUFFER_1_

  // RPSL: Reference Picture Selection Layer
  sym->value1 = 1;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  if(pp->type!=I_SLICE)
  {
    // let's mix some reference frames
    if ((pp->pn==5)&&(pp->type==P_SLICE))
    {
      // negative ADPN follows
      // RMPNI
      sym->value1 = 0;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
      // ADPN
      sym->value1 = 2;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    }
    // RMPNI
    sym->value1 = 3;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
  }
  
#else
  // RPSL: Reference Picture Selection Layer
//  sym->value1 = 0;
//  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

#endif

#ifdef _CHECK_MULTI_BUFFER_2_

  // Reference Picture Bufering Type
  sym->value1 = 1;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  // some code to check operation
  if ((pp->pn==3) && (pp->type==P_SLICE))
  {
    // set long term buffer size = 2
    // MMCO Specify Max Long Term Index
    // command
    sym->value1 = 4;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    // size = 2+1 (MLP1)
    sym->value1 = 2+1;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

    // assign a long term index to actual frame
    // MMCO Assign Long Term Index to a Picture
    // command
    sym->value1 = 3;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    // DPN=0 for actual frame 
    sym->value1 = 0;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    //long term ID
    sym->value1 = pp->lindex;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
  } 
  if ((pp->pn==4) && (pp->type==P_SLICE))
  {
     if (pp->max_lindex>0)
     {
      // delete long term picture again
      // MMCO Mark a Long-Term Picture as Unused
      // command
      sym->value1 = 2;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
      // MMCO LPIN
      // command
      sym->value1 = (pp->max_lindex+pp->lindex-1)%pp->max_lindex;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    }
  } 

  // end MMCO loop
  // end loop
  sym->value1 = 0;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#else
    // RPBT: Reference Picture Bufering Type
    sym->value1 = 0;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#endif 

  return len;
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the Layer Box
 *      Tian Dong, May 30, 2002:
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initLayerBox()
{
  int i;
  if ( input->NumFramesInELSubSeq == 0 ) return 0;
  if ( box_ath.numLayers > MAX_LAYER_NUMBER ) return -1;
  for (i=0; i<box_ath.numLayers; i++)
  {
    box_layr[i].type.size = 0;  // to be updated
    box_layr[i].type.type = BOX_LAYR;
    box_layr[i].avgBitRate = 0;
    box_layr[i].avgFrameRate = 0;

    box_layr[i].fp = tmpfile();
    if ( box_layr[i].fp == NULL ) return -1;
  }
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Update the average bit rate and frame rate in this Layer
 * \return
 *      0, if success
 *      -1, if failed
 ************************************************************************
 */
int updateLayerBox()
{
  int i;
  int pictureDataSize;

  if ( input->NumFramesInELSubSeq == 0 ) return 0;
  for (i=0; i<box_ath.numLayers; i++)
  {
    assert( box_layr[i].fp != NULL );
    // update the head data
    fseek( box_layr[i].fp, 0, SEEK_END );
    pictureDataSize = ftell( box_layr[i].fp );
    box_layr[i].type.size = SIZEOF_BOXTYPE + 8 + pictureDataSize;

    // replace the following two lines to calculate the average values
    box_layr[i].avgBitRate = 0;
    box_layr[i].avgFrameRate = 0;
  }
  return 0;
}

size_t mergeLayerBox( FILE* fp )
{
  size_t num = 0, num2 = 0;
  int layr;
  FILE* sourcef, *destf;
  unsigned char c;

  if ( input->NumFramesInELSubSeq == 0 ) return 0;
  for (layr=0; layr<box_ath.numLayers; layr++)
  {
    num = 0;
    num += writefile( &box_layr[layr].type.size, 4, 1, fp );
    num += writefile( &box_layr[layr].type.type, 4, 1, fp );

    num += writefile( &box_layr[layr].avgBitRate, 4, 1, fp );
    num += writefile( &box_layr[layr].avgFrameRate, 4, 1, fp );

    // append the data in box_layr[layr].fp into fp:
    sourcef = box_layr[layr].fp;
    destf = fp;

    fseek( sourcef, 0L, SEEK_SET );
  
    c = fgetc(sourcef);
    while ( !feof( sourcef ) )
    {
      fputc( c, destf );
      num++;
      c = fgetc(sourcef);
    }

    if ( num != box_layr[layr].type.size ) return -1;
    num2 += num;
  }
  return num2;
}

void freeLayerBox()
{
  int layr;
  if ( input->NumFramesInELSubSeq == 0 ) return;
  for (layr=0; layr<box_ath.numLayers; layr++)
  {
    fclose( box_layr[layr].fp );
  }
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the Sub Sequence Box
 *      Tian Dong, May 30, 2002:
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initSubSequenceBox(int layr)
{
  static unsigned INT16 id=0;

  if ( input->NumFramesInELSubSeq == 0 ) return 0;
  if (layr<0 || layr>box_ath.numLayers) return -1;

  box_sseq[layr].type.size = 0;  // to be updated
  box_sseq[layr].type.type = BOX_SSEQ;

  // set the data in current sub-sequence here...
  box_sseq[layr].subSequenceIdentifier = id++;
  box_sseq[layr].continuationFromPreviousSegmentFlag = FALSE;
  box_sseq[layr].continuationToNextSegmentFlag = FALSE;
  box_sseq[layr].startTickAvailableFlag = 0;
  box_sseq[layr].ssStartTick = 0;
  box_sseq[layr].ssDuration = 0;
  box_sseq[layr].avgBitRate = 0;
  box_sseq[layr].avgFrameRate = 0;
  box_sseq[layr].numReferenceSubSequences = 0; // to be updated. 

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Update the Sub Sequence Box
 *      Tian Dong, May 30, 2002:
 * \return
 *      number of bytes being written
 *      -1, if failed
 ************************************************************************
 */
int updateSubSequenceBox( int layr )
{
  if ( input->NumFramesInELSubSeq == 0 ) return 0;
  assert( layr >= 0 && layr < box_ath.numLayers );

  box_sseq[layr].type.size = SIZEOF_BOXTYPE + 30 + 3*box_sseq[layr].numReferenceSubSequences;
  box_sseq[layr].ssDuration = 0;
  box_sseq[layr].avgBitRate = 0;
  box_sseq[layr].avgFrameRate = 0;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Write the Sub Sequence Box
 *      Tian Dong, May 30, 2002:
 * \input
 *      layr: the layor number
 *      fp: the destination file, normally it is box_layr[layr].fp
 * \return
 *      number of bytes being written
 *      -1, if failed
 ************************************************************************
 */
size_t wrSubSequenceBox( int layr )
{
  size_t num = 0, num2;

⌨️ 快捷键说明

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