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

📄 rtp.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
  else
  {
    if (LastPicID == sh->PictureID)   // we are in the same picture
    {
      if (ExpectedMBNr == FirstMacroblockInSlice)
      {
        currSlice->partArr[0].bitstream->ei_flag = 0;    // everything seems to be ok.
      }
      else
      {
        if (FirstMacroblockInSlice == 0)
        {
          assert ("weird! PicID wrap around?  Should not happen\n");
        }
        else
        {
          //printf ("SLICE LOSS 1: Slice loss at PicID %d, macoblocks %d to %d\n",LastPicID, ExpectedMBNr, FirstMacroblockInSlice-1);
          back=p->packlen+8;
          fseek (bits, -back, SEEK_CUR);    

          //FirstMacroblockInSlice = (img->width*img->height)/(16*16);
          currSlice->ei_flag = 1;
          currSlice->dp_mode = PAR_DP_1;
          currSlice->start_mb_nr = ExpectedMBNr;
          //! just the same slice we just read!
          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;
          currSlice->partArr[0].bitstream->ei_flag=1;
          
          img->tr = currSlice->picture_id = LastPicID;
         
          return 0;
        }
      }
    }
    else      // we are in a different picture
    {
      b_interval = (int)((float)(InfoSet.FrameSkip +1)/(float)(InfoSet.NumberBFrames +1) + 0.49999);
      if (ExpectedMBNr == 0)    // the old picture was finished
      {
        if (((last_pframe + InfoSet.FrameSkip +1)%256) == sh->PictureID && 
             (bframe_to_code > InfoSet.NumberBFrames)) //! we received a new P-Frame and coded all B-Frames
        {
          if(InfoSet.NumberBFrames)
          {
            bframe_to_code = 1;
            last_pframe = sh->PictureID-(InfoSet.FrameSkip +1);
          }
          else
            last_pframe = sh->PictureID;

          if(last_pframe < 0)
            last_pframe += 256;
          b_frame = FALSE;
        }
        else if(sh->PictureID == ((last_pframe + b_interval*bframe_to_code)%256) && InfoSet.NumberBFrames) //! we received a B-Frame
        {
          bframe_to_code ++;
          b_frame = TRUE;
          if(bframe_to_code > InfoSet.NumberBFrames)
            last_pframe += (InfoSet.FrameSkip +1);
        }
        else //! we lost at least one whole frame
        {
          //printf ("SLICE LOSS 4: Slice loss at PicID %d containing the whole frame\n", LastPicID + InfoSet.FrameSkip +1); 
          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); 
          currSlice->partArr[0].readSyntaxElement = readSyntaxElement_RTP;
          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;

          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)
            {
              last_pframe = img->tr-(InfoSet.FrameSkip +1);
              bframe_to_code = 1;
            }
            else
              last_pframe = img->tr;
          
            if(last_pframe < 0)
              last_pframe += 256;
            b_frame = FALSE;
            img->pn++;
          }
          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);
          }
        
          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;
          currSlice->partArr[0].readSyntaxElement = readSyntaxElement_RTP;
        
          img->tr = currSlice->picture_id = sh->PictureID;
          if(b_frame == FALSE) //! we expect a P-Frame
          {
            img->type = INTER_IMG_1;
            img->pn++;
          }  
          else
            img->type = B_IMG_1;
        
          return 0;
        }
      }
      else //we did not finish the old frame
      {
        //upprintf ("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);    
        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;
        currSlice->partArr[0].readSyntaxElement = readSyntaxElement_RTP;
      
        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  || b_frame)         // Full Slice Packet or B-Frame
  {
    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;
    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 = MAX_QP-sh->InitialQP;

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

  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 >=MIN_QP && sh->InitialQP <= MAX_QP);


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

  /* KS: Multi-Picture Buffering Syntax */

⌨️ 快捷键说明

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