rtp.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:19k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *****************************************************************************
  3.  * file rtp.c
  4.  *
  5.  * brief
  6.  *    Functions to handle RTP headers and packets per RFC 3984
  7.  *    with restricted functionality.
  8.  *
  9.  * author
  10.  *    Stephan Wenger    stewe@cs.tu-berlin.de
  11.  *****************************************************************************/
  12. #ifdef WIN32
  13. #include <Winsock2.h>
  14. #else
  15. #include <netinet/in.h>
  16. #endif
  17. #include "global.h"
  18. #include "rtp.h"
  19. #include "sei.h"
  20. // A little trick to avoid those horrible #if TRACE all over the source code
  21. #if TRACE
  22. #define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
  23. #else
  24. #define SYMTRACESTRING(s) // to nothing
  25. #endif
  26. int CurrentRTPTimestamp = 0;      //! The RTP timestamp of the current packet,
  27.                                   //! incremented with all P and I frames
  28. unsigned short CurrentRTPSequenceNumber = 0; //! The RTP sequence number of the current packet
  29.                                              //! incremented by one for each sent packet
  30. FILE *f;
  31. /*!
  32.  *****************************************************************************
  33.  *
  34.  * brief
  35.  *    ComposeRTPpacket composes the complete RTP packet using the various
  36.  *    structure members of the RTPpacket_t structure
  37.  *
  38.  * return
  39.  *    0 in case of success
  40.  *    negative error code in case of failure
  41.  *
  42.  * par Parameters
  43.  *    Caller is responsible to allocate enough memory for the generated packet
  44.  *    in parameter->packet. Typically a malloc of 12+paylen bytes is sufficient
  45.  *
  46.  * par Side effects
  47.  *    none
  48.  *
  49.  * note
  50.  *    Function contains assert() tests for debug purposes (consistency checks
  51.  *    for RTP header fields
  52.  *
  53.  * date
  54.  *    30 September 2001
  55.  *
  56.  * author
  57.  *    Stephan Wenger   stewe@cs.tu-berlin.de
  58.  *****************************************************************************/
  59. int ComposeRTPPacket (RTPpacket_t *p)
  60. {
  61.   unsigned int temp32;
  62.   unsigned short temp16;
  63.   // Consistency checks through assert, only used for debug purposes
  64.   assert (p->v == 2);
  65.   assert (p->p == 0);
  66.   assert (p->x == 0);
  67.   assert (p->cc == 0);    // mixer designers need to change this one
  68.   assert (p->m == 0 || p->m == 1);
  69.   assert (p->pt < 128);
  70.   assert (p->payload != NULL);
  71.   assert (p->paylen < 65536 - 40);  // 2**16 -40 for IP/UDP/RTP header
  72.   assert (p->packet != NULL);
  73.   // Compose RTP header, little endian
  74.   p->packet[0] = (byte)
  75.     ( ((p->v  & 0x03) << 6)
  76.     | ((p->p  & 0x01) << 5)
  77.     | ((p->x  & 0x01) << 4)
  78.     | ((p->cc & 0x0F) << 0) );
  79.   p->packet[1] = (byte)
  80.     ( ((p->m  & 0x01) << 7)
  81.     | ((p->pt & 0x7F) << 0) );
  82.   // sequence number, msb first
  83.   temp16 = htons((unsigned short)p->seq);
  84.   memcpy (&p->packet[2], &temp16, 2);  // change to shifts for unified byte sex
  85.   //declare a temporary variable to perform network byte order conversion
  86.   temp32 = htonl(p->timestamp);
  87.   memcpy (&p->packet[4], &temp32, 4);  // change to shifts for unified byte sex
  88.   temp32 = htonl(p->ssrc);
  89.   memcpy (&p->packet[8], &temp32, 4);// change to shifts for unified byte sex
  90.   // Copy payload
  91.   memcpy (&p->packet[12], p->payload, p->paylen);
  92.   p->packlen = p->paylen+12;
  93.   return 0;
  94. }
  95. /*!
  96.  *****************************************************************************
  97.  *
  98.  * brief
  99.  *    WriteRTPPacket writes the supplied RTP packet to the output file
  100.  *
  101.  * return
  102.  *    0 in case of access
  103.  *    <0 in case of write failure (typically fatal)
  104.  *
  105.  * param p
  106.  *    the RTP packet to be written (after ComposeRTPPacket() )
  107.  * param f
  108.  *    output file
  109.  *
  110.  * date
  111.  *    October 23, 2001
  112.  *
  113.  * author
  114.  *    Stephan Wenger   stewe@cs.tu-berlin.de
  115.  *****************************************************************************/
  116. int WriteRTPPacket (RTPpacket_t *p, FILE *f)
  117. {
  118.   int intime = -1;
  119.   assert (f != NULL);
  120.   assert (p != NULL);
  121.   if (1 != fwrite (&p->packlen, 4, 1, f))
  122.     return -1;
  123.   if (1 != fwrite (&intime, 4, 1, f))
  124.     return -1;
  125.   if (1 != fwrite (p->packet, p->packlen, 1, f))
  126.     return -1;
  127.   return 0;
  128. }
  129. /*!
  130.  *****************************************************************************
  131.  *
  132.  * brief
  133.  *    int RTPWriteNALU write a NALU to the RTP file
  134.  *
  135.  * return
  136.  *    Number of bytes written to output file
  137.  *
  138.  * par Side effects
  139.  *    Packet written, RTPSequenceNumber and RTPTimestamp updated
  140.  *
  141.  * date
  142.  *    December 13, 2002
  143.  *
  144.  * author
  145.  *    Stephan Wenger   stewe@cs.tu-berlin.de
  146.  *****************************************************************************/
  147. int WriteRTPNALU (NALU_t *n)
  148. {
  149.   RTPpacket_t *p;
  150.   
  151.   byte first_byte;
  152.   assert (f != NULL);
  153.   assert (n != NULL);
  154.   assert (n->len < 65000);
  155.   first_byte = (byte)
  156.     (n->forbidden_bit << 7      |
  157.      n->nal_reference_idc << 5  |
  158.      n->nal_unit_type );
  159.   // Set RTP structure elements and alloca() memory foor the buffers
  160.   if ((p = (RTPpacket_t *) malloc (sizeof (RTPpacket_t))) == NULL)
  161.     no_mem_exit ("RTPWriteNALU-1");
  162.   if ((p->packet = malloc (MAXRTPPACKETSIZE)) == NULL)
  163.     no_mem_exit ("RTPWriteNALU-2");
  164.   if ((p->payload = malloc (MAXRTPPACKETSIZE)) == NULL)
  165.     no_mem_exit ("RTPWriteNALU-3");
  166.   p->v=2;
  167.   p->p=0;
  168.   p->x=0;
  169.   p->cc=0;
  170.   p->m=(n->startcodeprefix_len==4)&1;     // a long startcode of Annex B sets marker bit of RTP
  171.                                           // Not exactly according to the RTP paylaod spec, but
  172.                                           // good enough for now (hopefully).
  173.                                           //! For error resilience work, we need the correct
  174.                                           //! marker bit.  Introduce a nalu->marker and set it in
  175.                                           //! terminate_slice()?
  176.   p->pt=H264PAYLOADTYPE;
  177.   p->seq=CurrentRTPSequenceNumber++;
  178.   p->timestamp=CurrentRTPTimestamp;
  179.   p->ssrc=H264SSRC;
  180.   p->paylen = 1 + n->len;
  181.   p->payload[0] = first_byte;
  182.   memcpy (p->payload+1, n->buf, n->len);
  183.   // Generate complete RTP packet
  184.   if (ComposeRTPPacket (p) < 0)
  185.   {
  186.     printf ("Cannot compose RTP packet, exitn");
  187.     exit (-1);
  188.   }
  189.   if (WriteRTPPacket (p, f) < 0)
  190.   {
  191.     printf ("Cannot write %d bytes of RTP packet to outfile, exitn", p->packlen);
  192.     exit (-1);
  193.   }
  194.   free (p->packet);
  195.   free (p->payload);
  196.   free (p);
  197.   return (n->len * 8);
  198. }
  199. /*!
  200.  ********************************************************************************************
  201.  * brief
  202.  *    RTPUpdateTimestamp: patches the RTP timestamp depending on the TR
  203.  *
  204.  * param
  205.  *    tr: TRof the following NALUs
  206.  *
  207.  * return
  208.  *    none.
  209.  *
  210.  ********************************************************************************************
  211. */
  212. void RTPUpdateTimestamp (int tr)
  213. {
  214.   int delta;
  215.   static int oldtr = -1;
  216.   if (oldtr == -1)            // First invocation
  217.   {
  218.     CurrentRTPTimestamp = 0;  //! This is a violation of the security req. of
  219.                               //! RTP (random timestamp), but easier to debug
  220.     oldtr = 0;
  221.     return;
  222.   }
  223.   /*! The following code assumes a wrap around of TR at 256, and
  224.       needs to be changed as soon as this is no more true.
  225.       The support for B frames is a bit tricky, because it is not easy to distinguish
  226.       between a natural wrap-around of the tr, and the intentional going back of the
  227.       tr because of a B frame.  It is solved here by a heuristic means: It is assumed that
  228.       B frames are never "older" than 10 tr ticks.  Everything higher than 10 is considered
  229.       a wrap around.
  230.   */
  231.   delta = tr - oldtr;
  232.   if (delta < -10)        // wrap-around
  233.     delta+=256;
  234.   CurrentRTPTimestamp += delta * RTP_TR_TIMESTAMP_MULT;
  235.   oldtr = tr;
  236. }
  237. /*!
  238.  ********************************************************************************************
  239.  * brief
  240.  *    Opens the output file for the RTP packet stream
  241.  *
  242.  * param Filename
  243.  *    The filename of the file to be opened
  244.  *
  245.  * return
  246.  *    none.  Function terminates the program in case of an error
  247.  *
  248.  ********************************************************************************************
  249. */
  250. void OpenRTPFile (char *Filename)
  251. {
  252.   if ((f = fopen (Filename, "wb")) == NULL)
  253.   {
  254.     printf ("Fatal: cannot open bitstream file '%s', exit (-1)n", Filename);
  255.     exit (-1);
  256.   }
  257. }
  258. /*!
  259.  ********************************************************************************************
  260.  * brief
  261.  *    Closes the output file for the RTP packet stream
  262.  *
  263.  * return
  264.  *    none.  Function terminates the program in case of an error
  265.  *
  266.  ********************************************************************************************
  267. */
  268. void CloseRTPFile (void)
  269. {
  270.   fclose(f);
  271. }
  272. #if 0
  273. /*!
  274.  *****************************************************************************
  275.  *
  276.  * brief
  277.  *    int aggregationRTPWriteBits (int marker) write the Slice header for the RTP NAL
  278.  *
  279.  * return
  280.  *    Number of bytes written to output file
  281.  *
  282.  * param marker
  283.  *    marker bit,
  284.  *
  285.  * par Side effects
  286.  *    Packet written, RTPSequenceNumber and RTPTimestamp updated
  287.  *
  288.  * date
  289.  *    September 10, 2002
  290.  *
  291.  * author
  292.  *    Dong Tian   tian@cs.tut.fi
  293.  *****************************************************************************/
  294. int aggregationRTPWriteBits (int Marker, int PacketType, int subPacketType, void * bitstream,
  295.                     int BitStreamLenInByte, FILE *out)
  296. {
  297.   RTPpacket_t *p;
  298.   int offset;
  299. //  printf( "writing aggregation packet...n");
  300.   assert (out != NULL);
  301.   assert (BitStreamLenInByte < 65000);
  302.   assert (bitstream != NULL);
  303.   assert ((PacketType&0xf) == 4);
  304.   // Set RTP structure elements and alloca() memory foor the buffers
  305.   p = (RTPpacket_t *) alloca (sizeof (RTPpacket_t));
  306.   p->packet=alloca (MAXRTPPACKETSIZE);
  307.   p->payload=alloca (MAXRTPPACKETSIZE);
  308.   p->v=2;
  309.   p->p=0;
  310.   p->x=0;
  311.   p->cc=0;
  312.   p->m=Marker&1;
  313.   p->pt=H264PAYLOADTYPE;
  314.   p->seq=CurrentRTPSequenceNumber++;
  315.   p->timestamp=CurrentRTPTimestamp;
  316.   p->ssrc=H264SSRC;
  317.   offset = 0;
  318.   p->payload[offset++] = PacketType; // This is the first byte of the compound packet
  319.   // FIRST, write the sei message to aggregation packet, if it is available
  320.   if ( HaveAggregationSEI() )
  321.   {
  322.     p->payload[offset++] = sei_message[AGGREGATION_SEI].subPacketType; // this is the first byte of the first subpacket
  323.     *(short*)&(p->payload[offset]) = sei_message[AGGREGATION_SEI].payloadSize;
  324.     offset += 2;
  325.     memcpy (&p->payload[offset], sei_message[AGGREGATION_SEI].data, sei_message[AGGREGATION_SEI].payloadSize);
  326.     offset += sei_message[AGGREGATION_SEI].payloadSize;
  327.     clear_sei_message(AGGREGATION_SEI);
  328.   }
  329.   // SECOND, write other payload to the aggregation packet
  330.   // to do ...
  331.   // LAST, write the slice data to the aggregation packet
  332.   p->payload[offset++] = subPacketType;  // this is the first byte of the second subpacket
  333.   *(short*)&(p->payload[offset]) = BitStreamLenInByte;
  334.   offset += 2;
  335.   memcpy (&p->payload[offset], bitstream, BitStreamLenInByte);
  336.   offset += BitStreamLenInByte;
  337.   p->paylen = offset;  // 1 +3 +seiPayload.payloadSize +3 +BitStreamLenInByte
  338.   // Now the payload is ready, we can ...
  339.   // Generate complete RTP packet
  340.   if (ComposeRTPPacket (p) < 0)
  341.   {
  342.     printf ("Cannot compose RTP packet, exitn");
  343.     exit (-1);
  344.   }
  345.   if (WriteRTPPacket (p, out) < 0)
  346.   {
  347.     printf ("Cannot write %d bytes of RTP packet to outfile, exitn", p->packlen);
  348.     exit (-1);
  349.   }
  350.   return (p->packlen);
  351. }
  352. /*!
  353.  *****************************************************************************
  354.  * brief
  355.  *    Determine if current packet is normal packet or compound packet (aggregation
  356.  *    packet)
  357.  *
  358.  * return
  359.  *    return TRUE, if it is compound packet.
  360.  *    return FALSE, otherwise.
  361.  *
  362.  * date
  363.  *    September 10, 2002
  364.  *
  365.  * author
  366.  *    Dong Tian   tian@cs.tut.fi
  367.  *****************************************************************************/
  368. Boolean isAggregationPacket(void)
  369. {
  370.   if (HaveAggregationSEI())
  371.   {
  372.     return TRUE;
  373.   }
  374.   // Until Sept 2002, the JM will produce aggregation packet only for some SEI messages
  375.   return FALSE;
  376. }
  377. #endif
  378. /*!
  379.  *****************************************************************************
  380.  * brief
  381.  *    Prepare the aggregation sei message.
  382.  *
  383.  * date
  384.  *    September 10, 2002
  385.  *
  386.  * author
  387.  *    Dong Tian   tian@cs.tut.fi
  388.  *****************************************************************************/
  389. void PrepareAggregationSEIMessage(void)
  390. {
  391.   Boolean has_aggregation_sei_message = FALSE;
  392.   clear_sei_message(AGGREGATION_SEI);
  393.   // prepare the sei message here
  394.   // write the spare picture sei payload to the aggregation sei message
  395.   if (seiHasSparePicture && img->type != B_SLICE)
  396.   {
  397.     FinalizeSpareMBMap();
  398.     assert(seiSparePicturePayload.data->byte_pos == seiSparePicturePayload.payloadSize);
  399.     write_sei_message(AGGREGATION_SEI, seiSparePicturePayload.data->streamBuffer, seiSparePicturePayload.payloadSize, SEI_SPARE_PIC);
  400.     has_aggregation_sei_message = TRUE;
  401.   }
  402.   // write the sub sequence information sei paylaod to the aggregation sei message
  403.   if (seiHasSubseqInfo)
  404.   {
  405.     FinalizeSubseqInfo(img->layer);
  406.     write_sei_message(AGGREGATION_SEI, seiSubseqInfo[img->layer].data->streamBuffer, seiSubseqInfo[img->layer].payloadSize, SEI_SUB_SEQ_INFO);
  407.     ClearSubseqInfoPayload(img->layer);
  408.     has_aggregation_sei_message = TRUE;
  409.   }
  410.   // write the sub sequence layer information sei paylaod to the aggregation sei message
  411.   if (seiHasSubseqLayerInfo && img->number == 0)
  412.   {
  413.     FinalizeSubseqLayerInfo();
  414.     write_sei_message(AGGREGATION_SEI, seiSubseqLayerInfo.data, seiSubseqLayerInfo.payloadSize, SEI_SUB_SEQ_LAYER_CHARACTERISTICS);
  415.     seiHasSubseqLayerInfo = FALSE;
  416.     has_aggregation_sei_message = TRUE;
  417.   }
  418.   // write the sub sequence characteristics payload to the aggregation sei message
  419.   if (seiHasSubseqChar)
  420.   {
  421.     FinalizeSubseqChar();
  422.     write_sei_message(AGGREGATION_SEI, seiSubseqChar.data->streamBuffer, seiSubseqChar.payloadSize, SEI_SUB_SEQ_CHARACTERISTICS);
  423.     ClearSubseqCharPayload();
  424.     has_aggregation_sei_message = TRUE;
  425.   }
  426.   // write the pan scan rectangle info sei playload to the aggregation sei message
  427.   if (seiHasPanScanRectInfo)
  428.   {
  429.     FinalizePanScanRectInfo();
  430.     write_sei_message(AGGREGATION_SEI, seiPanScanRectInfo.data->streamBuffer, seiPanScanRectInfo.payloadSize, SEI_PAN_SCAN_RECT);
  431.     ClearPanScanRectInfoPayload();
  432.     has_aggregation_sei_message = TRUE;
  433.   }
  434.   // write the arbitrary (unregistered) info sei playload to the aggregation sei message
  435.   if (seiHasUser_data_unregistered_info)
  436.   {
  437.     FinalizeUser_data_unregistered();
  438.     write_sei_message(AGGREGATION_SEI, seiUser_data_unregistered.data->streamBuffer, seiUser_data_unregistered.payloadSize, SEI_USER_DATA_UNREGISTERED);
  439.     ClearUser_data_unregistered();
  440.     has_aggregation_sei_message = TRUE;
  441.   }
  442.   // write the arbitrary (unregistered) info sei playload to the aggregation sei message
  443.   if (seiHasUser_data_registered_itu_t_t35_info)
  444.   {
  445.     FinalizeUser_data_registered_itu_t_t35();
  446.     write_sei_message(AGGREGATION_SEI, seiUser_data_registered_itu_t_t35.data->streamBuffer, seiUser_data_registered_itu_t_t35.payloadSize, SEI_USER_DATA_REGISTERED_ITU_T_T35);
  447.     ClearUser_data_registered_itu_t_t35();
  448.     has_aggregation_sei_message = TRUE;
  449.   }
  450.   //write RandomAccess info sei payload to the aggregation sei message
  451.   if (seiHasRecoveryPoint_info)
  452.   {
  453.     FinalizeRandomAccess();
  454.     write_sei_message(AGGREGATION_SEI, seiRecoveryPoint.data->streamBuffer, seiRecoveryPoint.payloadSize, SEI_RECOVERY_POINT);
  455.     ClearRandomAccess();
  456.     has_aggregation_sei_message = TRUE;
  457.   }
  458.   // more aggregation sei payload is written here...
  459.   // write the scene information SEI payload
  460.   if (seiHasSceneInformation)
  461.   {
  462.     FinalizeSceneInformation();
  463.     write_sei_message(AGGREGATION_SEI, seiSceneInformation.data->streamBuffer, seiSceneInformation.payloadSize, SEI_SCENE_INFO);
  464.     has_aggregation_sei_message = TRUE;
  465.   }
  466.   if (seiHasTone_mapping)
  467.   {
  468.     FinalizeToneMapping();
  469.     write_sei_message(AGGREGATION_SEI, seiToneMapping.data->streamBuffer, seiToneMapping.payloadSize, SEI_TONE_MAPPING);
  470.     ClearToneMapping();
  471.     has_aggregation_sei_message = TRUE;
  472.   }
  473.   if (seiHasPostFilterHints_info)
  474.   {
  475.     FinalizePostFilterHints();
  476.     write_sei_message(AGGREGATION_SEI, seiPostFilterHints.data->streamBuffer, seiPostFilterHints.payloadSize, SEI_POST_FILTER_HINTS);
  477.     has_aggregation_sei_message = TRUE;
  478.   }
  479.   if (seiHasBuffering_period)
  480.   {
  481.     FinalizeBufferingPeriod();
  482.     write_sei_message(AGGREGATION_SEI, seiBufferingPeriod.data->streamBuffer, seiBufferingPeriod.payloadSize, SEI_BUFFERING_PERIOD);
  483.     has_aggregation_sei_message = TRUE;
  484.   }
  485.   if (seiHasPicTiming_info)
  486.   {
  487.     FinalizePicTiming();
  488.     write_sei_message(AGGREGATION_SEI, seiPicTiming.data->streamBuffer, seiPicTiming.payloadSize, SEI_PIC_TIMING);
  489.     has_aggregation_sei_message = TRUE;
  490.   }
  491.   // after all the sei payload is written
  492.   if (has_aggregation_sei_message)
  493.     finalize_sei_message(AGGREGATION_SEI);
  494. }
  495. #if 0
  496. /*!
  497.  *****************************************************************************
  498.  * begin_sub_sequence_rtp
  499.  * brief
  500.  *    do some initialization for sub-sequence under rtp
  501.  *
  502.  * date
  503.  *    September 10, 2002
  504.  *
  505.  * author
  506.  *    Dong Tian   tian@cs.tut.fi
  507.  *****************************************************************************/
  508. void begin_sub_sequence_rtp(void)
  509. {
  510.   if ( params->of_mode != PAR_OF_RTP || params->NumFramesInELSubSeq == 0 )
  511.     return;
  512.   // begin to encode the base layer subseq
  513.   if ( IMG_NUMBER == 0 )
  514.   {
  515. //    printf("begin to encode the base layer subseqn");
  516.     InitSubseqInfo(0);
  517.     if (1)
  518.       UpdateSubseqChar();
  519.   }
  520.   // begin to encode the enhanced layer subseq
  521.   if ( IMG_NUMBER % (params->NumFramesInELSubSeq+1) == 1 )
  522.   {
  523. //    printf("begin to encode the enhanced layer subseqn");
  524.     InitSubseqInfo(1);  // init the sub-sequence in the enhanced layer
  525. //    add_dependent_subseq(1);
  526.     if (1)
  527.       UpdateSubseqChar();
  528.   }
  529. }
  530. /*!
  531.  *****************************************************************************
  532.  * end_sub_sequence_rtp
  533.  * brief
  534.  *    do nothing
  535.  *
  536.  * date
  537.  *    September 10, 2002
  538.  *
  539.  * author
  540.  *    Dong Tian   tian@cs.tut.fi
  541.  *****************************************************************************/
  542. void end_sub_sequence_rtp(void)
  543. {
  544.   // end of the base layer:
  545.   if ( img->number == params->no_frames - 1 )
  546.   {
  547.     //    printf("end of encoding the base layer subseqn");
  548.     CloseSubseqInfo(0);
  549.     //    updateSubSequenceBox(0);
  550.   }
  551.   // end of the enhanced layer:
  552.   if ( ((IMG_NUMBER%(params->NumFramesInELSubSeq+1)==0) && (params->successive_Bframe != 0) && (IMG_NUMBER>0)) || // there are B frames
  553.     ((IMG_NUMBER%(params->NumFramesInELSubSeq+1)==params->NumFramesInELSubSeq) && (params->successive_Bframe==0))   // there are no B frames
  554.     )
  555.   {
  556.     //    printf("end of encoding the enhanced layer subseqn");
  557.     CloseSubseqInfo(1);
  558.     //    add_dependent_subseq(1);
  559.     //    updateSubSequenceBox(1);
  560.   }
  561. }
  562. #endif