[vlc-devel] H.263 over RTP (RFC 2429)

Callan, Wilson wcallan at starentnetworks.com
Fri May 28 16:53:43 CEST 2004


I have implemented enough of RFC 2429 "RTP Payload Format for the 1998 Version of H.263 Video" for it to work with live.com and quicktime.  in other words, i have a function in rtp.c for VLC to send H.263 in RTP to another VLC or to a quicktime client.  i first did it in 0.7.1.  i've integrated it in to 0.7.2 but cant get 0.7.2 to run at all without a segmentation fault so i havent tested it there.

should i give it to the current owner of rtp.c (Laurent Aimar <fenrir at via.ecp.fr>?) or should i somehow check it in myself?

here's the code...

in Add():

          case VLC_FOURCC( 'H', '2', '6', '3' ):
              id->i_payload_type = 34;  // from live.com MediaSession.cpp
              id->i_clock_rate = 90000;
              id->psz_rtpmap = strdup( "H263-1998/90000" );
              id->pf_packetize = rtp_packetize_h263;
              break;

and the new function in 0.7.2 format:

  /* rfc2429 */
  static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
                                 block_t *in )
  {
      uint8_t *p_data = in->p_buffer;
      int     i_data  = in->i_buffer;
      int     i;
  #define RTP_H263_HEADER_SIZE (2)  // plen = 0
      int     i_max   = id->i_mtu - 12 - RTP_H263_HEADER_SIZE; /* payload max in one packet */
      int     i_count;
      int     b_p_bit;
      int     b_v_bit = 0; // no pesky error resilience
      int     i_plen = 0; // normally plen=0 for PSC packet
      int     i_pebit = 0; // because plen=0
      uint16_t h;

      if (i_data < 2) {
        return VLC_EGENERIC;
      }
      if (p_data[0] || p_data[1]) {
        return VLC_EGENERIC;
      }
      // remove 2 leading 0 bytes
      p_data += 2;
      i_data -= 2;
      i_count = ( i_data + i_max - 1 ) / i_max;

  #define RTP_H263_PAYLOAD_START (14)  // plen = 0
      for( i = 0; i < i_count; i++ )
      {
          int      i_payload = __MIN( i_max, i_data );
          block_t *out = block_New( p_stream,
                                               RTP_H263_PAYLOAD_START + i_payload );
          b_p_bit = (i == 0) ? 1 : 0;
          h = ( b_p_bit << 10 )|
              ( b_v_bit << 9  )|
              ( i_plen  << 3  )|
                i_pebit;

          /* rtp common header */
          //b_m_bit = 1; // always contains end of frame
          rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
                                in->i_pts > 0 ? in->i_pts : in->i_dts );

          /* h263 header */
          out->p_buffer[12] = ( h >>  8 )&0xff;
          out->p_buffer[13] = ( h       )&0xff;

          memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );

          out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
          out->i_dts    = in->i_dts + i * in->i_length / i_count;
          out->i_length = in->i_length / i_count;

          sout_AccessOutWrite( id->p_access, out );

          p_data += i_payload;
          i_data -= i_payload;
      }

      return VLC_SUCCESS;
  }



for reference, the function in 0.7.1 format: 

  /* rfc2429 */
  static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
                                sout_buffer_t *in )
  {
      uint8_t *p_data = in->p_buffer;
      int     i_data  = in->i_size;
      int     i;
  #define WCAL_H263_HEADER_SIZE (2)  // plen = 0
      int     i_max   = id->i_mtu - 12 - WCAL_H263_HEADER_SIZE; /* payload max in one packet */
      int     i_count;
  //    int     b_m_bit;
      int     b_p_bit;
      int     b_v_bit = 0; // no pesky error resilience
      int     i_plen = 0; // normally plen=0 for PSC packet
      int     i_pebit = 0; // because plen=0
      uint16_t h;

      if (i_data < 2) {
        printf("WCAL not enough H263 data!\n");
        return VLC_EGENERIC;
      }
      if (p_data[0] || p_data[1]) {
        printf("WCAL not a PSC!\n");
        return VLC_EGENERIC;
      }
      // remove 2 leading 0 bytes
      p_data += 2;
      i_data -= 2;
      i_count = ( i_data + i_max - 1 ) / i_max;

  #define WCAL_H263_PAYLOAD_START (14)  // plen = 0
      for( i = 0; i < i_count; i++ )
      {
          int           i_payload = __MIN( i_max, i_data );
          sout_buffer_t *out = sout_BufferNew( p_stream->p_sout,
                                               WCAL_H263_PAYLOAD_START + i_payload );
          b_p_bit = (i == 0) ? 1 : 0;
          h = ( b_p_bit << 10 )|
              ( b_v_bit << 9  )|
              ( i_plen  << 3  )|
                i_pebit;
          //if (i_data > i_max) {
          //  printf("wcal h263 %d dont fit in pkt %d!\n", i_data, i_max);
          //}

          /* rtp common header */
          //b_m_bit = 1; // always contains end of frame
          rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
                                in->i_pts > 0 ? in->i_pts : in->i_dts );

         /* h263 header */
          out->p_buffer[12] = ( h >>  8 )&0xff;
          out->p_buffer[13] = ( h       )&0xff;

          memcpy( &out->p_buffer[WCAL_H263_PAYLOAD_START], p_data, i_payload );

          out->i_size   = WCAL_H263_PAYLOAD_START + i_payload;
          out->i_dts    = in->i_dts + i * in->i_length / i_count;
          out->i_length = in->i_length / i_count;

          sout_AccessOutWrite( id->p_access, out );

          p_data += i_payload;
          i_data -= i_payload;
      }

      return VLC_SUCCESS;
  }

-- 
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
If you are in trouble, please contact <postmaster at videolan.org>



More information about the vlc-devel mailing list