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

📄 rtp.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:

  /* Reference Picture Selection Flags */
  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &temp, &dummy);
  bitptr+=len;

  /* Picture Number */
  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &sh->PictureNum, &dummy);
  bitptr+=len;

  /* Reference picture selection layer */
  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &temp, &dummy);
  bitptr+=len;

  if (temp)
  {
    /* read Reference Picture Selection Layer */
    // free old buffer content
    while (sh->RMPNIbuffer)
    { 
      tmp_rmpni=sh->RMPNIbuffer;
 
      sh->RMPNIbuffer=tmp_rmpni->Next;
      free (tmp_rmpni);
    } 
    done=0;
    /* if P or B frame RMPNI */

    if ((sh->SliceType>=0)&&(sh->SliceType<=2))
    {
      do
      {
    
        len = GetVLCSymbol(buf, bitptr, &info, bufsize);
        linfo (len, info, &tmp1, &dummy);
        bitptr+=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
          len = GetVLCSymbol(buf, bitptr, &info, bufsize);
          linfo (len, info, &tmp_rmpni->Data, &dummy);
          bitptr+=len;

          // add RMPNI to list
          if (sh->RMPNIbuffer==NULL) 
          {
            sh->RMPNIbuffer=tmp_rmpni;
          }
          else
          {
            tmp_rmpni2=sh->RMPNIbuffer;
            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);
    }
  }

  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &sh->RPBT, &dummy);
  bitptr+=len;

  // free old buffer content
  while (sh->MMCObuffer)
  { 
    tmp_mmco=sh->MMCObuffer;
    sh->MMCObuffer=tmp_mmco->Next;
    free (tmp_mmco);
  } 
  
  /* read Memory Management Control Operation */
  if (sh->RPBT)
  {
    do
    {

      tmp_mmco=(MMCObuffer_t*)calloc (1,sizeof (MMCObuffer_t));
      tmp_mmco->Next=NULL;
    
      len = GetVLCSymbol(buf, bitptr, &info, bufsize);
      linfo (len, info, &tmp_mmco->MMCO, &dummy);
      bitptr+=len;

      switch (tmp_mmco->MMCO)
      {
      case 0:
      case 5:
        break;
      case 1:
        len = GetVLCSymbol(buf, bitptr, &info, bufsize);
        linfo (len, info, &tmp_mmco->DPN, &dummy);
        bitptr+=len;
        break;
      case 2:
        len = GetVLCSymbol(buf, bitptr, &info, bufsize);
        linfo (len, info, &tmp_mmco->LPIN, &dummy);
        bitptr+=len;
        break;
      case 3:
        len = GetVLCSymbol(buf, bitptr, &info, bufsize);
        linfo (len, info, &tmp_mmco->DPN, &dummy);
        bitptr+=len;
        len = GetVLCSymbol(buf, bitptr, &info, bufsize);
        linfo (len, info, &tmp_mmco->LPIN, &dummy);
        bitptr+=len;
        break;
      case 4:
        len = GetVLCSymbol(buf, bitptr, &info, bufsize);
        linfo (len, info, &tmp_mmco->MLIP1, &dummy);
        bitptr+=len;
        break;
      default:
        error ("Invalid MMCO operation specified",400);
        break;
      }

      // add MMCO to list
      if (sh->MMCObuffer==NULL) 
      {
        sh->MMCObuffer=tmp_mmco;
      }
      else
      {
        tmp_mmco2=sh->MMCObuffer;
        while (tmp_mmco2->Next!=NULL) tmp_mmco2=tmp_mmco2->Next;
        tmp_mmco2->Next=tmp_mmco;
      }
      
    }while (tmp_mmco->MMCO!=0);
  }
  /* end KS */

  if (ParSet[sh->ParameterSet].EntropyCoding == 1)   // CABAC in use, need to get LastMB
  {
    len = GetVLCSymbol(buf, bitptr, &info, bufsize);
    linfo (len, info, &sh->CABAC_LastMB, &dummy);
    bitptr+=len;
  }

  bytes = bitptr/8;
  if (bitptr%8)
    bytes++;

  return bytes;

}



