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

📄 rtp.c

📁 本源码是H.26L标准的Visual C++源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        else
          last_pframe = sh->PictureID;
        //! need to set the following for EC:
        img->tr = sh->PictureID;
      }
      else if(sh->PictureID == last_pframe + b_interval*bframe_to_code && InfoSet.NumberBFrames) //! we received a B-Frame
      {
        //! This B-Frame is the one we expected but maybe parts of it are lost!
        bframe_to_code ++;
        if(bframe_to_code > InfoSet.NumberBFrames) //! last B-Frame before next P-Frame
          last_pframe = (last_pframe+(InfoSet.FrameSkip +1))%256;
        //! need to set the following for EC:
        img->tr = sh->PictureID; 
      }
      else //! we lost at least one whole frame
      {
        back=p->packlen+8;                // Unread the packet
        fseek (bits, -back, SEEK_CUR);    
        currSlice->ei_flag = 1;
        currSlice->dp_mode = PAR_DP_1;
        currSlice->start_mb_nr = ExpectedMBNr;
        currSlice->next_header = RTPGetFollowingSliceHeader (img, nextp, nextsh); 
        assert (currSlice->start_mb_nr == img->current_mb_nr); 

#if _ERROR_CONCEALMENT_
        currSlice->last_mb_nr = img->max_mb_nr-1;
#else
        currSlice->last_mb_nr = img->max_mb_nr;
#endif
        currSlice->partArr[0].bitstream->bitstream_length=0;
        currSlice->partArr[0].bitstream->read_len=0;
        currSlice->partArr[0].bitstream->code_len=0;
        
        //TO should be OK like this
        img->pn++;
        
        if(!InfoSet.NumberBFrames || (bframe_to_code > InfoSet.NumberBFrames)) //! we expect a P-Frame
        {
          img->tr = currSlice->picture_id = (last_pframe + InfoSet.FrameSkip +1)%256;
          img->type = INTER_IMG_1;
          if(InfoSet.NumberBFrames)
          {
            bframe_to_code = 1;
            //! do not change last_pframe here
          }
          else
            last_pframe = img->tr; 
        }
        else //! we expect a B-Frame
        {
          img->tr = currSlice->picture_id = (last_pframe + b_interval*bframe_to_code)%256;
          img->type = B_IMG_1;
          bframe_to_code ++;
          if(bframe_to_code > InfoSet.NumberBFrames)
            last_pframe += (InfoSet.FrameSkip +1);
        }
        if(first)
        {
          img->pn = 0;
          img->tr = 0;
        }
        first = FALSE;
        return 0;
      }
      if(FirstMacroblockInSlice == 0)
      {
        currSlice->partArr[0].bitstream->ei_flag = 0; // everything seems to be ok.
      }
      else //! slice loss from the begining of the frame
      {
        // printf ("SLICE LOSS 2: Slice loss at PicID %d, beginning of picture to macroblock %d\n", LastPicID, FirstMacroblockInSlice); 
        back=p->packlen+8;                // Unread the packet
        fseek (bits, -back, SEEK_CUR);    
        currSlice->ei_flag = 1;
        currSlice->dp_mode = PAR_DP_1;
        currSlice->start_mb_nr = ExpectedMBNr;
        currSlice->next_header = RTPGetFollowingSliceHeader (img, nextp, nextsh); 
        assert (currSlice->start_mb_nr == img->current_mb_nr); 

#if _ERROR_CONCEALMENT_
        currSlice->last_mb_nr = FirstMacroblockInSlice-1;
#else
        currSlice->last_mb_nr = FirstMacroblockInSlice;
#endif
        currSlice->partArr[0].bitstream->bitstream_length=0;
        currSlice->partArr[0].bitstream->read_len=0;
        currSlice->partArr[0].bitstream->code_len=0;
        
        if(!InfoSet.NumberBFrames || (bframe_to_code > InfoSet.NumberBFrames)) //! we expect a P-Frame
        {
          img->type = INTER_IMG_1;
        }
        else //! we expect a B-Frame
        {
          img->type = B_IMG_1;
        }
        
        return 0;
      }
    }
    else //we did not finish the old frame
    {
      // printf ("SLICE LOSS 3: Slice loss at PicID %d, macroblocks %d to end of picture\n", LastPicID, ExpectedMBNr); 
      back=p->packlen+8;                // Unread the packet
      fseek (bits, -back, SEEK_CUR);    
      ei_flag = 1;
      currSlice->ei_flag = 1;
      currSlice->dp_mode = PAR_DP_1;
      currSlice->start_mb_nr = ExpectedMBNr;
      currSlice->next_header = RTPGetFollowingSliceHeader (img, nextp, nextsh); 
      assert (currSlice->start_mb_nr == img->current_mb_nr); 
#if _ERROR_CONCEALMENT_
      currSlice->last_mb_nr = img->max_mb_nr-1;
#else
      currSlice->last_mb_nr = img->max_mb_nr;
#endif
      currSlice->partArr[0].bitstream->bitstream_length=0;
      currSlice->partArr[0].bitstream->read_len=0;
      currSlice->partArr[0].bitstream->code_len=0;
      
      img->tr = currSlice->picture_id = LastPicID;
      
      return 0;
    }
  }

  // Here, all concealment is done and we have either a type A partition 
  // packet or a full slice packet, which need to be worked on
    
  RTPUseParameterSet (sh->ParameterSet, img, inp);
  RTPSetImgInp(img, inp, sh);

  free_Partition (currSlice->partArr[0].bitstream);

  assert (p->paylen-MBDataIndex > 0);
      
  currSlice->partArr[0].bitstream->read_len = 0;
  currSlice->partArr[0].bitstream->code_len = p->paylen-MBDataIndex;        // neu
  currSlice->partArr[0].bitstream->bitstream_length = p->paylen-MBDataIndex;

  memcpy (currSlice->partArr[0].bitstream->streamBuffer, &p->payload[MBDataIndex],p->paylen-MBDataIndex);
  buf = currSlice->partArr[0].bitstream->streamBuffer;

  if(inp->symbol_mode == CABAC)
  {
    dep = &((currSlice->partArr[0]).de_cabac);
    arideco_start_decoding(dep, buf, 0, &currSlice->partArr[0].bitstream->read_len);
  }
      
  currSlice->next_header = RTPGetFollowingSliceHeader (img, nextp, nextsh); // no use for the info in nextp, nextsh yet. 
  
  if ((p->payload[0]&0xf) == 0)         // Full Slice Packet
  {
    currSlice->dp_mode = PAR_DP_1;
    currSlice->max_part_nr=1;
    return 1;
  }
  else
  {
    currSlice->dp_mode = PAR_DP_3;
    currSlice->max_part_nr = 3;
    printf ("Found A-Partition: PicId %d, SliceID %d \n",sh->PictureID, sh->SliceID);
    RTPProcessDataPartitionedSlice (img, inp, bits, p, sh->SliceID);
    return 3;

  }

  return FALSE;
}


