gst_plugins_base/gst-libs/gst/rtp/gstrtpbuffer.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    67   unsigned int timestamp:32;    /* timestamp */
    67   unsigned int timestamp:32;    /* timestamp */
    68   unsigned int ssrc:32;         /* synchronization source */
    68   unsigned int ssrc:32;         /* synchronization source */
    69   guint8 csrclist[4];           /* optional CSRC list, 32 bits each */
    69   guint8 csrclist[4];           /* optional CSRC list, 32 bits each */
    70 } GstRTPHeader;
    70 } GstRTPHeader;
    71 
    71 
    72 #define GST_RTP_HEADER_VERSION(data)      (((GstRTPHeader *)(data))->version)
    72 #define GST_RTP_HEADER_VERSION(buf)     (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->version)
    73 #define GST_RTP_HEADER_PADDING(data)      (((GstRTPHeader *)(data))->padding)
    73 #define GST_RTP_HEADER_PADDING(buf)     (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->padding)
    74 #define GST_RTP_HEADER_EXTENSION(data)    (((GstRTPHeader *)(data))->extension)
    74 #define GST_RTP_HEADER_EXTENSION(buf)   (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->extension)
    75 #define GST_RTP_HEADER_CSRC_COUNT(data)   (((GstRTPHeader *)(data))->csrc_count)
    75 #define GST_RTP_HEADER_CSRC_COUNT(buf)  (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc_count)
    76 #define GST_RTP_HEADER_MARKER(data)       (((GstRTPHeader *)(data))->marker)
    76 #define GST_RTP_HEADER_MARKER(buf)      (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->marker)
    77 #define GST_RTP_HEADER_PAYLOAD_TYPE(data) (((GstRTPHeader *)(data))->payload_type)
    77 #define GST_RTP_HEADER_PAYLOAD_TYPE(buf)(((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->payload_type)
    78 #define GST_RTP_HEADER_SEQ(data)          (((GstRTPHeader *)(data))->seq)
    78 #define GST_RTP_HEADER_SEQ(buf)         (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->seq)
    79 #define GST_RTP_HEADER_TIMESTAMP(data)    (((GstRTPHeader *)(data))->timestamp)
    79 #define GST_RTP_HEADER_TIMESTAMP(buf)   (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->timestamp)
    80 #define GST_RTP_HEADER_SSRC(data)         (((GstRTPHeader *)(data))->ssrc)
    80 #define GST_RTP_HEADER_SSRC(buf)        (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->ssrc)
    81 #define GST_RTP_HEADER_CSRC_LIST_OFFSET(data,i)        \
    81 #define GST_RTP_HEADER_CSRC_LIST_OFFSET(buf,i)  \
    82     data + G_STRUCT_OFFSET(GstRTPHeader, csrclist) +   \
    82     GST_BUFFER_DATA (buf) +                     \
       
    83     G_STRUCT_OFFSET(GstRTPHeader, csrclist) +   \
    83     ((i) * sizeof(guint32))
    84     ((i) * sizeof(guint32))
    84 #define GST_RTP_HEADER_CSRC_SIZE(data)   (GST_RTP_HEADER_CSRC_COUNT(data) * sizeof (guint32))
    85 #define GST_RTP_HEADER_CSRC_SIZE(buf)   (GST_RTP_HEADER_CSRC_COUNT(buf) * sizeof (guint32))
    85 
    86 
    86 /**
    87 /**
    87  * gst_rtp_buffer_allocate_data:
    88  * gst_rtp_buffer_allocate_data:
    88  * @buffer: a #GstBuffer
    89  * @buffer: a #GstBuffer
    89  * @payload_len: the length of the payload
    90  * @payload_len: the length of the payload
   102 void
   103 void
   103 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
   104 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
   104     guint8 pad_len, guint8 csrc_count)
   105     guint8 pad_len, guint8 csrc_count)
   105 {
   106 {
   106   guint len;
   107   guint len;
   107   guint8 *data;
       
   108 
   108 
   109   g_return_if_fail (csrc_count <= 15);
   109   g_return_if_fail (csrc_count <= 15);
   110   g_return_if_fail (GST_IS_BUFFER (buffer));
   110   g_return_if_fail (GST_IS_BUFFER (buffer));
   111 
   111 
   112   len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
   112   len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
   113       + payload_len + pad_len;
   113       + payload_len + pad_len;
   114 
   114 
   115   data = g_malloc (len);
   115   GST_BUFFER_MALLOCDATA (buffer) = g_malloc (len);
   116   GST_BUFFER_MALLOCDATA (buffer) = data;
   116   GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
   117   GST_BUFFER_DATA (buffer) = data;
       
   118   GST_BUFFER_SIZE (buffer) = len;
   117   GST_BUFFER_SIZE (buffer) = len;
   119 
   118 
   120   /* fill in defaults */
   119   /* fill in defaults */
   121   GST_RTP_HEADER_VERSION (data) = GST_RTP_VERSION;
   120   GST_RTP_HEADER_VERSION (buffer) = GST_RTP_VERSION;
   122   GST_RTP_HEADER_PADDING (data) = FALSE;
   121   GST_RTP_HEADER_PADDING (buffer) = FALSE;
   123   GST_RTP_HEADER_EXTENSION (data) = FALSE;
   122   GST_RTP_HEADER_EXTENSION (buffer) = FALSE;
   124   GST_RTP_HEADER_CSRC_COUNT (data) = csrc_count;
   123   GST_RTP_HEADER_CSRC_COUNT (buffer) = csrc_count;
   125   memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, 0), 0,
   124   memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, 0), 0,
   126       csrc_count * sizeof (guint32));
   125       csrc_count * sizeof (guint32));
   127   GST_RTP_HEADER_MARKER (data) = FALSE;
   126   GST_RTP_HEADER_MARKER (buffer) = FALSE;
   128   GST_RTP_HEADER_PAYLOAD_TYPE (data) = 0;
   127   GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = 0;
   129   GST_RTP_HEADER_SEQ (data) = 0;
   128   GST_RTP_HEADER_SEQ (buffer) = 0;
   130   GST_RTP_HEADER_TIMESTAMP (data) = 0;
   129   GST_RTP_HEADER_TIMESTAMP (buffer) = 0;
   131   GST_RTP_HEADER_SSRC (data) = 0;
   130   GST_RTP_HEADER_SSRC (buffer) = 0;
   132 }
   131 }
   133 
   132 
   134 /**
   133 /**
   135  * gst_rtp_buffer_new_take_data:
   134  * gst_rtp_buffer_new_take_data:
   136  * @data: data for the new buffer
   135  * @data: data for the new buffer
   315   return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
   314   return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
   316       - pad_len;
   315       - pad_len;
   317 }
   316 }
   318 
   317 
   319 /**
   318 /**
   320  * validate_data:
   319  * gst_rtp_buffer_validate_data:
   321  * @data: the data to validate
   320  * @data: the data to validate
   322  * @len: the length of @data to validate
   321  * @len: the length of @data to validate
   323  * @payload: the payload if @data represents the header only
   322  *
   324  * @payload_len: the len of the payload
   323  * Check if the @data and @size point to the data of a valid RTP packet.
   325  *
   324  * This function checks the length, version and padding of the packet data.
   326  * Checks if @data is a valid RTP packet.
   325  * Use this function to validate a packet before using the other functions in
   327  *
   326  * this module.
   328  * Returns: TRUE if @data is a valid RTP packet
   327  *
   329  */
   328  * Returns: TRUE if the data points to a valid RTP packet.
   330 static gboolean
   329  */
   331 validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len)
   330 #ifdef __SYMBIAN32__
       
   331 EXPORT_C
       
   332 #endif
       
   333 
       
   334 gboolean
       
   335 gst_rtp_buffer_validate_data (guint8 * data, guint len)
   332 {
   336 {
   333   guint8 padding;
   337   guint8 padding;
   334   guint8 csrc_count;
   338   guint8 csrc_count;
   335   guint header_len;
   339   guint header_len;
   336   guint8 version;
   340   guint8 version;
   340   header_len = GST_RTP_HEADER_LEN;
   344   header_len = GST_RTP_HEADER_LEN;
   341   if (G_UNLIKELY (len < header_len))
   345   if (G_UNLIKELY (len < header_len))
   342     goto wrong_length;
   346     goto wrong_length;
   343 
   347 
   344   /* check version */
   348   /* check version */
   345   version = (data[0] & 0xc0);
   349   version = (data[0] & 0xc0) >> 6;
   346   if (G_UNLIKELY (version != (GST_RTP_VERSION << 6)))
   350   if (G_UNLIKELY (version != GST_RTP_VERSION))
   347     goto wrong_version;
   351     goto wrong_version;
   348 
   352 
   349   /* calc header length with csrc */
   353   /* calc header length with csrc */
   350   csrc_count = (data[0] & 0x0f);
   354   csrc_count = (data[0] & 0x0f);
   351   header_len += csrc_count * sizeof (guint32);
   355   header_len += csrc_count * sizeof (guint32);
   370 
   374 
   371     header_len += extlen * sizeof (guint32);
   375     header_len += extlen * sizeof (guint32);
   372   }
   376   }
   373 
   377 
   374   /* check for padding */
   378   /* check for padding */
   375   if (data[0] & 0x20) {
   379   if (data[0] & 0x20)
   376     if (payload)
   380     padding = data[len - 1];
   377       padding = payload[payload_len - 1];
   381   else
   378     else
       
   379       padding = data[len - 1];
       
   380   } else {
       
   381     padding = 0;
   382     padding = 0;
   382   }
   383 
   383 
   384   /* check if padding not bigger than packet and header */
   384   /* check if padding and header not bigger than packet length */
   385   if (G_UNLIKELY (len - header_len < padding))
   385   if (G_UNLIKELY (len < padding + header_len))
       
   386     goto wrong_padding;
   386     goto wrong_padding;
   387 
   387 
   388   return TRUE;
   388   return TRUE;
   389 
   389 
   390   /* ERRORS */
   390   /* ERRORS */
   404     return FALSE;
   404     return FALSE;
   405   }
   405   }
   406 }
   406 }
   407 
   407 
   408 /**
   408 /**
   409  * gst_rtp_buffer_validate_data:
       
   410  * @data: the data to validate
       
   411  * @len: the length of @data to validate
       
   412  *
       
   413  * Check if the @data and @size point to the data of a valid RTP packet.
       
   414  * This function checks the length, version and padding of the packet data.
       
   415  * Use this function to validate a packet before using the other functions in
       
   416  * this module.
       
   417  *
       
   418  * Returns: TRUE if the data points to a valid RTP packet.
       
   419  */
       
   420 #ifdef __SYMBIAN32__
       
   421 EXPORT_C
       
   422 #endif
       
   423 
       
   424 gboolean
       
   425 gst_rtp_buffer_validate_data (guint8 * data, guint len)
       
   426 {
       
   427   return validate_data (data, len, NULL, 0);
       
   428 }
       
   429 
       
   430 /**
       
   431  * gst_rtp_buffer_validate:
   409  * gst_rtp_buffer_validate:
   432  * @buffer: the buffer to validate
   410  * @buffer: the buffer to validate
   433  *
   411  *
   434  * Check if the data pointed to by @buffer is a valid RTP packet using
   412  * Check if the data pointed to by @buffer is a valid RTP packet using
   435  * validate_data().
   413  * gst_rtp_buffer_validate_data().
   436  * Use this function to validate a packet before using the other functions in
       
   437  * this module.
       
   438  *
   414  *
   439  * Returns: TRUE if @buffer is a valid RTP packet.
   415  * Returns: TRUE if @buffer is a valid RTP packet.
   440  */
   416  */
   441 #ifdef __SYMBIAN32__
   417 #ifdef __SYMBIAN32__
   442 EXPORT_C
   418 EXPORT_C
   451   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
   427   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
   452 
   428 
   453   data = GST_BUFFER_DATA (buffer);
   429   data = GST_BUFFER_DATA (buffer);
   454   len = GST_BUFFER_SIZE (buffer);
   430   len = GST_BUFFER_SIZE (buffer);
   455 
   431 
   456   return validate_data (data, len, NULL, 0);
   432   return gst_rtp_buffer_validate_data (data, len);
   457 }
       
   458 
       
   459 /**
       
   460  * gst_rtp_buffer_list_validate:
       
   461  * @list: the buffer list to validate
       
   462  *
       
   463  * Check if all RTP packets in the @list are valid using validate_data().
       
   464  * Use this function to validate an list before using the other functions in
       
   465  * this module.
       
   466  *
       
   467  * Returns: TRUE if @list consists only of valid RTP packets.
       
   468  *
       
   469  * Since: 0.10.24
       
   470  */
       
   471  
       
   472  #ifdef __SYMBIAN32__
       
   473 EXPORT_C
       
   474 #endif
       
   475 
       
   476 gboolean
       
   477 gst_rtp_buffer_list_validate (GstBufferList * list)
       
   478 {
       
   479   guint16 prev_seqnum = 0;
       
   480   GstBufferListIterator *it;
       
   481   guint i = 0;
       
   482 
       
   483   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
       
   484 
       
   485   it = gst_buffer_list_iterate (list);
       
   486   g_return_val_if_fail (it != NULL, FALSE);
       
   487 
       
   488   /* iterate through all the RTP packets in the list */
       
   489   while (gst_buffer_list_iterator_next_group (it)) {
       
   490     GstBuffer *rtpbuf;
       
   491     GstBuffer *paybuf;
       
   492     guint8 *packet_header;
       
   493     guint8 *packet_payload;
       
   494     guint payload_size;
       
   495     guint packet_size;
       
   496 
       
   497     /* each group should consists of 2 buffers: one containing the RTP header
       
   498      * and the other one the payload, FIXME, relax the requirement of only one
       
   499      * payload buffer. */
       
   500     if (gst_buffer_list_iterator_n_buffers (it) != 2)
       
   501       goto invalid_list;
       
   502 
       
   503     /* get the RTP header */
       
   504     rtpbuf = gst_buffer_list_iterator_next (it);
       
   505     packet_header = GST_BUFFER_DATA (rtpbuf);
       
   506     if (packet_header == NULL)
       
   507       goto invalid_list;
       
   508 
       
   509     /* get the payload */
       
   510     paybuf = gst_buffer_list_iterator_next (it);
       
   511     packet_payload = GST_BUFFER_DATA (paybuf);
       
   512     if (packet_payload == NULL) {
       
   513       goto invalid_list;
       
   514     }
       
   515     payload_size = GST_BUFFER_SIZE (paybuf);
       
   516     if (payload_size == 0) {
       
   517       goto invalid_list;
       
   518     }
       
   519 
       
   520     /* the size of the RTP packet within the current group */
       
   521     packet_size = GST_BUFFER_SIZE (rtpbuf) + payload_size;
       
   522 
       
   523     /* check the sequence number */
       
   524     if (G_UNLIKELY (i == 0)) {
       
   525       prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header));
       
   526       i++;
       
   527     } else {
       
   528       if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header)))
       
   529         goto invalid_list;
       
   530     }
       
   531 
       
   532     /* validate packet */
       
   533     if (!validate_data (packet_header, packet_size, packet_payload,
       
   534             payload_size)) {
       
   535       goto invalid_list;
       
   536     }
       
   537   }
       
   538 
       
   539   gst_buffer_list_iterator_free (it);
       
   540 
       
   541   return TRUE;
       
   542 
       
   543   /* ERRORS */
       
   544 invalid_list:
       
   545   {
       
   546     gst_buffer_list_iterator_free (it);
       
   547     return FALSE;
       
   548   }
       
   549 }
   433 }
   550 
   434 
   551 /**
   435 /**
   552  * gst_rtp_buffer_set_packet_len:
   436  * gst_rtp_buffer_set_packet_len:
   553  * @buffer: the buffer
   437  * @buffer: the buffer
   562 
   446 
   563 void
   447 void
   564 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
   448 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
   565 {
   449 {
   566   guint oldlen;
   450   guint oldlen;
   567   guint8 *data;
   451 
       
   452   g_return_if_fail (GST_IS_BUFFER (buffer));
   568 
   453 
   569   oldlen = GST_BUFFER_SIZE (buffer);
   454   oldlen = GST_BUFFER_SIZE (buffer);
   570   data = GST_BUFFER_DATA (buffer);
       
   571 
   455 
   572   if (oldlen < len) {
   456   if (oldlen < len) {
   573     data = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
   457     guint8 *newdata;
   574     GST_BUFFER_MALLOCDATA (buffer) = data;
   458 
   575     GST_BUFFER_DATA (buffer) = data;
   459     newdata = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
       
   460     GST_BUFFER_MALLOCDATA (buffer) = newdata;
       
   461     GST_BUFFER_DATA (buffer) = newdata;
   576   }
   462   }
   577   GST_BUFFER_SIZE (buffer) = len;
   463   GST_BUFFER_SIZE (buffer) = len;
   578 
   464 
   579   /* remove any padding */
   465   /* remove any padding */
   580   GST_RTP_HEADER_PADDING (data) = FALSE;
   466   GST_RTP_HEADER_PADDING (buffer) = FALSE;
   581 }
   467 }
   582 
   468 
   583 /**
   469 /**
   584  * gst_rtp_buffer_get_packet_len:
   470  * gst_rtp_buffer_get_packet_len:
   585  * @buffer: the buffer
   471  * @buffer: the buffer
   593 #endif
   479 #endif
   594 
   480 
   595 guint
   481 guint
   596 gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
   482 gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
   597 {
   483 {
       
   484   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
       
   485 
   598   return GST_BUFFER_SIZE (buffer);
   486   return GST_BUFFER_SIZE (buffer);
   599 }
   487 }
   600 
   488 
   601 /**
   489 /**
   602  * gst_rtp_buffer_get_header_len:
   490  * gst_rtp_buffer_get_header_len:
   613 
   501 
   614 guint
   502 guint
   615 gst_rtp_buffer_get_header_len (GstBuffer * buffer)
   503 gst_rtp_buffer_get_header_len (GstBuffer * buffer)
   616 {
   504 {
   617   guint len;
   505   guint len;
   618   guint8 *data;
   506 
   619 
   507   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
   620   data = GST_BUFFER_DATA (buffer);
   508 
   621 
   509   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer);
   622   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
   510   if (GST_RTP_HEADER_EXTENSION (buffer))
   623   if (GST_RTP_HEADER_EXTENSION (data))
   511     len += GST_READ_UINT16_BE (GST_BUFFER_DATA (buffer) + len + 2) * 4 + 4;
   624     len += GST_READ_UINT16_BE (data + len + 2) * 4 + 4;
       
   625 
   512 
   626   return len;
   513   return len;
   627 }
   514 }
   628 
   515 
   629 /**
   516 /**
   639 #endif
   526 #endif
   640 
   527 
   641 guint8
   528 guint8
   642 gst_rtp_buffer_get_version (GstBuffer * buffer)
   529 gst_rtp_buffer_get_version (GstBuffer * buffer)
   643 {
   530 {
   644   return GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer));
   531   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
       
   532   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
       
   533 
       
   534   return GST_RTP_HEADER_VERSION (buffer);
   645 }
   535 }
   646 
   536 
   647 /**
   537 /**
   648  * gst_rtp_buffer_set_version:
   538  * gst_rtp_buffer_set_version:
   649  * @buffer: the buffer
   539  * @buffer: the buffer
   656 #endif
   546 #endif
   657 
   547 
   658 void
   548 void
   659 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
   549 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
   660 {
   550 {
       
   551   g_return_if_fail (GST_IS_BUFFER (buffer));
   661   g_return_if_fail (version < 0x04);
   552   g_return_if_fail (version < 0x04);
   662 
   553   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
   663   GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer)) = version;
   554 
       
   555   GST_RTP_HEADER_VERSION (buffer) = version;
   664 }
   556 }
   665 
   557 
   666 /**
   558 /**
   667  * gst_rtp_buffer_get_padding:
   559  * gst_rtp_buffer_get_padding:
   668  * @buffer: the buffer
   560  * @buffer: the buffer
   676 #endif
   568 #endif
   677 
   569 
   678 gboolean
   570 gboolean
   679 gst_rtp_buffer_get_padding (GstBuffer * buffer)
   571 gst_rtp_buffer_get_padding (GstBuffer * buffer)
   680 {
   572 {
   681   return GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer));
   573   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
       
   574   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
       
   575 
       
   576   return GST_RTP_HEADER_PADDING (buffer);
   682 }
   577 }
   683 
   578 
   684 /**
   579 /**
   685  * gst_rtp_buffer_set_padding:
   580  * gst_rtp_buffer_set_padding:
   686  * @buffer: the buffer
   581  * @buffer: the buffer
   693 #endif
   588 #endif
   694 
   589 
   695 void
   590 void
   696 gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
   591 gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
   697 {
   592 {
   698   GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer)) = padding;
   593   g_return_if_fail (GST_IS_BUFFER (buffer));
       
   594   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
       
   595 
       
   596   GST_RTP_HEADER_PADDING (buffer) = padding;
   699 }
   597 }
   700 
   598 
   701 /**
   599 /**
   702  * gst_rtp_buffer_pad_to:
   600  * gst_rtp_buffer_pad_to:
   703  * @buffer: the buffer
   601  * @buffer: the buffer
   713 #endif
   611 #endif
   714 
   612 
   715 void
   613 void
   716 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
   614 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
   717 {
   615 {
   718   guint8 *data;
   616   g_return_if_fail (GST_IS_BUFFER (buffer));
   719 
   617   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
   720   data = GST_BUFFER_DATA (buffer);
       
   721 
   618 
   722   if (len > 0)
   619   if (len > 0)
   723     GST_RTP_HEADER_PADDING (data) = TRUE;
   620     GST_RTP_HEADER_PADDING (buffer) = TRUE;
   724   else
   621   else
   725     GST_RTP_HEADER_PADDING (data) = FALSE;
   622     GST_RTP_HEADER_PADDING (buffer) = FALSE;
   726 
   623 
   727   /* FIXME, set the padding byte at the end of the payload data */
   624   /* FIXME, set the padding byte at the end of the payload data */
   728 }
   625 }
   729 
   626 
   730 /**
   627 /**
   740 #endif
   637 #endif
   741 
   638 
   742 gboolean
   639 gboolean
   743 gst_rtp_buffer_get_extension (GstBuffer * buffer)
   640 gst_rtp_buffer_get_extension (GstBuffer * buffer)
   744 {
   641 {
   745   return GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer));
   642   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
       
   643   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
       
   644 
       
   645   return GST_RTP_HEADER_EXTENSION (buffer);
   746 }
   646 }
   747 
   647 
   748 /**
   648 /**
   749  * gst_rtp_buffer_set_extension:
   649  * gst_rtp_buffer_set_extension:
   750  * @buffer: the buffer
   650  * @buffer: the buffer
   757 #endif
   657 #endif
   758 
   658 
   759 void
   659 void
   760 gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
   660 gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
   761 {
   661 {
   762   GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer)) = extension;
   662   g_return_if_fail (GST_IS_BUFFER (buffer));
       
   663   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
       
   664 
       
   665   GST_RTP_HEADER_EXTENSION (buffer) = extension;
   763 }
   666 }
   764 
   667 
   765 /**
   668 /**
   766  * gst_rtp_buffer_get_extension_data:
   669  * gst_rtp_buffer_get_extension_data:
   767  * @buffer: the buffer
   670  * @buffer: the buffer
   789     gpointer * data, guint * wordlen)
   692     gpointer * data, guint * wordlen)
   790 {
   693 {
   791   guint len;
   694   guint len;
   792   guint8 *pdata;
   695   guint8 *pdata;
   793 
   696 
   794   pdata = GST_BUFFER_DATA (buffer);
   697   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
   795 
   698   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
   796   if (!GST_RTP_HEADER_EXTENSION (pdata))
   699 
       
   700   if (!GST_RTP_HEADER_EXTENSION (buffer))
   797     return FALSE;
   701     return FALSE;
   798 
   702 
   799   /* move to the extension */
   703   /* move to the extension */
   800   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata);
   704   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer);
   801   pdata += len;
   705   pdata = GST_BUFFER_DATA (buffer) + len;
   802 
   706 
   803   if (bits)
   707   if (bits)
   804     *bits = GST_READ_UINT16_BE (pdata);
   708     *bits = GST_READ_UINT16_BE (pdata);
   805   if (wordlen)
   709   if (wordlen)
   806     *wordlen = GST_READ_UINT16_BE (pdata + 2);
   710     *wordlen = GST_READ_UINT16_BE (pdata + 2);
   834     guint16 length)
   738     guint16 length)
   835 {
   739 {
   836   guint32 min_size = 0;
   740   guint32 min_size = 0;
   837   guint8 *data;
   741   guint8 *data;
   838 
   742 
   839   data = GST_BUFFER_DATA (buffer);
   743   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
   840 
   744   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
   841   /* check if the buffer is big enough to hold the extension */
   745 
       
   746   gst_rtp_buffer_set_extension (buffer, TRUE);
   842   min_size =
   747   min_size =
   843       GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 +
   748       GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer) + 4 +
   844       length * sizeof (guint32);
   749       length * sizeof (guint32);
   845   if (G_UNLIKELY (min_size > GST_BUFFER_SIZE (buffer)))
   750 
   846     goto too_small;
   751   if (min_size > GST_BUFFER_SIZE (buffer)) {
   847 
   752     GST_WARNING_OBJECT (buffer,
   848   /* now we can set the extension bit */
   753         "rtp buffer too small: need more than %d bytes but only have %d bytes",
   849   gst_rtp_buffer_set_extension (buffer, TRUE);
       
   850 
       
   851   data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
       
   852   GST_WRITE_UINT16_BE (data, bits);
       
   853   GST_WRITE_UINT16_BE (data + 2, length);
       
   854 
       
   855   return TRUE;
       
   856 
       
   857   /* ERRORS */
       
   858 too_small:
       
   859   {
       
   860     g_warning
       
   861         ("rtp buffer too small: need more than %d bytes but only have %d bytes",
       
   862         min_size, GST_BUFFER_SIZE (buffer));
   754         min_size, GST_BUFFER_SIZE (buffer));
   863     return FALSE;
   755     return FALSE;
   864   }
   756   }
       
   757 
       
   758   data =
       
   759       GST_BUFFER_DATA (buffer) + GST_RTP_HEADER_LEN +
       
   760       GST_RTP_HEADER_CSRC_SIZE (buffer);
       
   761   GST_WRITE_UINT16_BE (data, bits);
       
   762   GST_WRITE_UINT16_BE (data + 2, length);
       
   763   return TRUE;
   865 }
   764 }
   866 
   765 
   867 /**
   766 /**
   868  * gst_rtp_buffer_get_ssrc:
   767  * gst_rtp_buffer_get_ssrc:
   869  * @buffer: the buffer
   768  * @buffer: the buffer
   877 #endif
   776 #endif
   878 
   777 
   879 guint32
   778 guint32
   880 gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
   779 gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
   881 {
   780 {
   882   return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
   781   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
   883 }
   782   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
   884 
   783 
   885 /**
   784   return g_ntohl (GST_RTP_HEADER_SSRC (buffer));
   886  * gst_rtp_buffer_list_get_ssrc:
       
   887  * @list: the buffer list
       
   888  *
       
   889  * Get the SSRC of the first RTP packet in @list.
       
   890  * All RTP packets within @list have the same SSRC.
       
   891  *
       
   892  * Returns: the SSRC of @list in host order.
       
   893  *
       
   894  * Since: 0.10.24
       
   895  */
       
   896  
       
   897  #ifdef __SYMBIAN32__
       
   898 EXPORT_C
       
   899 #endif
       
   900 
       
   901 guint32
       
   902 gst_rtp_buffer_list_get_ssrc (GstBufferList * list)
       
   903 {
       
   904   GstBuffer *buffer;
       
   905 
       
   906   buffer = gst_buffer_list_get (list, 0, 0);
       
   907   g_return_val_if_fail (buffer != NULL, 0);
       
   908 
       
   909   return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
       
   910 }
   785 }
   911 
   786 
   912 /**
   787 /**
   913  * gst_rtp_buffer_set_ssrc:
   788  * gst_rtp_buffer_set_ssrc:
   914  * @buffer: the buffer
   789  * @buffer: the buffer
   921 #endif
   796 #endif
   922 
   797 
   923 void
   798 void
   924 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
   799 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
   925 {
   800 {
   926   GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)) = g_htonl (ssrc);
   801   g_return_if_fail (GST_IS_BUFFER (buffer));
   927 }
   802   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
   928 
   803 
   929 static GstBufferListItem
   804   GST_RTP_HEADER_SSRC (buffer) = g_htonl (ssrc);
   930 set_ssrc_header (GstBuffer ** buffer, guint group, guint idx, guint32 * ssrc)
       
   931 {
       
   932   GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (*buffer)) = g_htonl (*ssrc);
       
   933   return GST_BUFFER_LIST_SKIP_GROUP;
       
   934 }
       
   935 
       
   936 /**
       
   937  * gst_rtp_buffer_list_set_ssrc:
       
   938  * @list: the buffer list
       
   939  * @ssrc: the new SSRC
       
   940  *
       
   941  * Set the SSRC on each RTP packet in @list to @ssrc.
       
   942  *
       
   943  * Since: 0.10.24
       
   944  */
       
   945 #ifdef __SYMBIAN32__
       
   946 EXPORT_C
       
   947 #endif
       
   948 void
       
   949 gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc)
       
   950 {
       
   951   gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc);
       
   952 }
   805 }
   953 
   806 
   954 /**
   807 /**
   955  * gst_rtp_buffer_get_csrc_count:
   808  * gst_rtp_buffer_get_csrc_count:
   956  * @buffer: the buffer
   809  * @buffer: the buffer
   964 #endif
   817 #endif
   965 
   818 
   966 guint8
   819 guint8
   967 gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
   820 gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
   968 {
   821 {
   969   return GST_RTP_HEADER_CSRC_COUNT (GST_BUFFER_DATA (buffer));
   822   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
       
   823   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
       
   824 
       
   825   return GST_RTP_HEADER_CSRC_COUNT (buffer);
   970 }
   826 }
   971 
   827 
   972 /**
   828 /**
   973  * gst_rtp_buffer_get_csrc:
   829  * gst_rtp_buffer_get_csrc:
   974  * @buffer: the buffer
   830  * @buffer: the buffer
   983 #endif
   839 #endif
   984 
   840 
   985 guint32
   841 guint32
   986 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
   842 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
   987 {
   843 {
   988   guint8 *data;
   844   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
   989 
   845   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
   990   data = GST_BUFFER_DATA (buffer);
   846   g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer), 0);
   991 
   847 
   992   g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
   848   return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx));
   993 
       
   994   return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx));
       
   995 }
   849 }
   996 
   850 
   997 /**
   851 /**
   998  * gst_rtp_buffer_set_csrc:
   852  * gst_rtp_buffer_set_csrc:
   999  * @buffer: the buffer
   853  * @buffer: the buffer
  1007 #endif
   861 #endif
  1008 
   862 
  1009 void
   863 void
  1010 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
   864 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
  1011 {
   865 {
  1012   guint8 *data;
   866   g_return_if_fail (GST_IS_BUFFER (buffer));
  1013 
   867   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
  1014   data = GST_BUFFER_DATA (buffer);
   868   g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer));
  1015 
   869 
  1016   g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
   870   GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx), csrc);
  1017 
       
  1018   GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
       
  1019 }
   871 }
  1020 
   872 
  1021 /**
   873 /**
  1022  * gst_rtp_buffer_get_marker:
   874  * gst_rtp_buffer_get_marker:
  1023  * @buffer: the buffer
   875  * @buffer: the buffer
  1031 #endif
   883 #endif
  1032 
   884 
  1033 gboolean
   885 gboolean
  1034 gst_rtp_buffer_get_marker (GstBuffer * buffer)
   886 gst_rtp_buffer_get_marker (GstBuffer * buffer)
  1035 {
   887 {
  1036   return GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer));
   888   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
       
   889   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
       
   890 
       
   891   return GST_RTP_HEADER_MARKER (buffer);
  1037 }
   892 }
  1038 
   893 
  1039 /**
   894 /**
  1040  * gst_rtp_buffer_set_marker:
   895  * gst_rtp_buffer_set_marker:
  1041  * @buffer: the buffer
   896  * @buffer: the buffer
  1048 #endif
   903 #endif
  1049 
   904 
  1050 void
   905 void
  1051 gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
   906 gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
  1052 {
   907 {
  1053   GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer)) = marker;
   908   g_return_if_fail (GST_IS_BUFFER (buffer));
       
   909   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
       
   910 
       
   911   GST_RTP_HEADER_MARKER (buffer) = marker;
  1054 }
   912 }
  1055 
   913 
  1056 /**
   914 /**
  1057  * gst_rtp_buffer_get_payload_type:
   915  * gst_rtp_buffer_get_payload_type:
  1058  * @buffer: the buffer
   916  * @buffer: the buffer
  1066 #endif
   924 #endif
  1067 
   925 
  1068 guint8
   926 guint8
  1069 gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
   927 gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
  1070 {
   928 {
  1071   return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
   929   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
  1072 }
   930   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
  1073 
   931 
  1074 /**
   932   return GST_RTP_HEADER_PAYLOAD_TYPE (buffer);
  1075  * gst_rtp_buffer_list_get_payload_type:
       
  1076  * @list: the buffer list
       
  1077  *
       
  1078  * Get the payload type of the first RTP packet in @list.
       
  1079  * All packets in @list should have the same payload type.
       
  1080  *
       
  1081  * Returns: The payload type.
       
  1082  *
       
  1083  * Since: 0.10.24
       
  1084  */
       
  1085  
       
  1086  #ifdef __SYMBIAN32__
       
  1087 EXPORT_C
       
  1088 #endif
       
  1089 
       
  1090 guint8
       
  1091 gst_rtp_buffer_list_get_payload_type (GstBufferList * list)
       
  1092 {
       
  1093   GstBuffer *buffer;
       
  1094 
       
  1095   buffer = gst_buffer_list_get (list, 0, 0);
       
  1096   g_return_val_if_fail (buffer != NULL, 0);
       
  1097 
       
  1098   return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
       
  1099 }
   933 }
  1100 
   934 
  1101 /**
   935 /**
  1102  * gst_rtp_buffer_set_payload_type:
   936  * gst_rtp_buffer_set_payload_type:
  1103  * @buffer: the buffer
   937  * @buffer: the buffer
  1110 #endif
   944 #endif
  1111 
   945 
  1112 void
   946 void
  1113 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
   947 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
  1114 {
   948 {
       
   949   g_return_if_fail (GST_IS_BUFFER (buffer));
       
   950   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
  1115   g_return_if_fail (payload_type < 0x80);
   951   g_return_if_fail (payload_type < 0x80);
  1116 
   952 
  1117   GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)) = payload_type;
   953   GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = payload_type;
  1118 }
       
  1119 
       
  1120 static GstBufferListItem
       
  1121 set_pt_header (GstBuffer ** buffer, guint group, guint idx, guint8 * pt)
       
  1122 {
       
  1123   GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (*buffer)) = *pt;
       
  1124   return GST_BUFFER_LIST_SKIP_GROUP;
       
  1125 }
       
  1126 
       
  1127 /**
       
  1128  * gst_rtp_buffer_list_set_payload_type:
       
  1129  * @list: the buffer list
       
  1130  * @payload_type: the new type
       
  1131  *
       
  1132  * Set the payload type of each RTP packet in @list to @payload_type.
       
  1133  *
       
  1134  * Since: 0.10.24
       
  1135  */
       
  1136  
       
  1137 #ifdef __SYMBIAN32__
       
  1138 EXPORT_C
       
  1139 #endif
       
  1140  
       
  1141 void
       
  1142 gst_rtp_buffer_list_set_payload_type (GstBufferList * list, guint8 payload_type)
       
  1143 {
       
  1144   g_return_if_fail (payload_type < 0x80);
       
  1145 
       
  1146   gst_buffer_list_foreach (list, (GstBufferListFunc) set_pt_header,
       
  1147       &payload_type);
       
  1148 }
   954 }
  1149 
   955 
  1150 /**
   956 /**
  1151  * gst_rtp_buffer_get_seq:
   957  * gst_rtp_buffer_get_seq:
  1152  * @buffer: the buffer
   958  * @buffer: the buffer
  1160 #endif
   966 #endif
  1161 
   967 
  1162 guint16
   968 guint16
  1163 gst_rtp_buffer_get_seq (GstBuffer * buffer)
   969 gst_rtp_buffer_get_seq (GstBuffer * buffer)
  1164 {
   970 {
  1165   return g_ntohs (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
   971   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
       
   972   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
       
   973 
       
   974   return g_ntohs (GST_RTP_HEADER_SEQ (buffer));
  1166 }
   975 }
  1167 
   976 
  1168 /**
   977 /**
  1169  * gst_rtp_buffer_set_seq:
   978  * gst_rtp_buffer_set_seq:
  1170  * @buffer: the buffer
   979  * @buffer: the buffer
  1177 #endif
   986 #endif
  1178 
   987 
  1179 void
   988 void
  1180 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
   989 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
  1181 {
   990 {
  1182   GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)) = g_htons (seq);
   991   g_return_if_fail (GST_IS_BUFFER (buffer));
  1183 }
   992   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
  1184 
   993 
  1185 static GstBufferListItem
   994   GST_RTP_HEADER_SEQ (buffer) = g_htons (seq);
  1186 set_seq_header (GstBuffer ** buffer, guint group, guint idx, guint16 * seq)
   995 }
  1187 {
       
  1188   GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (*buffer)) = g_htons (*seq);
       
  1189   (*seq)++;
       
  1190   return GST_BUFFER_LIST_SKIP_GROUP;
       
  1191 }
       
  1192 
       
  1193 /**
       
  1194  * gst_rtp_buffer_list_set_seq:
       
  1195  * @list: the buffer list
       
  1196  * @seq: the new sequence number
       
  1197  *
       
  1198  * Set the sequence number of each RTP packet in @list to @seq.
       
  1199  *
       
  1200  * Returns: The seq number of the last packet in the list + 1.
       
  1201  *
       
  1202  * Since: 0.10.24
       
  1203  */
       
  1204  
       
  1205  #ifdef __SYMBIAN32__
       
  1206 EXPORT_C
       
  1207 #endif
       
  1208 
       
  1209 guint16
       
  1210 gst_rtp_buffer_list_set_seq (GstBufferList * list, guint16 seq)
       
  1211 {
       
  1212   gst_buffer_list_foreach (list, (GstBufferListFunc) set_seq_header, &seq);
       
  1213   return seq;
       
  1214 }
       
  1215 
       
  1216 /**
       
  1217  * gst_rtp_buffer_list_get_seq:
       
  1218  * @list: the buffer list
       
  1219  *
       
  1220  * Get the sequence number of the first RTP packet in @list.
       
  1221  * All packets within @list have the same sequence number.
       
  1222  *
       
  1223  * Returns: The seq number
       
  1224  *
       
  1225  * Since: 0.10.24
       
  1226  */
       
  1227  
       
  1228 #ifdef __SYMBIAN32__
       
  1229 EXPORT_C
       
  1230 #endif
       
  1231  
       
  1232 guint16
       
  1233 gst_rtp_buffer_list_get_seq (GstBufferList * list)
       
  1234 {
       
  1235   GstBuffer *buffer;
       
  1236 
       
  1237   buffer = gst_buffer_list_get (list, 0, 0);
       
  1238   g_return_val_if_fail (buffer != NULL, 0);
       
  1239 
       
  1240   return g_ntohl (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
       
  1241 }
       
  1242 
       
  1243 
   996 
  1244 /**
   997 /**
  1245  * gst_rtp_buffer_get_timestamp:
   998  * gst_rtp_buffer_get_timestamp:
  1246  * @buffer: the buffer
   999  * @buffer: the buffer
  1247  *
  1000  *
  1254 #endif
  1007 #endif
  1255 
  1008 
  1256 guint32
  1009 guint32
  1257 gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
  1010 gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
  1258 {
  1011 {
  1259   return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
  1012   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
  1260 }
  1013   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
  1261 
  1014 
  1262 /**
  1015   return g_ntohl (GST_RTP_HEADER_TIMESTAMP (buffer));
  1263  * gst_rtp_buffer_list_get_timestamp:
       
  1264  * @list: the buffer list
       
  1265  *
       
  1266  * Get the timestamp of the first RTP packet in @list.
       
  1267  * All packets within @list have the same timestamp.
       
  1268  *
       
  1269  * Returns: The timestamp in host order.
       
  1270  *
       
  1271  * Since: 0.10.24
       
  1272  */
       
  1273  
       
  1274  #ifdef __SYMBIAN32__
       
  1275 EXPORT_C
       
  1276 #endif
       
  1277 
       
  1278 guint32
       
  1279 gst_rtp_buffer_list_get_timestamp (GstBufferList * list)
       
  1280 {
       
  1281   GstBuffer *buffer;
       
  1282 
       
  1283   buffer = gst_buffer_list_get (list, 0, 0);
       
  1284   g_return_val_if_fail (buffer != NULL, 0);
       
  1285 
       
  1286   return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
       
  1287 }
  1016 }
  1288 
  1017 
  1289 /**
  1018 /**
  1290  * gst_rtp_buffer_set_timestamp:
  1019  * gst_rtp_buffer_set_timestamp:
  1291  * @buffer: the buffer
  1020  * @buffer: the buffer
  1298 #endif
  1027 #endif
  1299 
  1028 
  1300 void
  1029 void
  1301 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
  1030 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
  1302 {
  1031 {
  1303   GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)) = g_htonl (timestamp);
  1032   g_return_if_fail (GST_IS_BUFFER (buffer));
  1304 }
  1033   g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
  1305 
  1034 
  1306 
  1035   GST_RTP_HEADER_TIMESTAMP (buffer) = g_htonl (timestamp);
  1307 static GstBufferListItem
       
  1308 set_timestamp_header (GstBuffer ** buffer, guint group, guint idx,
       
  1309     guint32 * timestamp)
       
  1310 {
       
  1311   GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (*buffer)) = g_htonl (*timestamp);
       
  1312   return GST_BUFFER_LIST_SKIP_GROUP;
       
  1313 }
       
  1314 
       
  1315 /**
       
  1316  * gst_rtp_buffer_list_set_timestamp:
       
  1317  * @list: the buffer list
       
  1318  * @timestamp: the new timestamp
       
  1319  *
       
  1320  * Set the timestamp of each RTP packet in @list to @timestamp.
       
  1321  *
       
  1322  * Since: 0.10.24
       
  1323  */
       
  1324  
       
  1325  #ifdef __SYMBIAN32__
       
  1326 EXPORT_C
       
  1327 #endif
       
  1328 
       
  1329 void
       
  1330 gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
       
  1331 {
       
  1332   gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header,
       
  1333       &timestamp);
       
  1334 }
  1036 }
  1335 
  1037 
  1336 /**
  1038 /**
  1337  * gst_rtp_buffer_get_payload_subbuffer:
  1039  * gst_rtp_buffer_get_payload_subbuffer:
  1338  * @buffer: the buffer
  1040  * @buffer: the buffer
  1355 gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
  1057 gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
  1356     guint len)
  1058     guint len)
  1357 {
  1059 {
  1358   guint poffset, plen;
  1060   guint poffset, plen;
  1359 
  1061 
       
  1062   g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
       
  1063   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);
       
  1064 
  1360   plen = gst_rtp_buffer_get_payload_len (buffer);
  1065   plen = gst_rtp_buffer_get_payload_len (buffer);
  1361   /* we can't go past the length */
  1066   /* we can't go past the length */
  1362   if (G_UNLIKELY (offset >= plen))
  1067   if (G_UNLIKELY (offset >= plen)) {
  1363     goto wrong_offset;
  1068     GST_WARNING ("offset=%u should be less then plen=%u", offset, plen);
       
  1069     return (NULL);
       
  1070   }
  1364 
  1071 
  1365   /* apply offset */
  1072   /* apply offset */
  1366   poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
  1073   poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
  1367   plen -= offset;
  1074   plen -= offset;
  1368 
  1075 
  1369   /* see if we need to shrink the buffer based on @len */
  1076   /* see if we need to shrink the buffer based on @len */
  1370   if (len != -1 && len < plen)
  1077   if (len != -1 && len < plen)
  1371     plen = len;
  1078     plen = len;
  1372 
  1079 
  1373   return gst_buffer_create_sub (buffer, poffset, plen);
  1080   return gst_buffer_create_sub (buffer, poffset, plen);
  1374 
       
  1375   /* ERRORS */
       
  1376 wrong_offset:
       
  1377   {
       
  1378     g_warning ("offset=%u should be less then plen=%u", offset, plen);
       
  1379     return NULL;
       
  1380   }
       
  1381 }
  1081 }
  1382 
  1082 
  1383 /**
  1083 /**
  1384  * gst_rtp_buffer_get_payload_buffer:
  1084  * gst_rtp_buffer_get_payload_buffer:
  1385  * @buffer: the buffer
  1085  * @buffer: the buffer
  1414 
  1114 
  1415 guint
  1115 guint
  1416 gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
  1116 gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
  1417 {
  1117 {
  1418   guint len, size;
  1118   guint len, size;
  1419   guint8 *data;
  1119 
       
  1120   g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
       
  1121   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
  1420 
  1122 
  1421   size = GST_BUFFER_SIZE (buffer);
  1123   size = GST_BUFFER_SIZE (buffer);
  1422   data = GST_BUFFER_DATA (buffer);
       
  1423 
  1124 
  1424   len = size - gst_rtp_buffer_get_header_len (buffer);
  1125   len = size - gst_rtp_buffer_get_header_len (buffer);
  1425 
  1126 
  1426   if (GST_RTP_HEADER_PADDING (data))
  1127   if (GST_RTP_HEADER_PADDING (buffer))
  1427     len -= data[size - 1];
  1128     len -= GST_BUFFER_DATA (buffer)[size - 1];
  1428 
       
  1429   return len;
       
  1430 }
       
  1431 
       
  1432 /**
       
  1433  * gst_rtp_buffer_list_get_payload_len:
       
  1434  * @list: the buffer list
       
  1435  *
       
  1436  * Get the length of the payload of the RTP packet in @list.
       
  1437  *
       
  1438  * Returns: The length of the payload in @list.
       
  1439  *
       
  1440  * Since: 0.10.24
       
  1441  */
       
  1442  
       
  1443 #ifdef __SYMBIAN32__
       
  1444 EXPORT_C
       
  1445 #endif
       
  1446  
       
  1447 guint
       
  1448 gst_rtp_buffer_list_get_payload_len (GstBufferList * list)
       
  1449 {
       
  1450   guint len;
       
  1451   GstBufferListIterator *it;
       
  1452 
       
  1453   it = gst_buffer_list_iterate (list);
       
  1454   len = 0;
       
  1455 
       
  1456   while (gst_buffer_list_iterator_next_group (it)) {
       
  1457     guint i;
       
  1458     GstBuffer *buf;
       
  1459 
       
  1460     i = 0;
       
  1461     while ((buf = gst_buffer_list_iterator_next (it))) {
       
  1462       /* skip the RTP header */
       
  1463       if (!i++)
       
  1464         continue;
       
  1465       /* take the size of the current buffer */
       
  1466       len += GST_BUFFER_SIZE (buf);
       
  1467     }
       
  1468   }
       
  1469 
       
  1470   gst_buffer_list_iterator_free (it);
       
  1471 
  1129 
  1472   return len;
  1130   return len;
  1473 }
  1131 }
  1474 
  1132 
  1475 /**
  1133 /**
  1486 #endif
  1144 #endif
  1487 
  1145 
  1488 gpointer
  1146 gpointer
  1489 gst_rtp_buffer_get_payload (GstBuffer * buffer)
  1147 gst_rtp_buffer_get_payload (GstBuffer * buffer)
  1490 {
  1148 {
       
  1149   g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
       
  1150   g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);
       
  1151 
  1491   return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer);
  1152   return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer);
  1492 }
  1153 }
  1493 
  1154 
  1494 /**
  1155 /**
  1495  * gst_rtp_buffer_default_clock_rate:
  1156  * gst_rtp_buffer_default_clock_rate:
  1527 /**
  1188 /**
  1528  * gst_rtp_buffer_compare_seqnum:
  1189  * gst_rtp_buffer_compare_seqnum:
  1529  * @seqnum1: a sequence number
  1190  * @seqnum1: a sequence number
  1530  * @seqnum2: a sequence number
  1191  * @seqnum2: a sequence number
  1531  *
  1192  *
  1532  * Compare two sequence numbers, taking care of wraparounds. This function
  1193  * Compare two sequence numbers, taking care of wraparounds.
  1533  * returns the difference between @seqnum1 and @seqnum2.
  1194  *
  1534  *
  1195  * Returns: -1 if @seqnum1 is before @seqnum2, 0 if they are equal or 1 if
  1535  * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they
  1196  * @seqnum1 is bigger than @segnum2.
  1536  * are equal or a positive value if @seqnum1 is smaller than @segnum2.
       
  1537  *
  1197  *
  1538  * Since: 0.10.15
  1198  * Since: 0.10.15
  1539  */
  1199  */
  1540 #ifdef __SYMBIAN32__
  1200 #ifdef __SYMBIAN32__
  1541 EXPORT_C
  1201 EXPORT_C
  1542 #endif
  1202 #endif
  1543 
  1203 
  1544 gint
  1204 gint
  1545 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
  1205 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
  1546 {
  1206 {
  1547   return (gint16) (seqnum2 - seqnum1);
  1207   /* check if diff more than half of the 16bit range */
       
  1208   if (abs (seqnum2 - seqnum1) > (1 << 15)) {
       
  1209     /* one of a/b has wrapped */
       
  1210     return seqnum1 - seqnum2;
       
  1211   } else {
       
  1212     return seqnum2 - seqnum1;
       
  1213   }
  1548 }
  1214 }
  1549 
  1215 
  1550 /**
  1216 /**
  1551  * gst_rtp_buffer_ext_timestamp:
  1217  * gst_rtp_buffer_ext_timestamp:
  1552  * @exttimestamp: a previous extended timestamp
  1218  * @exttimestamp: a previous extended timestamp