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

📄 rtp.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (!strncmp (s, "MotionResolution", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_STRING;
        interpreter = INTERPRET_MOTION_RESOLUTION;
        destin = &ParSet[ps].MotionResolution;
        break;
      }
      if (!strncmp (s, "PartitioningType", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_STRING;
        interpreter = INTERPRET_PARTITIONING_TYPE;
        destin = &ParSet[ps].PartitioningType;
        break;
      }
      if (!strncmp (s, "IntraPredictionType", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_STRING;
        interpreter = INTERPRET_INTRA_PREDICTION;
        destin = &ParSet[ps].IntraPredictionType;
        break;
      }
      if (!strncmp (s, "HRCParameters", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_INT;
        interpreter = INTERPRET_COPY;
        destin = &ParSet[ps].HRCParameters;
        break;
      }
      if (!strncmp (s, "FramesToBeEncoded", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_INT;
        interpreter = INTERPRET_COPY;
        destin = &InfoSet.FramesToBeEncoded;
        break;
      }
      if (!strncmp (s, "FrameSkip", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_INT;
        interpreter = INTERPRET_COPY;
        destin = &InfoSet.FrameSkip;
        break;
      }
      if (!strncmp (s, "SequenceFileName", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_STRING;
        interpreter = INTERPRET_COPY;
        destin = &InfoSet.SequenceFileName;
        break;
      }
      if (!strncmp (s, "NumberBFrames", MAX_PARAMETER_STRINGLEN))
      {
        state = EXPECT_STRUCTVAL_INT;
        interpreter = INTERPRET_COPY;
        destin = &InfoSet.NumberBFrames;
        break;
      }
     
      // Here, all defined Parameter names are checked.  Anything else is a syntax error
      printf ("Syntax Error: unknown Parameter %s\n", s);
      printf ("Parsing error in Header Packet: position %d, packet %s\n",
          bufp, buf);
      return -3;
      break;        // to make lint happy
    
    case EXPECT_STRUCTVAL_INT:
      if (1!=sscanf (&buf[bufp], "%d", (int *)destin))
      {
        printf ("Parsing error EXPECT STRUCTVAL INT in Header Packet: position %d, packet %s\n",
          bufp, &buf[bufp]);
        return -4;
      }
// printf ("EXPECT_STRCUTVAL_INT: write %d\n", * (int *)destin);
      while (bufp < buflen && buf[bufp] != '\n')    // Skip any trailing whitespace and \n
        bufp++;
      bufp++;
      state=EXPECT_ATTR;
      break;
      
    case EXPECT_STRUCTVAL_STRING:
      if (1 != sscanf (&buf[bufp], "%100s", s))
      {
        printf ("Parsing error EXPECT STRUCTVAL STRING in Header Packet: position %d, packet %s\n",
          bufp, &buf[bufp]);
        return -5;
      }
      while (bufp < buflen && buf[bufp] != '\n')   // Skip any trailing whitespace and \n
        bufp++;
      bufp++;
      state=EXPECT_ATTR;

      switch (interpreter)
      {
      case INTERPRET_COPY:
        // nothing -- handled where it occurs
        break;
      case INTERPRET_ENTROPY_CODING:
        if (!strncmp (s, "UVLC", 4))
          * (int *)destin = 0;
        else
          * (int *)destin = 1;
//        printf ("in INterpret, Entropy COding :%s: results in %d\n", s, *(int *)destin);
        break;
      case INTERPRET_MOTION_RESOLUTION:
        if (!strncmp (s, "quater", 6))
          * (int *)destin = 0;
        else
          * (int *)destin = 1;
        break;
      case INTERPRET_INTRA_PREDICTION:
        if (!strncmp (s, "InterPredicted", 14))
          * (int *)destin = 0;
        else
          * (int *)destin = 1;
        break;
      case INTERPRET_PARTITIONING_TYPE:
        if (!strncmp (s, "one", 3))
          * (int *)destin = 0;
        else
          * (int *)destin = 1;
        break;
      default:
        assert (0==1);
      }
    break;

    default:
      printf ("Parsing error UNDEFINED SYNTAX in Header Packet: position %d, packet %s\n",
        bufp, &buf[bufp]);
      return -1;
    }
//  printf ("\t\t%d\n", bufp);
  }

//  printf ("CurrentParameterSet %d, ps %d\n", CurrentParameterSet, ps);
//  printf ("RTPInterpretParameterPacket: xsize x Ysize, %d x %d, Entropy %d, Motion %d  MaxPicId %d\n",
//    ParSet[ps].XSizeMB, ParSet[ps].YSizeMB, ParSet[ps].EntropyCoding, ParSet[ps].MotionResolution, ParSet[ps].MaxPicID);
  ParSet[ps].Valid = 1;
  return 0;
}


/*!
 ************************************************************************
 * \brief
 *    Update img->xxx with the content of a parameter set, called for 
 *    every slice 
 ************************************************************************
 */



void RTPUseParameterSet (int n, struct img_par *img, struct inp_par *inp)
{
  int status;
  
  if (n == CurrentParameterSet)
    return;   // no change

//  printf ("Use a new parameter set: old %d, new %d\n", CurrentParameterSet, n);
  CurrentParameterSet = n;

  status = RTP_PARAMETER_SET_OK;

  if (CurrentParameterSet < 0 || (CurrentParameterSet > RTP_MAX_PARAMETER_SET))
  {
    printf ("Parameter Set %d out of range, conceal to 0\n", CurrentParameterSet);
    CurrentParameterSet = 0;    // and pray that it works...
    status = RTP_PARAMETER_SET_OUT_OF_RANGE;
  }

  if (!ParSet[CurrentParameterSet].Valid)
  {
    printf ("Try to use uninitialized Parameter Set %d, conceal to 0\n", CurrentParameterSet);
    CurrentParameterSet = 0;
    status = RTP_PARAMETER_SET_INVALID;
  }

  // Now updates global decoder variables with the appropriate parameter set.

  // A full-fledged decoder would make some consistency checks.  For example,
  // it makes sense to change the MotionResolution or the EntropyCode within
  // a picture (img->current_mb_nr != 0).  It doesn't make sense to change
  // the pixel aspect ratio.
  // There is no need to do those checks in an error free environment -- an
  // encoder is simply not supposed to do so.  In error prone environments,
  // however, this is an additional means for error detection.

  // Note: Many parameters are available in both the input-> and img-> structures.
  // Some people seem to use the input-> parameters, others the img-> parameters.
  // This should be cleaned up one day.
  // For now simply copy any updated variables into both structures.

  // MaxPicID: doesn't exist in pinput-> or img->
  inp->buf_cycle = ParSet[CurrentParameterSet].BufCycle;
  img->buf_cycle = inp->buf_cycle+1;      // see init_global_buffers()

  // PixAspectRatioX: doesn't exist
  // PixAspectRatioY: doesn't exist
  // DisplayWindowOffset*: doesn't exist

  // XSizeMB
  img->width = ParSet[CurrentParameterSet].XSizeMB*16;
  img->width_cr = ParSet[CurrentParameterSet].XSizeMB*8;

  //YSizeMB
  img->height = ParSet[CurrentParameterSet].YSizeMB*16;
  img->height_cr = ParSet[CurrentParameterSet].YSizeMB*8;

  // EntropyCoding
  if (ParSet[CurrentParameterSet].EntropyCoding == 0)
    inp->symbol_mode = UVLC;
  else
    inp->symbol_mode = CABAC;

  // MotionResolution
  img->mv_res = ParSet[CurrentParameterSet].MotionResolution;

  // PartitioningType
  inp->partition_mode = ParSet[CurrentParameterSet].PartitioningType;

  // IntraPredictionType
  inp->UseConstrainedIntraPred = ParSet[CurrentParameterSet].IntraPredictionType;
  
  //! img->type: This is calculated by using ParSet[CurrentParameterSet].UseMultpred
  //! and the slice type from the slice header.  It is set in RTPSetImgInp()

  // HRCParameters: Doesn't exist
}


/*!
 *****************************************************************************
 *
 * \brief 
 *    RTPReadPacket reads one packet from file
 *
 * \return
 *    0 in case of success, -1 in case of error
 *
 * \para Paremeters
 *    p: packet data structure, with memory for p->packet allocated
 *
 * Side effects:
 *   - File pointer in bits moved
 *   - p->xxx filled by reading and Decomposepacket()
 *
 * \date
 *    04 November, 2001
 *
 * \author
 *    Stephan Wenger, stewe@cs.tu-berlin.de
 *****************************************************************************/

int RTPReadPacket (RTPpacket_t *p, FILE *bits)
{
  int Filepos, intime;

  assert (p != NULL);
  assert (p->packet != NULL);
  assert (p->payload != NULL);

  Filepos = ftell (bits);
  if (4 != fread (&p->packlen,1, 4, bits))
    {
      printf ("Unable to read 4 bytes for the RTP packet size\n");
      fseek (bits, Filepos, SEEK_SET);
      return -1;
    }
    
  if (4 != fread (&intime, 1, 4, bits))
    {
      fseek (bits, Filepos, SEEK_SET);
      printf ("RTPReadPacket: File corruption, could not read Timestamp, exit\n");
      exit (-1);
    }

  assert (p->packlen < MAXRTPPACKETSIZE);
  if (p->packlen != fread (p->packet, 1, p->packlen, bits))
    {
      printf ("RTPReadPacket: File corruption, could not read %d bytes\n", p->packlen);
      exit (-1);    // EOF inidication
    }
  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);
    }
    assert (p->pt == H26LPAYLOADTYPE);
    assert (p->ssrc == 0x12345678);
  return 0;
}


/*!
 *****************************************************************************
 *
 * \brief 
 *    RTPReadDataPartitionedSlice collects all partitiobnss of the slice
 *
 *
 * \return
 *  sequence number of the last packed that has been concealed
 *
 * VCEG-N72r1 may not state it explicitely, but we decided that partitions
 * have to be sent immediately after each other.  Meaning, if A, B, and C are
 * all present, the rtp-timestamp of A is 2 bigger than the one of A.
 * Hence, this function reads all those partitions into their respective 
 * buffers
 *
 * Side effects: many!
 *   - File pointer in bits moved
 *   - currSlice->partArr[0, 1, 2] updated
 *   - img-> and inp-> updated, see RTPSetImgInp() 
 *
 * \date
 *    04 November, 2001
 *
 * \author
 *    Stephan Wenger, stewe@cs.tu-berlin.de
 *****************************************************************************/

#define SEQ_PLUS_1  (a->seq+1 == b->seq)
#define SEQ_PLUS_2  (a->seq+2 == b->seq)
#define SAME_TIME (a->timestamp == b->timestamp)
#define SLICE_NO_OK (b_SliceID == a_SliceID)
#define SAME_SLICE (SAME_TIME && SLICE_NO_OK)
#define TYPE_B (b->payload[0] == 2)
#define TYPE_C (b->payload[0] == 3)

void RTPProcessDataPartitionedSlice (struct img_par *img, struct inp_par *inp, FILE *bits, 
                                     RTPpacket_t *a, int a_SliceID)


{

//!  BUG: need to fix wrap-around-problem for the sequence number
//!       needs to be fixed only for HUGE files (more than 2^^16 packets)
//!       Note: in contrast to RTP spec, encoder starts sequence no at 0 to ease debugging

  RTPpacket_t *b, *c;
  RTPSliceHeader_t *sh;
  long Filepos;
  int StartMBData;
  int b_SliceID, b_PicId, c_SliceID, c_PicID;
  Slice *currSlice = img->currentSlice;

  Filepos = ftell (bits);

  b=alloca(sizeof(RTPpacket_t));
  b->packet=alloca (MAXRTPPACKETSIZE);
  b->payload=alloca (MAXRTPPAYLOADLEN);
  sh=alloca (sizeof(RTPSliceHeader_t));

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


  if (RTPReadPacket (b, bits) != 0)
  {
    printf ("Error while reading RTP packet, assuming intentional EOF and the last slice contains no type B, C\n");
    img->currentSlice->partArr[1].bitstream->bitstream_length=0;
    img->currentSlice->partArr[1].bitstream->code_len=0;
    img->currentSlice->partArr[1].bitstream->ei_flag=0;
    img->currentSlice->partArr[2].bitstream->bitstream_length=0;
    img->currentSlice->partArr[2].bitstream->code_len=0;
    img->currentSlice->partArr[2].bitstream->ei_flag=0;
    return;
  }

  StartMBData = RTPInterpretPartitionHeader (&b->payload[1], b->paylen, sh);
  //StartMBData++;   // Skip First Byte
  b_SliceID = sh->SliceID;
  b_PicId = sh->PictureID;

  // General: 
  //   Lost partition, identified by missing packet due to sequence number problems, or
  //   Empty partition, identified by not present partition
  // The two cases are signalled to higher layers as follows
  //   Lost Partition: currStream->ei_flag is set, length inidicators don't care
  //   Empty Partition: only length indicator is zero, ei_flag is cleared


  if (b->seq > a->seq+2)    // two or more consecutive packet losses, none, one, or both 
  {                         // partitions lost and no way to figure which ones
    fseek (bits, Filepos, SEEK_SET);    // go back 
    printf ("lost at least two partitions\n");
    img->currentSlice->partArr[1].bitstream->bitstream_length=0;
    img->currentSlice->partArr[1].bitstream->code_len=0;
    img->currentSlice->partArr[1].bitstream->ei_flag=1;
    img->currentSlice->partArr[1].readSyntaxElement = readSyntaxElement_RTP;
    img->currentSlice->partArr[2].bitstream->bitstream_length=0;
    img->currentSlice->partArr[2].bitstream->code_len=0;
    img->currentSlice->partArr[2].bitstream->ei_flag=1;
    img->currentSlice->partArr[2].readSyntaxElement = readSyntaxElement_RTP;
    return;
  }

  if (SEQ_PLUS_2 && !SAME_SLICE) // one packet was lost could be type B partition or type C partition
  {
    fseek (bits, Filepos,

⌨️ 快捷键说明

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