/*!
 *****************************************************************************
 *
 * \brief 
 *    DecomposeRTPpacket interprets the RTP packet and writes the various
 *    structure members of the RTPpacket_t structure
 *
 * \return
 *    0 in case of success
 *    negative error code in case of failure
 *
 * \para Parameters
 *    Caller is responsible to allocate enough memory for the generated payload
 *    in parameter->payload. Typically a malloc of paclen-12 bytes is sufficient
 *
 * \para Side effects
 *    none
 *
 * \para Other Notes
 *    Function contains assert() tests for debug purposes (consistency checks
 *    for RTP header fields)
 *
 * \date
 *    30 Spetember 2001
 *
 * \author
 *    Stephan Wenger   stewe@cs.tu-berlin.de
 *****************************************************************************/

int DecomposeRTPpacket (RTPpacket_t *p)

{
  // consistency check 
  assert (p->packlen < 65536 - 28);  // IP, UDP headers
  assert (p->packlen >= 12);         // at least a complete RTP header
  assert (p->payload != NULL);
  assert (p->packet != NULL);

  // Extract header information

  p->v  = p->packet[0] & 0x3;
  p->p  = (p->packet[0] & 0x4) >> 2;
  p->x  = (p->packet[0] & 0x8) >> 3;
  p->cc = (p->packet[0] & 0xf0) >> 4;

  p->m  = p->packet[1] & 0x1;
  p->pt = (p->packet[1] & 0xfe) >> 1;

  p->seq = p->packet[2] | (p->packet[3] << 8);

  memcpy (&p->timestamp, &p->packet[4], 4);// change to shifts for unified byte sex
  memcpy (&p->ssrc, &p->packet[8], 4);// change to shifts for unified byte sex

  // header consistency checks
  if (     (p->v != 2)
        || (p->p != 0)
        || (p->x != 0)
        || (p->cc != 0) )
  {
    printf ("DecomposeRTPpacket, RTP header consistency problem, header follows\n");
    DumpRTPHeader (p);
    return -1;
  }
  p->paylen = p->packlen-12;
  memcpy (p->payload, &p->packet[12], p->paylen);
  return 0;
}

