Changeset 14fae49cbf998fee62323fde27ba6833f8da8289

Show
Ignore:
Timestamp:
13/12/07 20:03:29 (1 year ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1197572609 +0000
git-parent:

[1d22fe1f6f505bd877c173538c774ea20498558b]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1197572609 +0000
Message:

Split RTP sout further

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/stream_out/Modules.am

    r31067bd r14fae49  
    77SOURCES_stream_out_display = display.c 
    88SOURCES_stream_out_gather = gather.c 
    9 SOURCES_stream_out_rtp = rtp.h rtp.c rtcp.c rtsp.c 
     9SOURCES_stream_out_rtp = rtp.h rtp.c rtpfmt.c rtcp.c rtsp.c 
    1010SOURCES_stream_out_switcher = switcher.c 
    1111SOURCES_stream_out_bridge = bridge.c 
  • modules/stream_out/rtp.c

    r17d26df r14fae49  
    773773 * RTP mux 
    774774 *****************************************************************************/ 
    775 static int rtp_packetize_l16  ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    776 static int rtp_packetize_l8   ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    777 static int rtp_packetize_mpa  ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    778 static int rtp_packetize_mpv  ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    779 static int rtp_packetize_ac3  ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    780 static int rtp_packetize_split( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    781 static int rtp_packetize_mp4a ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    782 static int rtp_packetize_mp4a_latm ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    783 static int rtp_packetize_h263 ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    784 static int rtp_packetize_h264 ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    785 static int rtp_packetize_amr  ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    786 static int rtp_packetize_spx  ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    787 static int rtp_packetize_t140 ( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    788775 
    789776static void sprintf_hexa( char *s, uint8_t *p_data, int i_data ) 
     
    14361423} 
    14371424 
    1438 static inline void rtp_packetize_send( sout_stream_id_t *id, block_t *out ) 
    1439 { 
    1440     block_FifoPut( id->p_fifo, out ); 
    1441 } 
    1442  
    14431425int rtp_add_sink( sout_stream_id_t *id, int fd, vlc_bool_t rtcp_mux ) 
    14441426{ 
     
    15021484 
    15031485 
    1504 /**************************************************************************** 
    1505  * rtp_packetize_*: 
    1506  ****************************************************************************/ 
    1507 static void rtp_packetize_common( sout_stream_id_t *id, block_t *out, 
    1508                                   int b_marker, int64_t i_pts ) 
     1486void rtp_packetize_common( sout_stream_id_t *id, block_t *out, 
     1487                           int b_marker, int64_t i_pts ) 
    15091488{ 
    15101489    uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / I64C(1000000); 
     
    15251504} 
    15261505 
    1527 static int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1528                               block_t *in ) 
    1529 
    1530     int     i_max   = id->i_mtu - 12 - 4; /* payload max in one packet */ 
    1531     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    1532  
    1533     uint8_t *p_data = in->p_buffer; 
    1534     int     i_data  = in->i_buffer; 
    1535     int     i; 
    1536  
    1537     for( i = 0; i < i_count; i++ ) 
    1538     { 
    1539         int           i_payload = __MIN( i_max, i_data ); 
    1540         block_t *out = block_New( p_stream, 16 + i_payload ); 
    1541  
    1542         /* rtp common header */ 
    1543         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts ); 
    1544         /* mbz set to 0 */ 
    1545         out->p_buffer[12] = 0; 
    1546         out->p_buffer[13] = 0; 
    1547         /* fragment offset in the current frame */ 
    1548         out->p_buffer[14] = ( (i*i_max) >> 8 )&0xff; 
    1549         out->p_buffer[15] = ( (i*i_max)      )&0xff; 
    1550         memcpy( &out->p_buffer[16], p_data, i_payload ); 
    1551  
    1552         out->i_buffer   = 16 + i_payload; 
    1553         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1554         out->i_length = in->i_length / i_count; 
    1555  
    1556         rtp_packetize_send( id, out ); 
    1557  
    1558         p_data += i_payload; 
    1559         i_data -= i_payload; 
    1560     } 
    1561  
    1562     return VLC_SUCCESS; 
    1563 
    1564  
    1565 /* rfc2250 */ 
    1566 static int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1567                               block_t *in ) 
    1568 
    1569     int     i_max   = id->i_mtu - 12 - 4; /* payload max in one packet */ 
    1570     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    1571  
    1572     uint8_t *p_data = in->p_buffer; 
    1573     int     i_data  = in->i_buffer; 
    1574     int     i; 
    1575     int     b_sequence_start = 0; 
    1576     int     i_temporal_ref = 0; 
    1577     int     i_picture_coding_type = 0; 
    1578     int     i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0; 
    1579     int     b_start_slice = 0; 
    1580  
    1581     /* preparse this packet to get some info */ 
    1582     if( in->i_buffer > 4 ) 
    1583     { 
    1584         uint8_t *p = p_data; 
    1585         int      i_rest = in->i_buffer; 
    1586  
    1587         for( ;; ) 
    1588         { 
    1589             while( i_rest > 4 && 
    1590                    ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) ) 
    1591             { 
    1592                 p++; 
    1593                 i_rest--; 
    1594             } 
    1595             if( i_rest <= 4 ) 
    1596             { 
    1597                 break; 
    1598             } 
    1599             p += 3; 
    1600             i_rest -= 4; 
    1601  
    1602             if( *p == 0xb3 ) 
    1603             { 
    1604                 /* sequence start code */ 
    1605                 b_sequence_start = 1; 
    1606             } 
    1607             else if( *p == 0x00 && i_rest >= 4 ) 
    1608             { 
    1609                 /* picture */ 
    1610                 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03); 
    1611                 i_picture_coding_type = (p[2] >> 3)&0x07; 
    1612  
    1613                 if( i_rest >= 4 && ( i_picture_coding_type == 2 || 
    1614                                     i_picture_coding_type == 3 ) ) 
    1615                 { 
    1616                     i_ffv = (p[3] >> 2)&0x01; 
    1617                     i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01); 
    1618                     if( i_rest > 4 && i_picture_coding_type == 3 ) 
    1619                     { 
    1620                         i_fbv = (p[4]>>6)&0x01; 
    1621                         i_bfc = (p[4]>>3)&0x07; 
    1622                     } 
    1623                 } 
    1624             } 
    1625             else if( *p <= 0xaf ) 
    1626             { 
    1627                 b_start_slice = 1; 
    1628             } 
    1629         } 
    1630     } 
    1631  
    1632     for( i = 0; i < i_count; i++ ) 
    1633     { 
    1634         int           i_payload = __MIN( i_max, i_data ); 
    1635         block_t *out = block_New( p_stream, 
    1636                                              16 + i_payload ); 
    1637         uint32_t      h = ( i_temporal_ref << 16 )| 
    1638                           ( b_sequence_start << 13 )| 
    1639                           ( b_start_slice << 12 )| 
    1640                           ( i == i_count - 1 ? 1 << 11 : 0 )| 
    1641                           ( i_picture_coding_type << 8 )| 
    1642                           ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc; 
    1643  
    1644         /* rtp common header */ 
    1645         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, 
    1646                               in->i_pts > 0 ? in->i_pts : in->i_dts ); 
    1647  
    1648         /* 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 */ 
    1649         out->p_buffer[12] = ( h >> 24 )&0xff; 
    1650         out->p_buffer[13] = ( h >> 16 )&0xff; 
    1651         out->p_buffer[14] = ( h >>  8 )&0xff; 
    1652         out->p_buffer[15] = ( h       )&0xff; 
    1653  
    1654         memcpy( &out->p_buffer[16], p_data, i_payload ); 
    1655  
    1656         out->i_buffer   = 16 + i_payload; 
    1657         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1658         out->i_length = in->i_length / i_count; 
    1659  
    1660         rtp_packetize_send( id, out ); 
    1661  
    1662         p_data += i_payload; 
    1663         i_data -= i_payload; 
    1664     } 
    1665  
    1666     return VLC_SUCCESS; 
    1667 
    1668  
    1669 static int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1670                               block_t *in ) 
    1671 
    1672     int     i_max   = id->i_mtu - 12 - 2; /* payload max in one packet */ 
    1673     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    1674  
    1675     uint8_t *p_data = in->p_buffer; 
    1676     int     i_data  = in->i_buffer; 
    1677     int     i; 
    1678  
    1679     for( i = 0; i < i_count; i++ ) 
    1680     { 
    1681         int           i_payload = __MIN( i_max, i_data ); 
    1682         block_t *out = block_New( p_stream, 14 + i_payload ); 
    1683  
    1684         /* rtp common header */ 
    1685         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts ); 
    1686         /* unit count */ 
    1687         out->p_buffer[12] = 1; 
    1688         /* unit header */ 
    1689         out->p_buffer[13] = 0x00; 
    1690         /* data */ 
    1691         memcpy( &out->p_buffer[14], p_data, i_payload ); 
    1692  
    1693         out->i_buffer   = 14 + i_payload; 
    1694         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1695         out->i_length = in->i_length / i_count; 
    1696  
    1697         rtp_packetize_send( id, out ); 
    1698  
    1699         p_data += i_payload; 
    1700         i_data -= i_payload; 
    1701     } 
    1702  
    1703     return VLC_SUCCESS; 
    1704 
    1705  
    1706 static int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1707                                 block_t *in ) 
    1708 
    1709     int     i_max   = id->i_mtu - 12; /* payload max in one packet */ 
    1710     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    1711  
    1712     uint8_t *p_data = in->p_buffer; 
    1713     int     i_data  = in->i_buffer; 
    1714     int     i; 
    1715  
    1716     for( i = 0; i < i_count; i++ ) 
    1717     { 
    1718         int           i_payload = __MIN( i_max, i_data ); 
    1719         block_t *out = block_New( p_stream, 12 + i_payload ); 
    1720  
    1721         /* rtp common header */ 
    1722         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0), 
    1723                               (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    1724         memcpy( &out->p_buffer[12], p_data, i_payload ); 
    1725  
    1726         out->i_buffer   = 12 + i_payload; 
    1727         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1728         out->i_length = in->i_length / i_count; 
    1729  
    1730         rtp_packetize_send( id, out ); 
    1731  
    1732         p_data += i_payload; 
    1733         i_data -= i_payload; 
    1734     } 
    1735  
    1736     return VLC_SUCCESS; 
    1737 
    1738  
    1739 /* rfc3016 */ 
    1740 static int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1741                                 block_t *in ) 
    1742 
    1743     int     i_max   = id->i_mtu - 14;              /* payload max in one packet */ 
    1744     int     latmhdrsize = in->i_buffer / 0xff + 1; 
    1745     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    1746  
    1747     uint8_t *p_data = in->p_buffer, *p_header = NULL; 
    1748     int     i_data  = in->i_buffer; 
    1749     int     i; 
    1750  
    1751     for( i = 0; i < i_count; i++ ) 
    1752     { 
    1753         int     i_payload = __MIN( i_max, i_data ); 
    1754         block_t *out; 
    1755  
    1756         if( i != 0 ) 
    1757             latmhdrsize = 0; 
    1758         out = block_New( p_stream, 12 + latmhdrsize + i_payload ); 
    1759  
    1760         /* rtp common header */ 
    1761         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0), 
    1762                               (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    1763  
    1764         if( i == 0 ) 
    1765         { 
    1766             int tmp = in->i_buffer; 
    1767  
    1768             p_header=out->p_buffer+12; 
    1769             while( tmp > 0xfe ) 
    1770             { 
    1771                 *p_header = 0xff; 
    1772                 p_header++; 
    1773                 tmp -= 0xff; 
    1774             } 
    1775             *p_header = tmp; 
    1776         } 
    1777  
    1778         memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload ); 
    1779  
    1780         out->i_buffer   = 12 + latmhdrsize + i_payload; 
    1781         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1782         out->i_length = in->i_length / i_count; 
    1783  
    1784         rtp_packetize_send( id, out ); 
    1785  
    1786         p_data += i_payload; 
    1787         i_data -= i_payload; 
    1788     } 
    1789  
    1790     return VLC_SUCCESS; 
    1791 
    1792  
    1793 static int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1794                               block_t *in ) 
    1795 
    1796     const uint8_t *p_data = in->p_buffer; 
    1797     size_t i_data  = in->i_buffer; 
    1798     /* ptime=20ms -> 50Hz */ 
    1799     size_t i_plen = 2 * id->i_channels * ( ( id->i_clock_rate + 49 ) / 50 ); 
    1800  
    1801     for( unsigned i_packet = 0; i_data > 0; i_packet++ ) 
    1802     { 
    1803         int           i_payload = __MIN( i_plen, i_data ); 
    1804         block_t *out = block_New( p_stream, 12 + i_payload ); 
    1805  
    1806         /* rtp common header */ 
    1807         rtp_packetize_common( id, out, 0, 
    1808                               (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    1809         memcpy( &out->p_buffer[12], p_data, i_payload ); 
    1810  
    1811         out->i_buffer = 12 + i_payload; 
    1812         out->i_dts    = in->i_dts + i_packet * 20000; 
    1813         out->i_length = i_payload * 20000 / i_plen; 
    1814  
    1815         rtp_packetize_send( id, out ); 
    1816  
    1817         p_data += i_payload; 
    1818         i_data -= i_payload; 
    1819     } 
    1820  
    1821     return VLC_SUCCESS; 
    1822 
    1823  
    1824 static int rtp_packetize_l8( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1825                              block_t *in ) 
    1826 
    1827     const uint8_t *p_data = in->p_buffer; 
    1828     size_t i_data  = in->i_buffer; 
    1829     /* ptime=20ms -> 50Hz */ 
    1830     size_t i_plen = id->i_channels * ( ( id->i_clock_rate + 49 ) / 50 ); 
    1831  
    1832     for( unsigned i_packet = 0; i_data > 0; i_packet++ ) 
    1833     { 
    1834         int           i_payload = __MIN( i_plen, i_data ); 
    1835         block_t *out = block_New( p_stream, 12 + i_payload ); 
    1836  
    1837         /* rtp common header */ 
    1838         rtp_packetize_common( id, out, 0, 
    1839                               (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    1840         memcpy( &out->p_buffer[12], p_data, i_payload ); 
    1841  
    1842         out->i_buffer = 12 + i_payload; 
    1843         out->i_dts    = in->i_dts + i_packet * 20000; 
    1844         out->i_length = i_payload * 20000 / i_plen; 
    1845  
    1846         rtp_packetize_send( id, out ); 
    1847  
    1848         p_data += i_payload; 
    1849         i_data -= i_payload; 
    1850     } 
    1851  
    1852     return VLC_SUCCESS; 
    1853 
    1854  
    1855 static int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1856                                block_t *in ) 
    1857 
    1858     int     i_max   = id->i_mtu - 16; /* payload max in one packet */ 
    1859     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    1860  
    1861     uint8_t *p_data = in->p_buffer; 
    1862     int     i_data  = in->i_buffer; 
    1863     int     i; 
    1864  
    1865     for( i = 0; i < i_count; i++ ) 
    1866     { 
    1867         int           i_payload = __MIN( i_max, i_data ); 
    1868         block_t *out = block_New( p_stream, 16 + i_payload ); 
    1869  
    1870         /* rtp common header */ 
    1871         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0), 
    1872                               (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    1873         /* AU headers */ 
    1874         /* AU headers length (bits) */ 
    1875         out->p_buffer[12] = 0; 
    1876         out->p_buffer[13] = 2*8; 
    1877         /* for each AU length 13 bits + idx 3bits, */ 
    1878         out->p_buffer[14] = ( in->i_buffer >> 5 )&0xff; 
    1879         out->p_buffer[15] = ( (in->i_buffer&0xff)<<3 )|0; 
    1880  
    1881         memcpy( &out->p_buffer[16], p_data, i_payload ); 
    1882  
    1883         out->i_buffer   = 16 + i_payload; 
    1884         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1885         out->i_length = in->i_length / i_count; 
    1886  
    1887         rtp_packetize_send( id, out ); 
    1888  
    1889         p_data += i_payload; 
    1890         i_data -= i_payload; 
    1891     } 
    1892  
    1893     return VLC_SUCCESS; 
    1894 
    1895  
    1896  
    1897 /* rfc2429 */ 
    1898 #define RTP_H263_HEADER_SIZE (2)  // plen = 0 
    1899 #define RTP_H263_PAYLOAD_START (14)  // plen = 0 
    1900 static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1901                                block_t *in ) 
    1902 
    1903     uint8_t *p_data = in->p_buffer; 
    1904     int     i_data  = in->i_buffer; 
    1905     int     i; 
    1906     int     i_max   = id->i_mtu - 12 - RTP_H263_HEADER_SIZE; /* payload max in one packet */ 
    1907     int     i_count; 
    1908     int     b_p_bit; 
    1909     int     b_v_bit = 0; // no pesky error resilience 
    1910     int     i_plen = 0; // normally plen=0 for PSC packet 
    1911     int     i_pebit = 0; // because plen=0 
    1912     uint16_t h; 
    1913  
    1914     if( i_data < 2 ) 
    1915     { 
    1916         return VLC_EGENERIC; 
    1917     } 
    1918     if( p_data[0] || p_data[1] ) 
    1919     { 
    1920         return VLC_EGENERIC; 
    1921     } 
    1922     /* remove 2 leading 0 bytes */ 
    1923     p_data += 2; 
    1924     i_data -= 2; 
    1925     i_count = ( i_data + i_max - 1 ) / i_max; 
    1926  
    1927     for( i = 0; i < i_count; i++ ) 
    1928     { 
    1929         int      i_payload = __MIN( i_max, i_data ); 
    1930         block_t *out = block_New( p_stream, 
    1931                                   RTP_H263_PAYLOAD_START + i_payload ); 
    1932         b_p_bit = (i == 0) ? 1 : 0; 
    1933         h = ( b_p_bit << 10 )| 
    1934             ( b_v_bit << 9  )| 
    1935             ( i_plen  << 3  )| 
    1936               i_pebit; 
    1937  
    1938         /* rtp common header */ 
    1939         //b_m_bit = 1; // always contains end of frame 
    1940         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, 
    1941                               in->i_pts > 0 ? in->i_pts : in->i_dts ); 
    1942  
    1943         /* h263 header */ 
    1944         out->p_buffer[12] = ( h >>  8 )&0xff; 
    1945         out->p_buffer[13] = ( h       )&0xff; 
    1946         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload ); 
    1947  
    1948         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload; 
    1949         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    1950         out->i_length = in->i_length / i_count; 
    1951  
    1952         rtp_packetize_send( id, out ); 
    1953  
    1954         p_data += i_payload; 
    1955         i_data -= i_payload; 
    1956     } 
    1957  
    1958     return VLC_SUCCESS; 
    1959 
    1960  
    1961 /* rfc3984 */ 
    1962 static int 
    1963 rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id, 
    1964                         const uint8_t *p_data, int i_data, int64_t i_pts, 
    1965                         int64_t i_dts, vlc_bool_t b_last, int64_t i_length ) 
    1966 
    1967     const int i_max = id->i_mtu - 12; /* payload max in one packet */ 
    1968     int i_nal_hdr; 
    1969     int i_nal_type; 
    1970  
    1971     if( i_data < 5 ) 
    1972         return VLC_SUCCESS; 
    1973  
    1974     i_nal_hdr = p_data[3]; 
    1975     i_nal_type = i_nal_hdr&0x1f; 
    1976  
    1977     /* Skip start code */ 
    1978     p_data += 3; 
    1979     i_data -= 3; 
    1980  
    1981     /* */ 
    1982     if( i_data <= i_max ) 
    1983     { 
    1984         /* Single NAL unit packet */ 
    1985         block_t *out = block_New( p_stream, 12 + i_data ); 
    1986         out->i_dts    = i_dts; 
    1987         out->i_length = i_length; 
    1988  
    1989         /* */ 
    1990         rtp_packetize_common( id, out, b_last, i_pts ); 
    1991         out->i_buffer = 12 + i_data; 
    1992  
    1993         memcpy( &out->p_buffer[12], p_data, i_data ); 
    1994  
    1995         rtp_packetize_send( id, out ); 
    1996     } 
    1997     else 
    1998     { 
    1999         /* FU-A Fragmentation Unit without interleaving */ 
    2000         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2); 
    2001         int i; 
    2002  
    2003         p_data++; 
    2004         i_data--; 
    2005  
    2006         for( i = 0; i < i_count; i++ ) 
    2007         { 
    2008             const int i_payload = __MIN( i_data, i_max-2 ); 
    2009             block_t *out = block_New( p_stream, 12 + 2 + i_payload ); 
    2010             out->i_dts    = i_dts + i * i_length / i_count; 
    2011             out->i_length = i_length / i_count; 
    2012  
    2013             /* */ 
    2014             rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts ); 
    2015             out->i_buffer = 14 + i_payload; 
    2016  
    2017             /* FU indicator */ 
    2018             out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28; 
    2019             /* FU header */ 
    2020             out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type; 
    2021             memcpy( &out->p_buffer[14], p_data, i_payload ); 
    2022  
    2023             rtp_packetize_send( id, out ); 
    2024  
    2025             i_data -= i_payload; 
    2026             p_data += i_payload; 
    2027         } 
    2028     } 
    2029     return VLC_SUCCESS; 
    2030 
    2031  
    2032 static int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id, 
    2033                                block_t *in ) 
    2034 
    2035     const uint8_t *p_buffer = in->p_buffer; 
    2036     int i_buffer = in->i_buffer; 
    2037  
    2038     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) ) 
    2039     { 
    2040         i_buffer--; 
    2041         p_buffer++; 
    2042     } 
    2043  
    2044     /* Split nal units */ 
    2045     while( i_buffer > 4 ) 
    2046     { 
    2047         int i_offset; 
    2048         int i_size = i_buffer; 
    2049         int i_skip = i_buffer; 
    2050  
    2051         /* search nal end */ 
    2052         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++) 
    2053         { 
    2054             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 ) 
    2055             { 
    2056                 /* we found another startcode */ 
    2057                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0); 
    2058                 i_skip = i_offset; 
    2059                 break; 
    2060             } 
    2061         } 
    2062         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */ 
    2063         rtp_packetize_h264_nal( p_stream, id, p_buffer, i_size, 
    2064                                 (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts, 
    2065                                 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer ); 
    2066  
    2067         i_buffer -= i_skip; 
    2068         p_buffer += i_skip; 
    2069     } 
    2070     return VLC_SUCCESS; 
    2071 
    2072  
    2073 static int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id, 
    2074                               block_t *in ) 
    2075 
    2076     int     i_max   = id->i_mtu - 14; /* payload max in one packet */ 
    2077     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max; 
    2078  
    2079     uint8_t *p_data = in->p_buffer; 
    2080     int     i_data  = in->i_buffer; 
    2081     int     i; 
    2082  
    2083     /* Only supports octet-aligned mode */ 
    2084     for( i = 0; i < i_count; i++ ) 
    2085     { 
    2086         int           i_payload = __MIN( i_max, i_data ); 
    2087         block_t *out = block_New( p_stream, 14 + i_payload ); 
    2088  
    2089         /* rtp common header */ 
    2090         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0), 
    2091                               (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    2092         /* Payload header */ 
    2093         out->p_buffer[12] = 0xF0; /* CMR */ 
    2094         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */ 
    2095  
    2096         /* FIXME: are we fed multiple frames ? */ 
    2097         memcpy( &out->p_buffer[14], p_data+1, i_payload-1 ); 
    2098  
    2099         out->i_buffer   = 14 + i_payload-1; 
    2100         out->i_dts    = in->i_dts + i * in->i_length / i_count; 
    2101         out->i_length = in->i_length / i_count; 
    2102  
    2103         rtp_packetize_send( id, out ); 
    2104  
    2105         p_data += i_payload; 
    2106         i_data -= i_payload; 
    2107     } 
    2108  
    2109     return VLC_SUCCESS; 
    2110 
    2111  
    2112 static int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id, 
    2113                                block_t *in ) 
    2114 
    2115     const size_t   i_max  = id->i_mtu - 12; 
    2116     const uint8_t *p_data = in->p_buffer; 
    2117     size_t         i_data = in->i_buffer; 
    2118  
    2119     for( unsigned i_packet = 0; i_data > 0; i_packet++ ) 
    2120     { 
    2121         size_t i_payload = i_data; 
    2122  
    2123         /* Make sure we stop on an UTF-8 character boundary 
    2124          * (assuming the input is valid UTF-8) */ 
    2125         if( i_data > i_max ) 
    2126         { 
    2127             i_payload = i_max; 
    2128  
    2129             while( ( p_data[i_payload] & 0xC0 ) == 0x80 ) 
    2130             { 
    2131                 if( i_payload == 0 ) 
    2132                     return VLC_SUCCESS; /* fishy input! */ 
    2133  
    2134                 i_payload--; 
    2135             } 
    2136         } 
    2137  
    2138         block_t *out = block_New( p_stream, 12 + i_payload ); 
    2139         if( out == NULL ) 
    2140             return VLC_SUCCESS; 
    2141  
    2142         rtp_packetize_common( id, out, 0, in->i_pts + i_packet ); 
    2143         memcpy( out->p_buffer + 12, p_data, i_payload ); 
    2144  
    2145         out->i_buffer = 12 + i_payload; 
    2146         out->i_dts    = out->i_pts; 
    2147         out->i_length = 0; 
    2148  
    2149         rtp_packetize_send( id, out ); 
    2150  
    2151         p_data += i_payload; 
    2152         i_data -= i_payload; 
    2153     } 
    2154  
    2155     return VLC_SUCCESS; 
    2156 
     1506void rtp_packetize_send( sout_stream_id_t *id, block_t *out ) 
     1507
     1508    block_FifoPut( id->p_fifo, out ); 
     1509
     1510 
     1511/** 
     1512 * @return configured max RTP payload size (including payload type-specific 
     1513 * headers, excluding RTP and transport headers) 
     1514 */ 
     1515size_t rtp_mtu (const sout_stream_id_t *id) 
     1516
     1517    return id->i_mtu - 12; 
     1518
     1519 
     1520/** 
     1521 * @return number of audio samples to include for a given packetization time 
     1522 * (this really only makes sense for audio formats). 
     1523 */ 
     1524size_t rtp_plen (const sout_stream_id_t * id, unsigned ptime_ms) 
     1525
     1526    return id->i_channels * (((id->i_clock_rate - 1) * ptime_ms / 1000) + 1); 
     1527
     1528 
    21571529 
    21581530/***************************************************************************** 
     
    22891661    return p_grab; 
    22901662} 
    2291  
    2292 static int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id, 
    2293                               block_t *in ) 
    2294 { 
    2295     uint8_t *p_buffer = in->p_buffer; 
    2296     int i_data_size, i_payload_size, i_payload_padding; 
    2297     i_data_size = i_payload_size = in->i_buffer; 
    2298     i_payload_padding = 0; 
    2299     block_t *p_out; 
    2300  
    2301     if ( in->i_buffer + 12 > id->i_mtu ) 
    2302     { 
    2303         msg_Warn( p_stream, "Cannot send packet larger than output MTU" ); 
    2304         return VLC_SUCCESS; 
    2305     } 
    2306  
    2307     /* 
    2308       RFC for Speex in RTP says that each packet must end on an octet  
    2309       boundary. So, we check to see if the number of bytes % 4 is zero. 
    2310       If not, we have to add some padding.  
    2311  
    2312       This MAY be overkill since packetization is handled elsewhere and  
    2313       appears to ensure the octet boundary. However, better safe than 
    2314       sorry. 
    2315     */ 
    2316     if ( i_payload_size % 4 ) 
    2317     { 
    2318         i_payload_padding = 4 - ( i_payload_size % 4 ); 
    2319         i_payload_size += i_payload_padding; 
    2320     } 
    2321  
    2322     /*  
    2323       Allocate a new RTP p_output block of the appropriate size.  
    2324       Allow for 12 extra bytes of RTP header.  
    2325     */ 
    2326     p_out = block_New( p_stream, 12 + i_payload_size ); 
    2327  
    2328     if ( i_payload_padding ) 
    2329     { 
    2330         /*  
    2331       The padding is required to be a zero followed by all 1s. 
    2332     */ 
    2333     char c_first_pad, c_remaining_pad; 
    2334     c_first_pad = 0x7F; 
    2335     c_remaining_pad = 0xFF; 
    2336  
    2337         /*  
    2338       Allow for 12 bytes before the i_data_size because 
    2339       of the expected RTP header added during 
    2340       rtp_packetize_common. 
    2341     */ 
    2342     p_out->p_buffer[12 + i_data_size] = c_first_pad;  
    2343     switch (i_payload_padding) 
    2344     { 
    2345         case 2: 
    2346             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;  
    2347             break; 
    2348         case 3: 
    2349             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;  
    2350             p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad;  
    2351             break; 
    2352     } 
    2353     }  
    2354  
    2355     /* Add the RTP header to our p_output buffer. */ 
    2356     rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) ); 
    2357     /* Copy the Speex payload to the p_output buffer */ 
    2358     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size ); 
    2359  
    2360     p_out->i_buffer = 12 + i_payload_size; 
    2361     p_out->i_dts = in->i_dts; 
    2362     p_out->i_length = in->i_length; 
    2363  
    2364     /* Queue the buffer for actual transmission. */ 
    2365     rtp_packetize_send( id, p_out ); 
    2366     return VLC_SUCCESS; 
    2367 } 
  • modules/stream_out/rtp.h

    r59a4031 r14fae49  
    4242unsigned rtp_get_num( const sout_stream_id_t *id ); 
    4343 
     44/* RTP packetization */ 
     45void rtp_packetize_common (sout_stream_id_t *id, block_t *out, 
     46                           int b_marker, int64_t i_pts); 
     47void rtp_packetize_send (sout_stream_id_t *id, block_t *out); 
     48size_t rtp_mtu (const sout_stream_id_t *id); 
     49size_t rtp_plen (const sout_stream_id_t * id, unsigned ptime); 
     50 
     51int rtp_packetize_l16  (sout_stream_t *, sout_stream_id_t *, block_t *); 
     52int rtp_packetize_l8   (sout_stream_t *, sout_stream_id_t *, block_t *); 
     53int rtp_packetize_mpa  (sout_stream_t *, sout_stream_id_t *, block_t *); 
     54int rtp_packetize_mpv  (sout_stream_t *, sout_stream_id_t *, block_t *); 
     55int rtp_packetize_ac3  (sout_stream_t *, sout_stream_id_t *, block_t *); 
     56int rtp_packetize_split(sout_stream_t *, sout_stream_id_t *, block_t *); 
     57int rtp_packetize_mp4a (sout_stream_t *, sout_stream_id_t *, block_t *); 
     58int rtp_packetize_mp4a_latm (sout_stream_t *, sout_stream_id_t *, block_t *); 
     59int rtp_packetize_h263 (sout_stream_t *, sout_stream_id_t *, block_t *); 
     60int rtp_packetize_h264 (sout_stream_t *, sout_stream_id_t *, block_t *); 
     61int rtp_packetize_amr  (sout_stream_t *, sout_stream_id_t *, block_t *); 
     62int rtp_packetize_spx  (sout_stream_t *, sout_stream_id_t *, block_t *); 
     63int rtp_packetize_t140 (sout_stream_t *, sout_stream_id_t *, block_t *); 
     64 
    4465/* RTCP */ 
    4566typedef struct rtcp_sender_t rtcp_sender_t;