/*!
 *****************************************************************************
 *
 * \brief 
 *    Parses and interprets the UVLC-coded partition header (Type B and C packets only)
 *
 * \return
 *    negative in case of errors, the byte-index where the UVLC/CABAC MB data
 *    starts otherwise
 * Side effects:
 *    sh->PictureID und sh->SliceID set, all other values unchanged
 *
 * \date
 *    27 October, 2001
 *
 * \author
 *    Stephan Wenger   stewe@cs.tu-berlin.de
 *****************************************************************************/

int RTPInterpretPartitionHeader (byte *buf, int bufsize, RTPSliceHeader_t *sh)
{
  int len, info, bytes, dummy, bitptr=0;
  
  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &sh->PictureID, &dummy);
  bitptr+=len;

  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &sh->SliceID, &dummy);
  bitptr+=len;

  bytes = bitptr/8;
  if (bitptr%8)
    bytes++;

  return bytes;

}

/*!
 *****************************************************************************
 *
 * \brief 
 *    Reads and interprets the RTP sequence header, expects a type 6 packet
 *
 * \return
 *
 * Side effects:
 *   sets several fields in the img-> and inp-> structure, see RTPUseParameterSet
 *
 * \date
 *    27 October, 2001
 *
 * \author
 *    Stephan Wenger   stewe@cs.tu-berlin.de
 *****************************************************************************/

// Each RTP File is supposed to start with a type 6 (Header) packet.  It is necessary
// to read this early on in order to allocate the memory for the decoder.  This should
// be fixed some day in such a way that the decoder allocates memory as needed, and
// not statically at the first frame.

int RTPSequenceHeader (struct img_par *img, struct inp_par *inp, FILE *bits)
{
  int TotalPackLen;
  RTPpacket_t *p;
  RTPSliceHeader_t *sh;
  int err;
  int intime=0;

  assert (bits != NULL);

  p=alloca (sizeof (RTPpacket_t));
  sh=alloca(sizeof (RTPSliceHeader_t));

  if (4 != fread (&TotalPackLen,1, 4, bits))
    return -4711;    // EOF inidication
  if (4 != fread (&intime, 1, 4, bits))
    return -4712;

  p->packlen = TotalPackLen;
  p->packet = alloca (p->packlen);
  if (p->packlen != fread (p->packet, 1, p->packlen, bits))
    {
      // The corruption of a packet file is not a case we should handle.
      // In a real-world system, RTP packets may get lost, but they will
      // never get shortened.  Hence, the error checked here cannot occur.
      printf ("RTP File corruption, unexpected end of file, tried to read %d bytes\n", p->packlen);
      return -4713;    // EOF
    }

  p->paylen = p->packlen - 12;          // 12 bytes RTP header
  p->payload = alloca (p->paylen);   

  if (DecomposeRTPpacket (p) < 0)
    {
      // this should never happen, hence exit() is ok.  We probably do not want to attempt
      // to decode a packet that obviously wasn't generated by RTP
      printf ("Errors reported by DecomposePacket(), exit\n");
      exit (-700);
    }

    // Here the packet is ready for interpretation

  assert (p->pt == H26LPAYLOADTYPE);
  assert (p->ssrc == 0x12345678);

  if (p->payload[0] != 6)
  {
    printf ("RTPSequenceHeader: Expect Header Packet (FirstByet = 6), found packet type %d\n", p->payload[0]);
    exit (-1);
  }

  if ((err = RTPInterpretParameterSetPacket (&p->payload[1], p->paylen-1)) < 0)
    {
      printf ("RTPInterpretParameterSetPacket returns error %d\n", err);
    }

  RTPUseParameterSet (0, img, inp);
  img->number = 0;
  
  return 0;
}