/*!
 *****************************************************************************
 *
 * \brief 
 *    DumpRTPHeader is a debug tool that dumps a human-readable interpretation
 *    of the RTP header
 *
 * \return
 *    n.a.
 * \para Parameters
 *    the RTP packet to be dumped, after DecompositeRTPpacket()
 *
 * \para Side effects
 *    Debug output to stdout
 *
 * \date
 *    30 Spetember 2001
 *
 * \author
 *    Stephan Wenger   stewe@cs.tu-berlin.de
 *****************************************************************************/

void DumpRTPHeader (RTPpacket_t *p)

{
  int i;
  for (i=0; i< 30; i++)
    printf ("%02x ", p->packet[i]);
  printf ("Version (V): %d\n", p->v);
  printf ("Padding (P): %d\n", p->p);
  printf ("Extension (X): %d\n", p->x);
  printf ("CSRC count (CC): %d\n", p->cc);
  printf ("Marker bit (M): %d\n", p->m);
  printf ("Payload Type (PT): %d\n", p->pt);
  printf ("Sequence Number: %d\n", p->seq);
  printf ("Timestamp: %d\n", p->timestamp);
  printf ("SSRC: %d\n", p->ssrc);
}

/*!
 *****************************************************************************
 *
 * \brief 
 *    Parses and interprets the UVLC-coded slice header
 *
 * \return
 *    negative in case of errors, the byte-index where the UVLC/CABAC MB data
 *    starts otherwise
 *
 * \date
 *    27 October, 2001
 *
 * \author
 *    Stephan Wenger   stewe@cs.tu-berlin.de
 *****************************************************************************/

int RTPInterpretSliceHeader (byte *buf, int bufsize, int ReadSliceId, RTPSliceHeader_t *sh)
{
  int len, info, bytes, dummy, bitptr=0;
  int temp, tmp1;
  RMPNIbuffer_t *tmp_rmpni,*tmp_rmpni2;
  MMCObuffer_t *tmp_mmco,*tmp_mmco2;
  int done;
  
  len = GetVLCSymbol(buf, bitptr, &info, bufsize);
  linfo (len, info, &sh->ParameterSet, &dummy);
  bitptr+=len;

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

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

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

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

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

  if (sh->SliceType==2) // SP Picture
  {
    len = GetVLCSymbol(buf, bitptr, &info, bufsize);
    linfo (len, info, &sh->InitialSPQP, &dummy);
    bitptr+=len;
    sh->InitialSPQP = 31-sh->InitialSPQP;
  }

  assert (sh->ParameterSet == 0);     // only for testing, should be deleted as soon as more than one parameter set is generated by trhe encoder
  assert (sh->SliceType > 0 || sh->SliceType < 5);
  assert (sh->InitialQP >=0 && sh->InitialQP < 32);
  assert (sh->InitialSPQP >=0 && sh->InitialSPQP < 32);


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

  /* KS: Multi-Picture Buffering Syntax */

  /* 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

⌨️ 快捷键说明

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