rtpfmt.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:21k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * rtpfmt.c: RTP payload formats
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 the VideoLAN team
  5.  * Copyright © 2007 Rémi Denis-Courmont
  6.  * $Id: 680f7456b18ea969b119696da27f51aaf161bdbb $
  7.  *
  8.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #ifdef HAVE_CONFIG_H
  25. # include "config.h"
  26. #endif
  27. #include <vlc_common.h>
  28. #include <vlc_sout.h>
  29. #include <vlc_block.h>
  30. #include "rtp.h"
  31. int
  32. rtp_packetize_h264_nal( sout_stream_id_t *id,
  33.                         const uint8_t *p_data, int i_data, int64_t i_pts,
  34.                         int64_t i_dts, bool b_last, int64_t i_length );
  35. int rtp_packetize_mpa( sout_stream_id_t *id,
  36.                        block_t *in )
  37. {
  38.     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
  39.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  40.     uint8_t *p_data = in->p_buffer;
  41.     int     i_data  = in->i_buffer;
  42.     int     i;
  43.     for( i = 0; i < i_count; i++ )
  44.     {
  45.         int           i_payload = __MIN( i_max, i_data );
  46.         block_t *out = block_Alloc( 16 + i_payload );
  47.         /* rtp common header */
  48.         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
  49.         /* mbz set to 0 */
  50.         SetWBE( out->p_buffer + 12, 0 );
  51.         /* fragment offset in the current frame */
  52.         SetWBE( out->p_buffer + 14, i * i_max );
  53.         memcpy( &out->p_buffer[16], p_data, i_payload );
  54.         out->i_buffer   = 16 + i_payload;
  55.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  56.         out->i_length = in->i_length / i_count;
  57.         rtp_packetize_send( id, out );
  58.         p_data += i_payload;
  59.         i_data -= i_payload;
  60.     }
  61.     return VLC_SUCCESS;
  62. }
  63. /* rfc2250 */
  64. int rtp_packetize_mpv( sout_stream_id_t *id, block_t *in )
  65. {
  66.     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
  67.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  68.     uint8_t *p_data = in->p_buffer;
  69.     int     i_data  = in->i_buffer;
  70.     int     i;
  71.     int     b_sequence_start = 0;
  72.     int     i_temporal_ref = 0;
  73.     int     i_picture_coding_type = 0;
  74.     int     i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
  75.     int     b_start_slice = 0;
  76.     /* preparse this packet to get some info */
  77.     if( in->i_buffer > 4 )
  78.     {
  79.         uint8_t *p = p_data;
  80.         int      i_rest = in->i_buffer;
  81.         for( ;; )
  82.         {
  83.             while( i_rest > 4 &&
  84.                    ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
  85.             {
  86.                 p++;
  87.                 i_rest--;
  88.             }
  89.             if( i_rest <= 4 )
  90.             {
  91.                 break;
  92.             }
  93.             p += 3;
  94.             i_rest -= 4;
  95.             if( *p == 0xb3 )
  96.             {
  97.                 /* sequence start code */
  98.                 b_sequence_start = 1;
  99.             }
  100.             else if( *p == 0x00 && i_rest >= 4 )
  101.             {
  102.                 /* picture */
  103.                 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
  104.                 i_picture_coding_type = (p[2] >> 3)&0x07;
  105.                 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
  106.                                     i_picture_coding_type == 3 ) )
  107.                 {
  108.                     i_ffv = (p[3] >> 2)&0x01;
  109.                     i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
  110.                     if( i_rest > 4 && i_picture_coding_type == 3 )
  111.                     {
  112.                         i_fbv = (p[4]>>6)&0x01;
  113.                         i_bfc = (p[4]>>3)&0x07;
  114.                     }
  115.                 }
  116.             }
  117.             else if( *p <= 0xaf )
  118.             {
  119.                 b_start_slice = 1;
  120.             }
  121.         }
  122.     }
  123.     for( i = 0; i < i_count; i++ )
  124.     {
  125.         int           i_payload = __MIN( i_max, i_data );
  126.         block_t *out = block_Alloc( 16 + i_payload );
  127.         /* MBZ:5 T:1 TR:10 AN:1 N:1 S:1 B:1 E:1 P:3 FBV:1 BFC:3 FFV:1 FFC:3 */
  128.         uint32_t      h = ( i_temporal_ref << 16 )|
  129.                           ( b_sequence_start << 13 )|
  130.                           ( b_start_slice << 12 )|
  131.                           ( i == i_count - 1 ? 1 << 11 : 0 )|
  132.                           ( i_picture_coding_type << 8 )|
  133.                           ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
  134.         /* rtp common header */
  135.         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
  136.                               in->i_pts > 0 ? in->i_pts : in->i_dts );
  137.         SetDWBE( out->p_buffer + 12, h );
  138.         memcpy( &out->p_buffer[16], p_data, i_payload );
  139.         out->i_buffer   = 16 + i_payload;
  140.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  141.         out->i_length = in->i_length / i_count;
  142.         rtp_packetize_send( id, out );
  143.         p_data += i_payload;
  144.         i_data -= i_payload;
  145.     }
  146.     return VLC_SUCCESS;
  147. }
  148. int rtp_packetize_ac3( sout_stream_id_t *id, block_t *in )
  149. {
  150.     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
  151.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  152.     uint8_t *p_data = in->p_buffer;
  153.     int     i_data  = in->i_buffer;
  154.     int     i;
  155.     for( i = 0; i < i_count; i++ )
  156.     {
  157.         int           i_payload = __MIN( i_max, i_data );
  158.         block_t *out = block_Alloc( 14 + i_payload );
  159.         /* rtp common header */
  160.         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
  161.         /* unit count */
  162.         out->p_buffer[12] = 1;
  163.         /* unit header */
  164.         out->p_buffer[13] = 0x00;
  165.         /* data */
  166.         memcpy( &out->p_buffer[14], p_data, i_payload );
  167.         out->i_buffer   = 14 + i_payload;
  168.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  169.         out->i_length = in->i_length / i_count;
  170.         rtp_packetize_send( id, out );
  171.         p_data += i_payload;
  172.         i_data -= i_payload;
  173.     }
  174.     return VLC_SUCCESS;
  175. }
  176. int rtp_packetize_split( sout_stream_id_t *id, block_t *in )
  177. {
  178.     int     i_max   = rtp_mtu (id); /* payload max in one packet */
  179.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  180.     uint8_t *p_data = in->p_buffer;
  181.     int     i_data  = in->i_buffer;
  182.     int     i;
  183.     for( i = 0; i < i_count; i++ )
  184.     {
  185.         int           i_payload = __MIN( i_max, i_data );
  186.         block_t *out = block_Alloc( 12 + i_payload );
  187.         /* rtp common header */
  188.         rtp_packetize_common( id, out, (i == i_count - 1),
  189.                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
  190.         memcpy( &out->p_buffer[12], p_data, i_payload );
  191.         out->i_buffer   = 12 + i_payload;
  192.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  193.         out->i_length = in->i_length / i_count;
  194.         rtp_packetize_send( id, out );
  195.         p_data += i_payload;
  196.         i_data -= i_payload;
  197.     }
  198.     return VLC_SUCCESS;
  199. }
  200. /* rfc3016 */
  201. int rtp_packetize_mp4a_latm( sout_stream_id_t *id, block_t *in )
  202. {
  203.     int     i_max   = rtp_mtu (id) - 2;              /* payload max in one packet */
  204.     int     latmhdrsize = in->i_buffer / 0xff + 1;
  205.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  206.     uint8_t *p_data = in->p_buffer, *p_header = NULL;
  207.     int     i_data  = in->i_buffer;
  208.     int     i;
  209.     for( i = 0; i < i_count; i++ )
  210.     {
  211.         int     i_payload = __MIN( i_max, i_data );
  212.         block_t *out;
  213.         if( i != 0 )
  214.             latmhdrsize = 0;
  215.         out = block_Alloc( 12 + latmhdrsize + i_payload );
  216.         /* rtp common header */
  217.         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
  218.                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
  219.         if( i == 0 )
  220.         {
  221.             int tmp = in->i_buffer;
  222.             p_header=out->p_buffer+12;
  223.             while( tmp > 0xfe )
  224.             {
  225.                 *p_header = 0xff;
  226.                 p_header++;
  227.                 tmp -= 0xff;
  228.             }
  229.             *p_header = tmp;
  230.         }
  231.         memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
  232.         out->i_buffer   = 12 + latmhdrsize + i_payload;
  233.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  234.         out->i_length = in->i_length / i_count;
  235.         rtp_packetize_send( id, out );
  236.         p_data += i_payload;
  237.         i_data -= i_payload;
  238.     }
  239.     return VLC_SUCCESS;
  240. }
  241. int rtp_packetize_mp4a( sout_stream_id_t *id, block_t *in )
  242. {
  243.     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
  244.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  245.     uint8_t *p_data = in->p_buffer;
  246.     int     i_data  = in->i_buffer;
  247.     int     i;
  248.     for( i = 0; i < i_count; i++ )
  249.     {
  250.         int           i_payload = __MIN( i_max, i_data );
  251.         block_t *out = block_Alloc( 16 + i_payload );
  252.         /* rtp common header */
  253.         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
  254.                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
  255.         /* AU headers */
  256.         /* AU headers length (bits) */
  257.         out->p_buffer[12] = 0;
  258.         out->p_buffer[13] = 2*8;
  259.         /* for each AU length 13 bits + idx 3bits, */
  260.         SetWBE( out->p_buffer + 14, (in->i_buffer << 3) | 0 );
  261.         memcpy( &out->p_buffer[16], p_data, i_payload );
  262.         out->i_buffer   = 16 + i_payload;
  263.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  264.         out->i_length = in->i_length / i_count;
  265.         rtp_packetize_send( id, out );
  266.         p_data += i_payload;
  267.         i_data -= i_payload;
  268.     }
  269.     return VLC_SUCCESS;
  270. }
  271. /* rfc2429 */
  272. #define RTP_H263_HEADER_SIZE (2)  // plen = 0
  273. #define RTP_H263_PAYLOAD_START (14)  // plen = 0
  274. int rtp_packetize_h263( sout_stream_id_t *id, block_t *in )
  275. {
  276.     uint8_t *p_data = in->p_buffer;
  277.     int     i_data  = in->i_buffer;
  278.     int     i;
  279.     int     i_max   = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */
  280.     int     i_count;
  281.     int     b_p_bit;
  282.     int     b_v_bit = 0; // no pesky error resilience
  283.     int     i_plen = 0; // normally plen=0 for PSC packet
  284.     int     i_pebit = 0; // because plen=0
  285.     uint16_t h;
  286.     if( i_data < 2 )
  287.     {
  288.         return VLC_EGENERIC;
  289.     }
  290.     if( p_data[0] || p_data[1] )
  291.     {
  292.         return VLC_EGENERIC;
  293.     }
  294.     /* remove 2 leading 0 bytes */
  295.     p_data += 2;
  296.     i_data -= 2;
  297.     i_count = ( i_data + i_max - 1 ) / i_max;
  298.     for( i = 0; i < i_count; i++ )
  299.     {
  300.         int      i_payload = __MIN( i_max, i_data );
  301.         block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );
  302.         b_p_bit = (i == 0) ? 1 : 0;
  303.         h = ( b_p_bit << 10 )|
  304.             ( b_v_bit << 9  )|
  305.             ( i_plen  << 3  )|
  306.               i_pebit;
  307.         /* rtp common header */
  308.         //b_m_bit = 1; // always contains end of frame
  309.         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
  310.                               in->i_pts > 0 ? in->i_pts : in->i_dts );
  311.         /* h263 header */
  312.         SetWBE( out->p_buffer + 12, h );
  313.         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
  314.         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
  315.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  316.         out->i_length = in->i_length / i_count;
  317.         rtp_packetize_send( id, out );
  318.         p_data += i_payload;
  319.         i_data -= i_payload;
  320.     }
  321.     return VLC_SUCCESS;
  322. }
  323. /* rfc3984 */
  324. int
  325. rtp_packetize_h264_nal( sout_stream_id_t *id,
  326.                         const uint8_t *p_data, int i_data, int64_t i_pts,
  327.                         int64_t i_dts, bool b_last, int64_t i_length )
  328. {
  329.     const int i_max = rtp_mtu (id); /* payload max in one packet */
  330.     int i_nal_hdr;
  331.     int i_nal_type;
  332.     if( i_data < 5 )
  333.         return VLC_SUCCESS;
  334.     i_nal_hdr = p_data[3];
  335.     i_nal_type = i_nal_hdr&0x1f;
  336.     /* Skip start code */
  337.     p_data += 3;
  338.     i_data -= 3;
  339.     /* */
  340.     if( i_data <= i_max )
  341.     {
  342.         /* Single NAL unit packet */
  343.         block_t *out = block_Alloc( 12 + i_data );
  344.         out->i_dts    = i_dts;
  345.         out->i_length = i_length;
  346.         /* */
  347.         rtp_packetize_common( id, out, b_last, i_pts );
  348.         out->i_buffer = 12 + i_data;
  349.         memcpy( &out->p_buffer[12], p_data, i_data );
  350.         rtp_packetize_send( id, out );
  351.     }
  352.     else
  353.     {
  354.         /* FU-A Fragmentation Unit without interleaving */
  355.         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
  356.         int i;
  357.         p_data++;
  358.         i_data--;
  359.         for( i = 0; i < i_count; i++ )
  360.         {
  361.             const int i_payload = __MIN( i_data, i_max-2 );
  362.             block_t *out = block_Alloc( 12 + 2 + i_payload );
  363.             out->i_dts    = i_dts + i * i_length / i_count;
  364.             out->i_length = i_length / i_count;
  365.             /* */
  366.             rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts );
  367.             out->i_buffer = 14 + i_payload;
  368.             /* FU indicator */
  369.             out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
  370.             /* FU header */
  371.             out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type;
  372.             memcpy( &out->p_buffer[14], p_data, i_payload );
  373.             rtp_packetize_send( id, out );
  374.             i_data -= i_payload;
  375.             p_data += i_payload;
  376.         }
  377.     }
  378.     return VLC_SUCCESS;
  379. }
  380. int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
  381. {
  382.     const uint8_t *p_buffer = in->p_buffer;
  383.     int i_buffer = in->i_buffer;
  384.     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
  385.     {
  386.         i_buffer--;
  387.         p_buffer++;
  388.     }
  389.     /* Split nal units */
  390.     while( i_buffer > 4 )
  391.     {
  392.         int i_offset;
  393.         int i_size = i_buffer;
  394.         int i_skip = i_buffer;
  395.         /* search nal end */
  396.         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
  397.         {
  398.             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
  399.             {
  400.                 /* we found another startcode */
  401.                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
  402.                 i_skip = i_offset;
  403.                 break;
  404.             }
  405.         }
  406.         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
  407.         rtp_packetize_h264_nal( id, p_buffer, i_size,
  408.                                 (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts,
  409.                                 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
  410.         i_buffer -= i_skip;
  411.         p_buffer += i_skip;
  412.     }
  413.     return VLC_SUCCESS;
  414. }
  415. int rtp_packetize_amr( sout_stream_id_t *id, block_t *in )
  416. {
  417.     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
  418.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  419.     uint8_t *p_data = in->p_buffer;
  420.     int     i_data  = in->i_buffer;
  421.     int     i;
  422.     /* Only supports octet-aligned mode */
  423.     for( i = 0; i < i_count; i++ )
  424.     {
  425.         int           i_payload = __MIN( i_max, i_data );
  426.         block_t *out = block_Alloc( 14 + i_payload );
  427.         /* rtp common header */
  428.         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
  429.                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
  430.         /* Payload header */
  431.         out->p_buffer[12] = 0xF0; /* CMR */
  432.         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
  433.         /* FIXME: are we fed multiple frames ? */
  434.         memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
  435.         out->i_buffer   = 14 + i_payload-1;
  436.         out->i_dts    = in->i_dts + i * in->i_length / i_count;
  437.         out->i_length = in->i_length / i_count;
  438.         rtp_packetize_send( id, out );
  439.         p_data += i_payload;
  440.         i_data -= i_payload;
  441.     }
  442.     return VLC_SUCCESS;
  443. }
  444. int rtp_packetize_t140( sout_stream_id_t *id, block_t *in )
  445. {
  446.     const size_t   i_max  = rtp_mtu (id);
  447.     const uint8_t *p_data = in->p_buffer;
  448.     size_t         i_data = in->i_buffer;
  449.     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
  450.     {
  451.         size_t i_payload = i_data;
  452.         /* Make sure we stop on an UTF-8 character boundary
  453.          * (assuming the input is valid UTF-8) */
  454.         if( i_data > i_max )
  455.         {
  456.             i_payload = i_max;
  457.             while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
  458.             {
  459.                 if( i_payload == 0 )
  460.                     return VLC_SUCCESS; /* fishy input! */
  461.                 i_payload--;
  462.             }
  463.         }
  464.         block_t *out = block_Alloc( 12 + i_payload );
  465.         if( out == NULL )
  466.             return VLC_SUCCESS;
  467.         rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
  468.         memcpy( out->p_buffer + 12, p_data, i_payload );
  469.         out->i_buffer = 12 + i_payload;
  470.         out->i_dts    = out->i_pts;
  471.         out->i_length = 0;
  472.         rtp_packetize_send( id, out );
  473.         p_data += i_payload;
  474.         i_data -= i_payload;
  475.     }
  476.     return VLC_SUCCESS;
  477. }
  478. int rtp_packetize_spx( sout_stream_id_t *id, block_t *in )
  479. {
  480.     uint8_t *p_buffer = in->p_buffer;
  481.     int i_data_size, i_payload_size, i_payload_padding;
  482.     i_data_size = i_payload_size = in->i_buffer;
  483.     i_payload_padding = 0;
  484.     block_t *p_out;
  485.     if ( in->i_buffer > rtp_mtu (id) )
  486.         return VLC_SUCCESS;
  487.     /*
  488.       RFC for Speex in RTP says that each packet must end on an octet 
  489.       boundary. So, we check to see if the number of bytes % 4 is zero.
  490.       If not, we have to add some padding. 
  491.       This MAY be overkill since packetization is handled elsewhere and 
  492.       appears to ensure the octet boundary. However, better safe than
  493.       sorry.
  494.     */
  495.     if ( i_payload_size % 4 )
  496.     {
  497.         i_payload_padding = 4 - ( i_payload_size % 4 );
  498.         i_payload_size += i_payload_padding;
  499.     }
  500.     /*
  501.       Allocate a new RTP p_output block of the appropriate size. 
  502.       Allow for 12 extra bytes of RTP header. 
  503.     */
  504.     p_out = block_Alloc( 12 + i_payload_size );
  505.     if ( i_payload_padding )
  506.     {
  507.     /*
  508.       The padding is required to be a zero followed by all 1s.
  509.     */
  510.         char c_first_pad, c_remaining_pad;
  511.         c_first_pad = 0x7F;
  512.         c_remaining_pad = 0xFF;
  513.         /*
  514.           Allow for 12 bytes before the i_data_size because
  515.           of the expected RTP header added during
  516.           rtp_packetize_common.
  517.         */
  518.         p_out->p_buffer[12 + i_data_size] = c_first_pad; 
  519.         switch (i_payload_padding)
  520.         {
  521.           case 2:
  522.             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
  523.             break;
  524.           case 3:
  525.             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
  526.             p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; 
  527.             break;
  528.         }
  529.     }
  530.     /* Add the RTP header to our p_output buffer. */
  531.     rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );
  532.     /* Copy the Speex payload to the p_output buffer */
  533.     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
  534.     p_out->i_buffer = 12 + i_payload_size;
  535.     p_out->i_dts = in->i_dts;
  536.     p_out->i_length = in->i_length;
  537.     /* Queue the buffer for actual transmission. */
  538.     rtp_packetize_send( id, p_out );
  539.     return VLC_SUCCESS;
  540. }
  541. static int rtp_packetize_g726( sout_stream_id_t *id, block_t *in, int i_pad )
  542. {
  543.     int     i_max   = (rtp_mtu( id )- 12 + i_pad - 1) & ~i_pad;
  544.     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
  545.     uint8_t *p_data = in->p_buffer;
  546.     int     i_data  = in->i_buffer;
  547.     int     i_packet = 0;
  548.     while( i_data > 0 )
  549.     {
  550.         int           i_payload = __MIN( i_max, i_data );
  551.         block_t *out = block_New( p_stream, 12 + i_payload );
  552.         /* rtp common header */
  553.         rtp_packetize_common( id, out, 0,
  554.                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
  555.         memcpy( &out->p_buffer[12], p_data, i_payload );
  556.         out->i_buffer   = 12 + i_payload;
  557.         out->i_dts    = in->i_dts + i_packet++ * in->i_length / i_count;
  558.         out->i_length = in->i_length / i_count;
  559.         rtp_packetize_send( id, out );
  560.         p_data += i_payload;
  561.         i_data -= i_payload;
  562.     }
  563.     return VLC_SUCCESS;
  564. }
  565. int rtp_packetize_g726_16( sout_stream_id_t *id, block_t *in )
  566. {
  567.     return rtp_packetize_g726( id, in, 4 );
  568. }
  569. int rtp_packetize_g726_24( sout_stream_id_t *id, block_t *in )
  570. {
  571.     return rtp_packetize_g726( id, in, 8 );
  572. }
  573. int rtp_packetize_g726_32( sout_stream_id_t *id, block_t *in )
  574. {
  575.     return rtp_packetize_g726( id, in, 2 );
  576. }
  577. int rtp_packetize_g726_40( sout_stream_id_t *id, block_t *in )
  578. {
  579.     return rtp_packetize_g726( id, in, 8 );
  580. }