/*!
 *****************************************************************************
 *
 * \brief 
 *    Sets various img->, inp-> and currSlice->struct members according to 
 *    the contents of the sh-> slice header structure
 *
 * \return
 *
 * Side effects:
 *    Set img->       qp, current_slice_nr, type, tr
 *    Set inp->
 *    Set currSlice-> qp, start_mb_nr, slice_nr, picture_type, picture_id (CABAC only: last_mb_nr)
 *
 * \date
 *    27 October, 2001
 *
 * \author
 *    Stephan Wenger   stewe@cs.tu-berlin.de
 *****************************************************************************/

void RTPSetImgInp (struct img_par *img, struct inp_par *inp, RTPSliceHeader_t *sh)
{
  static int ActualPictureType;
  Slice *currSlice = img->currentSlice;
 
  RMPNIbuffer_t *tmp_rmpni;
  MMCObuffer_t *tmp_mmco;

  img->qp = currSlice->qp = sh->InitialQP;

  if (sh->SliceType==2)
    img->qpsp = sh->InitialSPQP;

  currSlice->start_mb_nr = (img->width/16)*sh->FirstMBInSliceY+sh->FirstMBInSliceX;

  switch (sh->SliceType)
  {
  //! Potential BUG: do we need to distinguish between INTER_IMG_MULT and INTER_IMG?
  //!    similar with B_IMG_! and B_IMG_MULT
  //! also: need to define Slice types for SP images
  //! see VCEG-N72r1 for the Slice types, which are mapped here to img->type
  case 0:
    img->type = currSlice->picture_type = ParSet[CurrentParameterSet].UseMultpred?INTER_IMG_MULT:INTER_IMG_1;
    break;
  case 1:
    img->type = currSlice->picture_type = ParSet[CurrentParameterSet].UseMultpred?B_IMG_MULT:B_IMG_1;
    break;
  case 2:
    img->type = currSlice->picture_type = ParSet[CurrentParameterSet].UseMultpred?SP_IMG_MULT:SP_IMG_1;
    break;
  case 3:
    img->type = currSlice->picture_type = INTRA_IMG;
    break;
  default:
    printf ("Panic: unknown Slice type %d, conceal by loosing slice\n", sh->SliceType);
    currSlice->ei_flag = 1;
  }  
  

  //! The purpose of the following is to check for mixed Slices in one picture.
  //! According to VCEG-N72r1 and common sense this is allowed.  However, the
  //! current software seems to have a problem of some kind, to be checked.  Hence,
  //! printf a warning

  if (currSlice->start_mb_nr == 0)
    ActualPictureType = img->type;
  else
    if (ActualPictureType != img->type)
    {
      printf ("WARNING: mixed Slice types in a single picture -- interesting things may happen :-(\n");
    }

  img->tr = currSlice->picture_id = sh->PictureID;

  currSlice->last_mb_nr = currSlice->start_mb_nr + sh->CABAC_LastMB;

  if (currSlice->last_mb_nr == currSlice->start_mb_nr)
    currSlice->last_mb_nr = img->max_mb_nr;

  /* KS: Multi Frame Buffering Syntax */
  img->pn=sh->PictureNum;

  // clear old slice RMPNI command buffer
  while (img->currentSlice->rmpni_buffer)
  {
    tmp_rmpni = img->currentSlice->rmpni_buffer;
  
    img->currentSlice->rmpni_buffer=tmp_rmpni->Next;
    free (tmp_rmpni);
  }

  img->currentSlice->rmpni_buffer=sh->RMPNIbuffer;

  sh->RMPNIbuffer=NULL;

  // free image MMCO buffer
  while (img->mmco_buffer)
  {
    tmp_mmco=img->mmco_buffer;

    img->mmco_buffer=tmp_mmco->Next;
    free (tmp_mmco);
  }

  // set image mmco bufer to actual MMCO buffer
  img->mmco_buffer=sh->MMCObuffer;
  sh->MMCObuffer=NULL;
}


/*!
 *****************************************************************************

⌨️ 快捷键说明

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